Помогают защитить Большой Барьерный Риф с TensorFlow на Kaggle Присоединяйтесь вызов

Вложения слов

Посмотреть на TensorFlow.org Запускаем в Google Colab Посмотреть исходный код на GitHub Скачать блокнот

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

Скриншот встраиваемого проектора

Представление текста в виде чисел

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

Горячие кодировки

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

Схема горячих кодировок

Чтобы создать вектор, содержащий кодировку предложения, вы можете затем объединить горячие векторы для каждого слова.

Закодируйте каждое слово уникальным номером

Второй подход, который вы можете попробовать, - это закодировать каждое слово с помощью уникального номера. Продолжая приведенный выше пример, вы можете присвоить 1 «коту», 2 «мату» и так далее. Затем вы можете закодировать предложение «Кот сидел на циновке» как плотный вектор, например [5, 1, 4, 3, 5, 2]. Такой подход эффективен. Вместо разреженного вектора у вас теперь есть плотный вектор (где все элементы заполнены).

Однако у этого подхода есть два недостатка:

  • Целочисленное кодирование произвольно (оно не фиксирует никаких отношений между словами).

  • Целочисленное кодирование может быть сложной задачей для интерпретации модели. Например, линейный классификатор изучает один вес для каждой функции. Поскольку нет никакой связи между сходством любых двух слов и сходством их кодировок, эта комбинация весовых характеристик не имеет смысла.

Вложения слов

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

Схема вложения

Выше представлена ​​схема вложения слов. Каждое слово представлено как 4-мерный вектор значений с плавающей запятой. Другой способ представить вложение - это «таблица поиска». После того, как эти веса были изучены, вы можете закодировать каждое слово, просмотрев плотный вектор, которому оно соответствует, в таблице.

Настраивать

import io
import os
import re
import shutil
import string
import tensorflow as tf

from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense, Embedding, GlobalAveragePooling1D
from tensorflow.keras.layers import TextVectorization

Загрузите набор данных IMDb

Вы будете использовать Большой отзыв о фильме Dataset через учебник. Вы обучите модель классификатора настроений на этом наборе данных и в процессе выучите вложения с нуля. Чтобы узнать больше о загрузке набора данных с нуля, см Загрузка текста учебника .

Загрузите набор данных с помощью файловой утилиты Keras и просмотрите каталоги.

url = "https://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz"

dataset = tf.keras.utils.get_file("aclImdb_v1.tar.gz", url,
                                  untar=True, cache_dir='.',
                                  cache_subdir='')

dataset_dir = os.path.join(os.path.dirname(dataset), 'aclImdb')
os.listdir(dataset_dir)
Downloading data from https://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz
84131840/84125825 [==============================] - 14s 0us/step
84140032/84125825 [==============================] - 14s 0us/step
['README', 'test', 'imdbEr.txt', 'train', 'imdb.vocab']

Посмотрите на train/ каталог. Она имеет pos и neg папку с обзорами фильмов помеченных как положительные , так и отрицательной , соответственно. Вы будете использовать отзывы от pos и neg папок для подготовки бинарной модели классификации.

train_dir = os.path.join(dataset_dir, 'train')
os.listdir(train_dir)
['neg',
 'pos',
 'urls_pos.txt',
 'unsupBow.feat',
 'labeledBow.feat',
 'urls_neg.txt',
 'urls_unsup.txt',
 'unsup']

train каталог также содержит дополнительные папки , которые должны быть удалены перед созданием обучающего набора данных.

remove_dir = os.path.join(train_dir, 'unsup')
shutil.rmtree(remove_dir)

Затем создайте tf.data.Dataset с помощью tf.keras.utils.text_dataset_from_directory . Вы можете прочитать больше об использовании этой утилиты в этом тексте классификации урока .

Используйте train каталог для создания как поезд и проверки наборов данных с расколом 20% для проверки.

batch_size = 1024
seed = 123
train_ds = tf.keras.utils.text_dataset_from_directory(
    'aclImdb/train', batch_size=batch_size, validation_split=0.2,
    subset='training', seed=seed)
val_ds = tf.keras.utils.text_dataset_from_directory(
    'aclImdb/train', batch_size=batch_size, validation_split=0.2,
    subset='validation', seed=seed)
