Переход с Theano 1.0.0 на TensorFlow 2.2 (оба с использованием Keras) вызывает экспоненциально растущие потери и постоянную точность - PullRequest
2 голосов
/ 14 июля 2020

Информация о системе

  • Написал ли я собственный код (в отличие от использования стандартного примера сценария, представленного в TensorFlow): Да
  • Платформа и распространение ОС (например, Linux Ubuntu 16.04): Linux Ubuntu 16.04
  • Мобильное устройство (например, iPhone 8, Pixel 2, Samsung Galaxy), если проблема возникает на мобильном устройстве:
  • TensorFlow установлен из (исходный или двоичный): pip
  • Версия TensorFlow (используйте команду ниже): 2.2
  • Python версия: 3.6.10
  • версия Bazel (при компиляции из источника):
  • Версия GCC / компилятора (при компиляции из исходников):
  • Версия CUDA / cuDNN: CUDA 10.1, cuDNN 7.6.5
  • Модель графического процессора и память: GeForce GTX Titan X, 12 ГБ

Опишите текущее поведение

После переноса некоторого кода Keras из серверной части Theano (Keras 2.0.7, Theano 1.0.0 ) на чистый TensorFlow, модель не может тренироваться с тем же успехом, что и раньше. Я ничего не менял в архитектуре модели, гиперпараметрах или параметрах функции подбора. Все, что изменилось, это операторы импорта (например: keras.layers -> tensorflow.keras.layers)

С TensorFlow:

2020-07-10 23:12:37 WARNING  Using a generator with use_multiprocessing=True and multiple workers may duplicate your data. Please consider using the tf.data.Dataset.
Epoch 1/8
2020-07-10 23:12:38.795744: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcublas.so.10
2020-07-10 23:12:38 WARNING  multiprocessing can interact badly with TensorFlow, causing nondeterministic deadlocks. For high performance data pipelines tf.data is recommended.
2020-07-10 23:12:39.211689: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcudnn.so.7
100/100 [==============================] - 10s 103ms/step - loss: 5.1734 - accuracy: 0.1002
Epoch 2/8
100/100 [==============================] - 10s 102ms/step - loss: 6.1694 - accuracy: 0.1079
Epoch 3/8
100/100 [==============================] - 10s 102ms/step - loss: 13.4283 - accuracy: 0.0830
Epoch 4/8
100/100 [==============================] - 10s 101ms/step - loss: 22.0164 - accuracy: 0.0838
Epoch 5/8
100/100 [==============================] - 10s 102ms/step - loss: 44.7066 - accuracy: 0.0575
Epoch 6/8
100/100 [==============================] - 10s 102ms/step - loss: 38.3269 - accuracy: 0.0690
Epoch 7/8
100/100 [==============================] - 10s 102ms/step - loss: 53.5934 - accuracy: 0.0641
Epoch 8/8
100/100 [==============================] - 10s 101ms/step - loss: 66.5487 - accuracy: 0.0673

Опишите ожидаемое поведение

Ожидаемое поведение при обучении должно быть аналогично поведению Keras с серверной частью Theano:

/usr/local/lib/python3.6/site-packages/keras/engine/training.py:1984: UserWarning: Using a generator with use_multiprocessing=True and multiple workers may duplicate your data. Please consider using the keras.utils.Sequence class.
  UserWarning('Using a generator with use_multiprocessing=True')
Epoch 1/8
100/100 [==============================] - 14s - loss: 4.8412 - acc: 0.1197          
Epoch 2/8
100/100 [==============================] - 13s - loss: 3.7391 - acc: 0.2454     
Epoch 3/8
100/100 [==============================] - 13s - loss: 3.2523 - acc: 0.3528     
Epoch 4/8
100/100 [==============================] - 13s - loss: 2.9821 - acc: 0.3923     
Epoch 5/8
100/100 [==============================] - 13s - loss: 2.8871 - acc: 0.4059     
Epoch 6/8
100/100 [==============================] - 13s - loss: 2.8087 - acc: 0.4177     
Epoch 7/8
100/100 [==============================] - 13s - loss: 2.7203 - acc: 0.4290     
Epoch 8/8
100/100 [==============================] - 13s - loss: 2.6507 - acc: 0.4351

Автономный код для воспроизведения проблемы

Архитектура модели:

import tensorflow.keras.backend as K
from tensorflow.keras import Model, Sequential, Input
from tensorflow.keras.layers import Dense, Lambda, Embedding, LSTM
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.losses import CategoricalCrossentropy
from tensorflow.keras.metrics import Accuracy

epoch = 1
batch_size = 2048
validation_batch_size = 1024
one_hot_dim = 80000
embedding_dim = 128
max_seq_len = 50
hidden_layer_dim = 512
max_q_size = 5000

nb_worker = 5
one_indexing = False
featurizer = "sequence"
featurizer_parameters = [one_hot_dim, max_seq_len, one_indexing]
def create_model_architecture(num_classes):
    # build model architecture
    model = Sequential(
         [
             Input(shape=(max_seq_len,), name="query_input"),
             Embedding(output_dim=embedding_dim, input_dim=one_hot_dim, input_length=max_seq_len),
             LSTM(embedding_dim, input_shape=(max_seq_len, embedding_dim)),
             Lambda(lambda x: K.cast(x, "float32")),
             Dense(units=hidden_layer_dim, kernel_initializer="he_normal", activation="relu"),
             Dense(units=num_classes, kernel_initializer="normal", activation="softmax", name="prediction")
         ]
    )
    model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']
    model.summary()
    return model

В model.compile я также пробовал использовать классы оптимизатора, потерь и показателей (например, Adam, CategoriesCrossentropy, Accuracy). Это приводит к тому, что точность намного выше, но потери все равно возрастают экспоненциально.

Вызов соответствия модели:

model.fit(data_generator_train.generate(),
            steps_per_epoch=args.step_log,
            epochs=8,
            validation_data=data_generator_validate.generate() if data_generator_validate else None,
            validation_steps=data_generator_validate.num_batches if data_generator_validate else None,
            max_queue_size=model_module.max_q_size,
            shuffle=True,
            use_multiprocessing=True,
            workers=model_module.nb_worker,
            callbacks=[check_pointer])

Функция генератора данных:

@threadsafe_generator
def generate(self):
   while True:
      for filename in glob.glob(self.dataset_files):
         with open(filename) as fr:
            while True:
               lines = list(islice(fr, self.batch_size))
               if not lines:
                  break
               x, y, w = self.get_train_vectors(lines)
               yield x, y, w

Другая информация / журналы

Другие вещи, которые я пробовал:

Использование tensorflow.keras.utils.Sequence вместо генератора и включение shuffle = True Не использование многопроцессорности Не использование последовательного использования классы вместо имен в model.compile () Изменение таких параметров, как размер пакета, steps_per_epoch, и т. д. c.

Другие примечания:

Я использую пользовательское изображение Docker для запуска модель. Я сделал монтирование томов с локального компьютера, включая CUDA, cuDNN, и т. Д. c. в / usr / local / cuda. В TensorFlow 2.2 также есть библиотека (libcublas.so), которой там нет, поэтому у меня есть дополнительное сопоставление в /usr/lib/x86_64-linux-gnu.

...