Для тех из вас, кто не видит этот пост, используйте нашу Ссылку друга !!
Продолжая предыдущий пост, который был в основном о том, как работает RNN и его реализация в среде keras, в этом я сосредоточусь на TensorFlow с некоторыми улучшениями.
Затем, как и было обещано, я думаю, нам пора вернуться и посмотреть, как предварительно обработать необработанные текстовые данные. Когда все это будет сделано, я планирую погрузиться в продвинутую RNN до начала лунных новогодних праздников. Или, может быть, после 🌝.
Я еду в Рим на этот праздник, и внутри меня полно волнения и радости !!!!! Не могу дождаться!
Этот пост основан
[1] Глубокое обучение с помощью Python, Франсуа Шоле, стр.207–224.
[2] руководство по TensorFlow, так что если вам нужна дополнительная информация, обратитесь по этой ссылке!
I. Исходный уровень
- Техническая настройка
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 из последней публикации.
- Базовая модель
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 без выпадения? Посмотрим на сюжеты.
- двунаправленный слой без исключения
2. два двунаправленных уровня LSTM без отключения
Вы видите разницу? В зависимости от перспективы и учитывая время вычисления дополнительного двунаправленного слоя, это кажется простым улучшением.
- Точность проверки увеличилась с 86% до 88%.
- Похоже, мы решили проблему переобучения, но этого недостаточно.
Это все для этой публикации, а далее будет рассказано о том, как предварительно обработать необработанные текстовые данные. Тогда увидимся!