Для тех из вас, кто не видит этот пост, используйте нашу Ссылку друга !!

Продолжая предыдущий пост, который был в основном о том, как работает RNN и его реализация в среде keras, в этом я сосредоточусь на TensorFlow с некоторыми улучшениями.

Затем, как и было обещано, я думаю, нам пора вернуться и посмотреть, как предварительно обработать необработанные текстовые данные. Когда все это будет сделано, я планирую погрузиться в продвинутую RNN до начала лунных новогодних праздников. Или, может быть, после 🌝.
Я еду в Рим на этот праздник, и внутри меня полно волнения и радости !!!!! Не могу дождаться!

Этот пост основан

[1] Глубокое обучение с помощью Python, Франсуа Шоле, стр.207–224.

[2] руководство по TensorFlow, так что если вам нужна дополнительная информация, обратитесь по этой ссылке!



I. Исходный уровень

  1. Техническая настройка
from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow_datasets as tfds
import tensorflow as tf

2. Загрузите данные IMDB и выполните предварительную обработку

dataset, info = tfds.load('imdb_reviews/subwords8k', with_info=True,
                          as_supervised=True)
train_dataset, test_dataset = dataset['train'], dataset['test']

Как мы уже говорили в части 3 встраивания слов в TensorFlow, мы не усекаем текст. Скорее, мы дополняем нули в соответствии с максимальной длиной входных текстовых данных.

3. Моделирование

encoder = info.features['text'].encoder
model = tf.keras.Sequential([
tf.keras.layers.Embedding(encoder.vocab_size, 64),
tf.keras.layers.LSTM(64),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.Dense(1, activation='sigmoid')
])

4. Компиляция и подгонка

model.compile(loss='binary_crossentropy',          optimizer=tf.keras.optimizers.Adam(1e-4),metrics=['accuracy'])
history = model.fit(train_dataset, epochs=10, validation_data=test_dataset, validation_steps=30)

5. Графика

BUFFER_SIZE = 10000
BATCH_SIZE = 64
train_dataset = train_dataset.shuffle(BUFFER_SIZE)
train_dataset = train_dataset.padded_batch(BATCH_SIZE, train_dataset.output_shapes)
test_dataset = test_dataset.padded_batch(BATCH_SIZE, test_dataset.output_shapes)
import matplotlib.pyplot as plt
history_dict = history.history
acc = history_dict['accuracy']
val_acc = history_dict['val_accuracy']
loss = history_dict['loss']
val_loss = history_dict['val_loss']
epochs = range(1, len(acc) + 1)
plt.figure(figsize=(4,3))
plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
plt.figure(figsize=(4,3))
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend(loc='lower right')
plt.ylim((0.5,1))
plt.show()

С этого момента шаги 4 и 5 (обучение и построение графиков) будут использоваться постоянно, но не будут указаны в этом посте для пространственной эффективности.

Это настоящая масса.

Тогда что мы можем сделать, чтобы улучшить эту сеть?

II. Предлагаемые улучшения

Мы достигли значительного прогресса, начиная от встраивания слов с плотными слоями до слоев LSTM. Однако нерешенными проблемами являются переоснащение и низкая точность проверки / высокие потери при проверке. Кроме того, хотя LSTM хорошо справился с отслеживанием информации о состоянии на протяжении итераций, не будем предполагать, что все улажено.

Ниже приведены некоторые полезные методы продвижения;

  • Двунаправленный рекуррентный слой - он предоставляет одну и ту же информацию повторяющейся сети по-разному (в двух направлениях), что увеличивает точность и уменьшает кратковременную потерю памяти :).
  • Recurrent Dropout - классический способ борьбы с переобучением также можно использовать в RNN.
  • Укладка повторяющихся слоев - типичный способ увеличения пропускной способности сети - это увеличение единиц в уровнях и добавление слоев (если вы считаете, что ваша сеть не переоснащается).

III. Двунаправленный рекуррентный слой

Двунаправленный рекуррентный слой или BRNN - очень удобная стратегия, когда дело доходит до анализа естественного языка.

Во-первых, двунаправленная RNN имеет дело с двумя обычными RNN, у нее будет вдвое больше параметров по сравнению с обычными уровнями RNN. Каждый уровень в двунаправленной RNN работает отдельно в соответствии со своим механизмом. Таким образом, двунаправленная RNN улавливает больше деталей, чем может сделать однонаправленная RNN.