Found 25000 files belonging to 2 classes.
Using 20000 files for training.
Found 25000 files belonging to 2 classes.
Using 5000 files for validation.

Взгляните на несколько обзоров фильмов и их этикетками (1: positive, 0: negative) от железнодорожного набора данных.

for text_batch, label_batch in train_ds.take(1):
  for i in range(5):
    print(label_batch[i].numpy(), text_batch.numpy()[i])
0 b"Oh My God! Please, for the love of all that is holy, Do Not Watch This Movie! It it 82 minutes of my life I will never get back. Sure, I could have stopped watching half way through. But I thought it might get better. It Didn't. Anyone who actually enjoyed this movie is one seriously sick and twisted individual. No wonder us Australians/New Zealanders have a terrible reputation when it comes to making movies. Everything about this movie is horrible, from the acting to the editing. I don't even normally write reviews on here, but in this case I'll make an exception. I only wish someone had of warned me before I hired this catastrophe"
1 b'This movie is SOOOO funny!!! The acting is WONDERFUL, the Ramones are sexy, the jokes are subtle, and the plot is just what every high schooler dreams of doing to his/her school. I absolutely loved the soundtrack as well as the carefully placed cynicism. If you like monty python, You will love this film. This movie is a tad bit "grease"esk (without all the annoying songs). The songs that are sung are likable; you might even find yourself singing these songs once the movie is through. This musical ranks number two in musicals to me (second next to the blues brothers). But please, do not think of it as a musical per say; seeing as how the songs are so likable, it is hard to tell a carefully choreographed scene is taking place. I think of this movie as more of a comedy with undertones of romance. You will be reminded of what it was like to be a rebellious teenager; needless to say, you will be reminiscing of your old high school days after seeing this film. Highly recommended for both the family (since it is a very youthful but also for adults since there are many jokes that are funnier with age and experience.'
0 b"Alex D. Linz replaces Macaulay Culkin as the central figure in the third movie in the Home Alone empire. Four industrial spies acquire a missile guidance system computer chip and smuggle it through an airport inside a remote controlled toy car. Because of baggage confusion, grouchy Mrs. Hess (Marian Seldes) gets the car. She gives it to her neighbor, Alex (Linz), just before the spies turn up. The spies rent a house in order to burglarize each house in the neighborhood until they locate the car. Home alone with the chicken pox, Alex calls 911 each time he spots a theft in progress, but the spies always manage to elude the police while Alex is accused of making prank calls. The spies finally turn their attentions toward Alex, unaware that he has rigged devices to cleverly booby-trap his entire house. Home Alone 3 wasn't horrible, but probably shouldn't have been made, you can't just replace Macauley Culkin, Joe Pesci, or Daniel Stern. Home Alone 3 had some funny parts, but I don't like when characters are changed in a movie series, view at own risk."
0 b"There's a good movie lurking here, but this isn't it. The basic idea is good: to explore the moral issues that would face a group of young survivors of the apocalypse. But the logic is so muddled that it's impossible to get involved.<br /><br />For example, our four heroes are (understandably) paranoid about catching the mysterious airborne contagion that's wiped out virtually all of mankind. Yet they wear surgical masks some times, not others. Some times they're fanatical about wiping down with bleach any area touched by an infected person. Other times, they seem completely unconcerned.<br /><br />Worse, after apparently surviving some weeks or months in this new kill-or-be-killed world, these people constantly behave like total newbs. They don't bother accumulating proper equipment, or food. They're forever running out of fuel in the middle of nowhere. They don't take elementary precautions when meeting strangers. And after wading through the rotting corpses of the entire human race, they're as squeamish as sheltered debutantes. You have to constantly wonder how they could have survived this long... and even if they did, why anyone would want to make a movie about them.<br /><br />So when these dweebs stop to agonize over the moral dimensions of their actions, it's impossible to take their soul-searching seriously. Their actions would first have to make some kind of minimal sense.<br /><br />On top of all this, we must contend with the dubious acting abilities of Chris Pine. His portrayal of an arrogant young James T Kirk might have seemed shrewd, when viewed in isolation. But in Carriers he plays on exactly that same note: arrogant and boneheaded. It's impossible not to suspect that this constitutes his entire dramatic range.<br /><br />On the positive side, the film *looks* excellent. It's got an over-sharp, saturated look that really suits the southwestern US locale. But that can't save the truly feeble writing nor the paper-thin (and annoying) characters. Even if you're a fan of the end-of-the-world genre, you should save yourself the agony of watching Carriers."
0 b'I saw this movie at an actual movie theater (probably the \\(2.00 one) with my cousin and uncle. We were around 11 and 12, I guess, and really into scary movies. I remember being so excited to see it because my cool uncle let us pick the movie (and we probably never got to do that again!) and sooo disappointed afterwards!! Just boring and not scary. The only redeeming thing I can remember was Corky Pigeon from Silver Spoons, and that wasn\'t all that great, just someone I recognized. I\'ve seen bad movies before and this one has always stuck out in my mind as the worst. This was from what I can recall, one of the most boring, non-scary, waste of our collective \\)6, and a waste of film. I have read some of the reviews that say it is worth a watch and I say, "Too each his own", but I wouldn\'t even bother. Not even so bad it\'s good.'

