Ошибка выполнения Variable_scope при создании настраиваемого слоя keras с использованием моделей концентратора тензорного потока и тензорного потока 2.0 в качестве бэкэнда

Я пытаюсь использовать предварительно обученную модель tf-hub elmo, интегрировав ее в слой keras .

Слой Кераса:

class ElmoEmbeddingLayer(tf.keras.layers.Layer):

    def __init__(self, **kwargs):
        super(ElmoEmbeddingLayer, self).__init__(**kwargs)
        self.dimensions = 1024
        self.trainable = True
        self.elmo = None

    def build(self, input_shape):
        url = 'https://tfhub.dev/google/elmo/2'

        self.elmo = hub.Module(url)
        self._trainable_weights += trainable_variables(
            scope="^{}_module/.*".format(self.name))
        super(ElmoEmbeddingLayer, self).build(input_shape)

    def call(self, x, mask=None):
        result = self.elmo(
            x,
            signature="default",
            as_dict=True)["elmo"]
        return result

    def compute_output_shape(self, input_shape):
        return input_shape[0], self.dimensions

Когда я запускаю код, я получаю следующую ошибку:

Traceback (most recent call last):
  File "D:/Google Drive/Licenta/Gemini/Emotion Analysis/nn/trainer/model.py", line 170, in <module>
    validation_steps=validation_dataset.size())
  File "D:/Google Drive/Licenta/Gemini/Emotion Analysis/nn/trainer/model.py", line 79, in train_gpu
    model = build_model(self.config, self.embeddings, self.sequence_len, self.out_classes, summary=True)
  File "D:\Google Drive\Licenta\Gemini\Emotion Analysis\nn\architectures\models.py", line 8, in build_model
    return my_model(embeddings, config, sequence_length, out_classes, summary)
  File "D:\Google Drive\Licenta\Gemini\Emotion Analysis\nn\architectures\models.py", line 66, in my_model
    inputs, embedding = resolve_inputs(embeddings, sequence_length, model_config, input_type)
  File "D:\Google Drive\Licenta\Gemini\Emotion Analysis\nn\architectures\models.py", line 19, in resolve_inputs
    return elmo_input(model_conf)
  File "D:\Google Drive\Licenta\Gemini\Emotion Analysis\nn\architectures\models.py", line 58, in elmo_input
    embedding = ElmoEmbeddingLayer()(input_text)
  File "D:\Apps\Anaconda\envs\tf2.0\lib\site-packages\tensorflow\python\keras\engine\base_layer.py", line 616, in __call__
    self._maybe_build(inputs)
  File "D:\Apps\Anaconda\envs\tf2.0\lib\site-packages\tensorflow\python\keras\engine\base_layer.py", line 1966, in _maybe_build
    self.build(input_shapes)
  File "D:\Google Drive\Licenta\Gemini\Emotion Analysis\nn\architectures\custom_layers.py", line 21, in build
    self.elmo = hub.Module(url)
  File "D:\Apps\Anaconda\envs\tf2.0\lib\site-packages\tensorflow_hub\module.py", line 156, in __init__
    abs_state_scope = _try_get_state_scope(name, mark_name_scope_used=False)
  File "D:\Apps\Anaconda\envs\tf2.0\lib\site-packages\tensorflow_hub\module.py", line 389, in _try_get_state_scope
    "name_scope was already taken." % abs_state_scope)
RuntimeError: variable_scope module/ was unused but the corresponding name_scope was already taken.

Похоже, это связано с нетерпеливым исполнением. Если я отключу активное выполнение, мне придется окружить функцию model.fit сеансом tenorflow и инициализировать переменные с помощью sess.run(global_variables_initializer()), чтобы избежать следующей ошибки:

Traceback (most recent call last):
  File "D:/Google Drive/Licenta/Gemini/Emotion Analysis/nn/trainer/model.py", line 168, in <module>
    validation_steps=validation_dataset.size().eval(session=Session()))
  File "D:/Google Drive/Licenta/Gemini/Emotion Analysis/nn/trainer/model.py", line 90, in train_gpu
    class_weight=weighted)
  File "D:\Apps\Anaconda\envs\tf2.0\lib\site-packages\tensorflow\python\keras\engine\training.py", line 643, in fit
    use_multiprocessing=use_multiprocessing)
  File "D:\Apps\Anaconda\envs\tf2.0\lib\site-packages\tensorflow\python\keras\engine\training_arrays.py", line 664, in fit
    steps_name='steps_per_epoch')
  File "D:\Apps\Anaconda\envs\tf2.0\lib\site-packages\tensorflow\python\keras\engine\training_arrays.py", line 294, in model_iteration
    batch_outs = f(actual_inputs)
  File "D:\Apps\Anaconda\envs\tf2.0\lib\site-packages\tensorflow\python\keras\backend.py", line 3353, in __call__
    run_metadata=self.run_metadata)
  File "D:\Apps\Anaconda\envs\tf2.0\lib\site-packages\tensorflow\python\client\session.py", line 1458, in __call__
    run_metadata_ptr)