Кроме того, RNN очень чувствительна к порядку, и двунаправленная RNN использует эту функцию. Он смотрит на свою входную последовательность как в нормальной / хронологической последовательности, так и в обратной последовательности.

Краткий механизм двунаправленной RNN выглядит следующим образом.

3. Моделирование

encoder = info.features['text'].encoder
model = tf.keras.Sequential([
    tf.keras.layers.Embedding(encoder.vocab_size, 64),
    tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64)),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
])
model.summary()

Мы практиковались в кодировании в части 3 вложения слов. Помните пример «Возлюби ближнего твоего, как самого себя»? В этом кодировщике было 8185 словарей.

  • 8185*64=523,840
  • Помните, как рассчитывались параметры слоя LSTM?
    (64 + 64 + 1 + 129 * 3) * 64 = 33024. Подробнее см. в комментариях.
    Итак, в двунаправленной RNN удвойте числа = 33 024 * 2 = 66 048 и обратите внимание, что форма вывода - (, 128)
  • (128+1)*64=8256
  • (64+1)*1=65

По сравнению с простым примером LSTM произошло огромное улучшение. Однако мы можем наблюдать серьезную переоснащенность. Как упоминалось ранее, отсев может облегчить переобучение. Тогда посмотрим.

IV. Бросить

Выпадение - это классическое решение проблемы переобучения в машинном обучении, которое случайным образом отбрасывает входные единицы слоя, чтобы предотвратить случайную корреляцию в обучающих данных. Согласно некоторым исследованиям, это также может быть реализовано в повторяющихся слоях, если на каждом временном шаге применяется одна и та же маска исключения (шаблон отброшенных единиц).

Чтобы увидеть некоторые достижения, которых может добиться отсев, давайте вернемся к предыдущему примеру LSTM с данными IMDB из последней публикации.

  1. Базовая модель
model = Sequential()
model.add(Embedding(max_features, 32))
model.add(LSTM(32))
model.add(Dense(1, activation='sigmoid')

2. С отсевом

model = Sequential()
model.add(Embedding(max_features, 32))
model.add(LSTM(32,dropout=0.2,recurrent_dropout=0.2))
model.add(Dense(1, activation='sigmoid'))
  • dropout указывает частоту отсева для ввода слоя.
  • recurrent_dropout указывает частоту отсева повторяющихся единиц.

Вы заметили разницу?

Осторожно, отсев в TensorFlow выполняется немного иначе.
Мы увидим это ниже.

IV. Сложите еще два слоя LSTM - все вместе

Теперь, когда мы мягко решили проблему переобучения с отсевом, наша модель находится под контролем. Затем мы хотим увеличить емкость нашей модели. Даже в сети с прямой связью или с плотными слоями мы добавляем слои и единицы для повышения точности. Кроме того, мы должны позаботиться о том, чтобы промежуточные уровни RNN возвращали полную последовательность выходных данных; 3D-тензор, указав return_sequences = True.

model = tf.keras.Sequential([
tf.keras.layers.Embedding(encoder.vocab_size, 64),
tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64, return_sequences=True)),
tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(32)),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(1, activation='sigmoid')
])
model.summary()

  • Во-первых, промежуточный слой LSTM имеет трехмерную форму.
  • 8185*64=523,840
  • {(64+64+1+129*3)*64}*2=66,048
  • {(128 + 32 + 1 + 161 * 3) * 32} * 2 = 41216
    Здесь выходные данные предыдущего слоя LSTM становятся входными данными этого 128-мерного слоя. . Кроме того, этот второй уровень состоит из 32 единиц, поэтому состояние будет 32-мерным.
  • (64+1)*65=4,160
  • (64+1)*1=65

Тогда это лучше, чем в первом примере с одним двунаправленным слоем LSTM без выпадения? Посмотрим на сюжеты.

  1. двунаправленный слой без исключения

2. два двунаправленных уровня LSTM без отключения

Вы видите разницу? В зависимости от перспективы и учитывая время вычисления дополнительного двунаправленного слоя, это кажется простым улучшением.

  • Точность проверки увеличилась с 86% до 88%.
  • Похоже, мы решили проблему переобучения, но этого недостаточно.

Это все для этой публикации, а далее будет рассказано о том, как предварительно обработать необработанные текстовые данные. Тогда увидимся!