Настройте набор данных для повышения производительности

Это два важных метода, которые вы должны использовать при загрузке данных, чтобы убедиться, что ввод-вывод не становится блокирующим.

.cache() хранит данные в памяти после того, как он будет загружен с диска. Это гарантирует, что набор данных не станет узким местом при обучении вашей модели. Если ваш набор данных слишком велик, чтобы уместиться в памяти, вы также можете использовать этот метод для создания производительного кеша на диске, который более эффективен для чтения, чем многие небольшие файлы.

.prefetch() перекрывает данные предварительной обработки и выполнение модели во время тренировки.

Вы можете узнать о более обоих методов, а также как данные кэша на диск в руководстве производительности данных .

AUTOTUNE = tf.data.AUTOTUNE

train_ds = train_ds.cache().prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)

Использование слоя встраивания

Keras упрощает использование встраивания слов. Посмотрите на Встраивание слоя.

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

# Embed a 1,000 word vocabulary into 5 dimensions.
embedding_layer = tf.keras.layers.Embedding(1000, 5)

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

Если вы передаете целое число на слой внедрения, результат заменяет каждое целое число вектором из таблицы внедрения:

result = embedding_layer(tf.constant([1, 2, 3]))
result.numpy()
array([[-0.04019697,  0.04224065,  0.00102   ,  0.01922709,  0.02511886],
       [ 0.00518478, -0.01365643, -0.03913582,  0.01221374,  0.01733081],
       [-0.03728701, -0.02411445,  0.01473696, -0.04623942, -0.02814811]],
      dtype=float32)

Для текстовых или последовательности задач, слой Встраивания принимает тензор 2D целых чисел, форм (samples, sequence_length) , где каждый элемент представляет собой последовательность целых чисел. Он может встраивать последовательности переменной длины. Вы можете кормить в вложению слой над партиями с формами (32, 10) (партия из 32 последовательностей длины 10) или (64, 15) (партии из 64 последовательностей длины 15).

У возвращенного тензора на одну ось больше, чем у входных, векторы внедрения выравниваются по новой последней оси. Передать его (2, 3) входной партии и выход (2, 3, N)

result = embedding_layer(tf.constant([[0, 1, 2], [3, 4, 5]]))
result.shape
TensorShape([2, 3, 5])

Когда дано партию последовательностей в качестве входных данных, вложение слоя возвращает тензор с плавающей точкой, 3D формы (samples, sequence_length, embedding_dimensionality) . Для преобразования этой последовательности переменной длины в фиксированное представление существует множество стандартных подходов. Вы можете использовать слой RNN, Attention или pooling, прежде чем передавать его на слой Dense. В этом руководстве используется пул, потому что он самый простой. Текст классификация с РННАМИ учебником является хорошим следующим шагом.

Предварительная обработка текста

Затем определите шаги предварительной обработки набора данных, необходимые для вашей модели классификации тональности. Инициализируйте слой TextVectorization с желаемыми параметрами для векторизации обзоров фильмов. Вы можете узнать больше об использовании этого слоя в классификации текста учебника.

# Create a custom standardization function to strip HTML break tags '<br />'.
def custom_standardization(input_data):
  lowercase = tf.strings.lower(input_data)
  stripped_html = tf.strings.regex_replace(lowercase, '<br />', ' ')
  return tf.strings.regex_replace(stripped_html,
                                  '[%s]' % re.escape(string.punctuation), '')