tensorflow.python.framework.errors_impl.FailedPreconditionError: 2 root error(s) found.
  (0) Failed precondition: Error while reading resource variable module/bilm/RNN_0/RNN/MultiRNNCell/Cell1/rnn/lstm_cell/bias from Container: localhost. This could mean that the variable was uninitialized. Not found: Resource localhost/module/bilm/RNN_0/RNN/MultiRNNCell/Cell1/rnn/lstm_cell/bias/class tensorflow::Var does not exist.
     [[{{node elmo_embedding_layer/module_apply_default/bilm/RNN_0/RNN/MultiRNNCell/Cell1/rnn/lstm_cell/bias/Read/ReadVariableOp}}]]
  (1) Failed precondition: Error while reading resource variable module/bilm/RNN_0/RNN/MultiRNNCell/Cell1/rnn/lstm_cell/bias from Container: localhost. This could mean that the variable was uninitialized. Not found: Resource localhost/module/bilm/RNN_0/RNN/MultiRNNCell/Cell1/rnn/lstm_cell/bias/class tensorflow::Var does not exist.
     [[{{node elmo_embedding_layer/module_apply_default/bilm/RNN_0/RNN/MultiRNNCell/Cell1/rnn/lstm_cell/bias/Read/ReadVariableOp}}]]
     [[metrics/f1_micro/Identity/_223]]
0 successful operations.
0 derived errors ignored.

Мое решение:

with Session() as sess:
    sess.run(global_variables_initializer())
    history = model.fit(self.train_data.repeat(),
                        epochs=self.config['epochs'],
                        validation_data=self.validation_data.repeat(),
                        steps_per_epoch=steps_per_epoch,
                        validation_steps=validation_steps,
                        callbacks=self.__callbacks(monitor_metric),
                        class_weight=weighted)

Главный вопрос - есть ли другой способ использовать модуль elmo tf-hub в пользовательском слое keras и обучить мою модель. Другой вопрос, не влияет ли мое текущее решение на производительность обучения или выдает ошибку OOM GPU (я получаю ошибку OOM через несколько эпох с более высоким размером пакета, что, как я обнаружил, связано с незакрытыми сеансами или утечками памяти. ).


person George Alexandru Vlad    schedule 31.07.2019    source источник


Ответы (2)


Если вы заключите свою модель в поле Session (), вам также придется заключить весь другой код, который использует вашу модель, в поле Session (). На это нужно много времени и усилий. У меня есть другой способ справиться с этим: во-первых, создать модуль elmo, добавить сеанс в keras:

   elmo_model = hub.Module("https://tfhub.dev/google/elmo/3", trainable=True, 
   name='elmo_module')
   sess = tf.Session()
   sess.run(tf.global_variables_initializer())
   sess.run(tf.tables_initializer())
   K.set_session(sess)

Вместо того, чтобы создавать модуль elmo прямо в вашем ElmoEmbeddinglayer

  self.elmo = hub.Module(url)
  self._trainable_weights += trainable_variables(
            scope="^{}_module/.*".format(self.name))

Можно сделать следующее, думаю нормально работает!

  self.elmo = elmo_model
  self._trainable_weights += trainable_variables(
            scope="^elmo_module/.*")
person ducPham    schedule 31.10.2019

Вот простое решение, которое я использовал в своем случае:

Это случилось со мной, когда я использовал отдельный скрипт Python для создания модуля.

Чтобы решить эту проблему, я передал tf.Session () в основном скрипте в tf.keras.backend в другом скрипте, создав точку входа для передачи перед вызовом уровня. init

Пример:

Главный файл:

import tensorflow.compat.v1 as tf
from ModuleFile import ModuleLayer

def __main__():
  init_args = [...]
  input = ...
  sess= tf.keras.backend.get_session()
  Module_layer.__init_session___(sess)
  module_layer = ModuleLayer(init_args)(input)

Файл модуля:

import tensorflow.compat.v1 as tf

class ModuleLayer(tf.keras.layers.Layer):

  @staticmethod
  def __init_session__(session):
    tf.keras.backend.set_session(session)

  def __init__(*args):
  ...

Надеюсь, это поможет :)

person Gal Fridman    schedule 27.11.2019