# Vocabulary size and number of words in a sequence.
vocab_size = 10000
sequence_length = 100

# Use the text vectorization layer to normalize, split, and map strings to
# integers. Note that the layer uses the custom standardization defined above.
# Set maximum_sequence length as all samples are not of the same length.
vectorize_layer = TextVectorization(
    standardize=custom_standardization,
    max_tokens=vocab_size,
    output_mode='int',
    output_sequence_length=sequence_length)

# Make a text-only dataset (no labels) and call adapt to build the vocabulary.
text_ds = train_ds.map(lambda x, y: x)
vectorize_layer.adapt(text_ds)

Создать модель классификации

С помощью API Keras Sequential для определения классификационной модели настроения. В данном случае это модель стиля «Сплошной мешок слов».

  • TextVectorization слой преобразует строки в словарные индексы. Вы уже инициализирована vectorize_layer как TextVectorization слой и построил его словарный запас, вызвав adapt на text_ds . Теперь vectorize_layer можно использовать в качестве первого уровня вашей модели сквозной классификации, подавая преобразованные строки в слой Embedding.
  • Embedding слой принимает целое число в кодировке словаря и ищет вложение вектора для каждого слова-индекса. Эти векторы изучаются по мере обучения модели. Векторы добавляют измерение к выходному массиву. Полученные размеры: (batch, sequence, embedding) .

  • GlobalAveragePooling1D слой возвращает выходной вектор фиксированной длины для каждого примера путем усреднения по размерности последовательности. Это позволяет модели обрабатывать ввод переменной длины самым простым способом.

  • Выходной вектор фиксированной длины по трубопроводу через полностью подключено ( Dense слой) с 16 скрытых блоками.

  • Последний слой плотно связан с единственным выходным узлом.

embedding_dim=16

model = Sequential([
  vectorize_layer,
  Embedding(vocab_size, embedding_dim, name="embedding"),
  GlobalAveragePooling1D(),
  Dense(16, activation='relu'),
  Dense(1)
])

Скомпилируйте и обучите модель

Вы будете использовать TensorBoard для визуализации показателей , включая потерю и точность. Создание tf.keras.callbacks.TensorBoard .

tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir="logs")

Обобщение и обучения модели , используя Adam оптимизатора и BinaryCrossentropy потери.

model.compile(optimizer='adam',
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              metrics=['accuracy'])
model.fit(
    train_ds,
    validation_data=val_ds,
    epochs=15,
    callbacks=[tensorboard_callback])
Epoch 1/15
20/20 [==============================] - 2s 61ms/step - loss: 0.6918 - accuracy: 0.5028 - val_loss: 0.6900 - val_accuracy: 0.4886
Epoch 2/15
20/20 [==============================] - 1s 49ms/step - loss: 0.6868 - accuracy: 0.5028 - val_loss: 0.6838 - val_accuracy: 0.4886
Epoch 3/15
20/20 [==============================] - 1s 49ms/step - loss: 0.6783 - accuracy: 0.5028 - val_loss: 0.6737 - val_accuracy: 0.4886
Epoch 4/15
20/20 [==============================] - 1s 49ms/step - loss: 0.6648 - accuracy: 0.5028 - val_loss: 0.6585 - val_accuracy: 0.4886
Epoch 5/15
20/20 [==============================] - 1s 48ms/step - loss: 0.6456 - accuracy: 0.5028 - val_loss: 0.6378 - val_accuracy: 0.4886
Epoch 6/15
20/20 [==============================] - 1s 48ms/step - loss: 0.6204 - accuracy: 0.5036 - val_loss: 0.6123 - val_accuracy: 0.4968
Epoch 7/15
20/20 [==============================] - 1s 49ms/step - loss: 0.5901 - accuracy: 0.5687 - val_loss: 0.5831 - val_accuracy: 0.5912
Epoch 8/15
20/20 [==============================] - 1s 48ms/step - loss: 0.5557 - accuracy: 0.6558 - val_loss: 0.5524 - val_accuracy: 0.6498
Epoch 9/15
20/20 [==============================] - 1s 49ms/step - loss: 0.5205 - accuracy: 0.7157 - val_loss: 0.5230 - val_accuracy: 0.6930
Epoch 10/15
20/20 [==============================] - 1s 48ms/step - loss: 0.4858 - accuracy: 0.7540 - val_loss: 0.4951 - val_accuracy: 0.7290
Epoch 11/15
20/20 [==============================] - 1s 48ms/step - loss: 0.4534 - accuracy: 0.7836 - val_loss: 0.4715 - val_accuracy: 0.7472
Epoch 12/15
20/20 [==============================] - 1s 49ms/step - loss: 0.4249 - accuracy: 0.8044 - val_loss: 0.4519 - val_accuracy: 0.7608
Epoch 13/15
20/20 [==============================] - 1s 48ms/step - loss: 0.3999 - accuracy: 0.8224 - val_loss: 0.4358 - val_accuracy: 0.7726
Epoch 14/15
20/20 [==============================] - 1s 48ms/step - loss: 0.3780 - accuracy: 0.8352 - val_loss: 0.4227 - val_accuracy: 0.7836
Epoch 15/15
20/20 [==============================] - 1s 49ms/step - loss: 0.3587 - accuracy: 0.8454 - val_loss: 0.4121 - val_accuracy: 0.7910
<keras.callbacks.History at 0x7f776eab1bd0>

При таком подходе модель достигает точности проверки около 78% (обратите внимание, что модель переобучена, поскольку точность обучения выше).

Вы можете изучить сводку модели, чтобы узнать больше о каждом слое модели.

model.summary()
Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 text_vectorization (TextVec  (None, 100)              0         
 torization)                                                     
                                                                 
 embedding (Embedding)       (None, 100, 16)           160000    
                                                                 
 global_average_pooling1d (G  (None, 16)               0         
 lobalAveragePooling1D)                                          
                                                                 
 dense (Dense)               (None, 16)                272       
                                                                 
 dense_1 (Dense)             (None, 1)                 17        
                                                                 
=================================================================
Total params: 160,289
Trainable params: 160,289
Non-trainable params: 0
_________________________________________________________________

Визуализируйте метрики модели в TensorBoard.

#docs_infra: no_execute
%load_ext tensorboard
%tensorboard --logdir logs

embeddings_classifier_accuracy.png

Получить обученные вложения слов и сохранить их на диск

Затем извлеките вложения слов, изученные во время обучения. Вложения - это веса слоя встраивания в модели. Матрица весов имеет форму (vocab_size, embedding_dimension) .

Получение веса от модели с использованием get_layer() и get_weights() . get_vocabulary() функция обеспечивает словарный запас для создания файла метаданных с одним маркером в каждой строке.

weights = model.get_layer('embedding').get_weights()[0]
vocab = vectorize_layer.get_vocabulary()

Запишите веса на диск. Для использования Встраивания проектора , вы будете загружать два файла в закладке разделенного формата: файл векторов (содержащее вложение), и файл метаданных (содержащие слова).

out_v = io.open('vectors.tsv', 'w', encoding='utf-8')
out_m = io.open('metadata.tsv', 'w', encoding='utf-8')

for index, word in enumerate(vocab):
  if index == 0:
    continue  # skip 0, it's padding.
  vec = weights[index]
  out_v.write('\t'.join([str(x) for x in vec]) + "\n")
  out_m.write(word + "\n")
out_v.close()
out_m.close()

Если вы работаете в этот учебник в Colaboratory , вы можете использовать следующий фрагмент кода , чтобы загрузить эти файлы на локальном компьютере (или используйте браузер файлов, View -> Содержание -> браузер файлов).

try:
  from google.colab import files
  files.download('vectors.tsv')
  files.download('metadata.tsv')
except Exception:
  pass

Визуализируйте вложения

Чтобы визуализировать вложения, загрузите их в встраивающий проектор.

Откройте Встраивание проектор (это также может работать в локальном экземпляре TensorBoard).

  • Щелкните «Загрузить данные».

  • Загрузите эти два файла , которые вы создали выше: vecs.tsv и meta.tsv .

Теперь будут отображаться обученные вами вложения. Вы можете искать слова, чтобы найти их ближайших соседей. Например, попробуйте поискать по слову «красивый». Вы можете увидеть соседей как «чудесных».

Следующие шаги

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