Обновление 10.13: недавно была выпущена новая современная модель предварительного обучения.Портал:
Ли Юмо: [НЛП] Подробное объяснение Google BERTzhuanlan.zhihu.com1. Введение
Векторы слов долгое время были доминирующим методом представления в задачах НЛП. После ряда технологических прорывов в конце 2017 и начале 2018 года исследования подтвердили, что предварительно обученные языковые представления могут повысить производительность при выполнении многочисленных задач НЛП после точной настройки. В настоящее время существует два метода предварительной подготовки:
- На основе функций: используйте обученное представление в качестве функции для задач из векторов слов, векторов предложений, векторов сегментов и векторов текста. Новый ELMo также попадает в эту категорию, но представление входных данных необходимо пересчитывать после миграции.
- Тонкая настройка: это в основном заимствовано из CV, которое заключается в добавлении некоторых слоев для конкретных задач в предварительно обученную модель, а затем в точной настройке последних слоев. Новые ULMFit и OpenAI GPT попадают в эту категорию.
В этой статье в основном представлены три предварительно обученные языковые модели ELMo, ULMFiT и OpenAI GPT.
2. ELMo
2.1 Принцип модели и архитектура
Оригинальная ссылка:Deep contextualized word representations
ELMo — это вложение, извлеченное из двунаправленной языковой модели (BiLM). BiLSTM используется во время обучения, учитывая N токенов (t1, t2,...,tN), цель состоит в том, чтобы максимизировать:
ELMo за каждый токен, 2L+1 представления вычисляются с помощью L-слоя biLM:
вявляется результатом прямого кодирования токена (здесь символы кодируются CNN),является выходом каждого слоя biLSTM.
Приложение сжимает выходные данные R всех слоев в ELMo в один вектор,, самый простой метод сжатия — взять результат верхнего слоя в качестве представления токена:, более общий подход заключается в объединении информации всех слоев по некоторым параметрам:
вэто вес от softmax,— это масштабный параметр, связанный с задачей, который очень важен в процессе оптимизации, а также потому, что выходное распределение каждого слоя BiLM отличается,Может играть роль нормализации слоев.
Предварительно обученный BiLM, используемый в статье,Jozefowicz et al.серединаCNN-BIG-LSTMНа основе были сделаны модификации, и окончательная модель2слой biLSTM (4096 единиц, 512 размерных проекций) с остаточными связями, добавленными между первым и вторым слоями. Контекстно-свободное кодирование токенов на уровне символов с использованием как CNN, так и двухслойного Highway. Наконец, модель выводит трехслойное векторное представление для каждого токена.
2.2 Меры предосторожности при обучении моделей
- Регуляризация:
1. Dropout
2. Добавьте к потерям штрафной пункт в виде веса.(Экспериментальные результаты показывают, что ELMo подходит для небольших )
- Исходный код версии TFРазобрать:
1. Код архитектуры модели в основном находится в классе LanguageModel учебного модуля, который разделен на два этапа: первый шаг — создание слоя встраивания слов или символов (CNN+Highway), второй шаг — создание слой BiLSTM.
2. Загрузите требуемую модель предварительного обучения как класс BidirectionalLanguageModel в модуле модели.
2.3 Использование модели
- Преобразуйте вектор ELMoс традиционными векторами словсращенный вПосле этого он вводится в РНС, соответствующую конкретной задаче.
- Поместите вектор ELMo в часть вывода модели, а вывод конкретной задачи RNNсращенный в.
- Пример кода Кераса
import tensorflow as tf
from keras import backend as K
import keras.layers as layers
from keras.models import Model
# Initialize session
sess = tf.Session()
K.set_session(sess)
# Instantiate the elmo model
elmo_model = hub.Module("https://tfhub.dev/google/elmo/1", trainable=True)
sess.run(tf.global_variables_initializer())
sess.run(tf.tables_initializer())
# We create a function to integrate the tensorflow model with a Keras model
# This requires explicitly casting the tensor to a string, because of a Keras quirk
def ElmoEmbedding(x):
return elmo_model(tf.squeeze(tf.cast(x, tf.string)), signature="default", as_dict=True)["default"]
input_text = layers.Input(shape=(1,), dtype=tf.string)
embedding = layers.Lambda(ElmoEmbedding, output_shape=(1024,))(input_text)
dense = layers.Dense(256, activation='relu')(embedding)
pred = layers.Dense(1, activation='sigmoid')(dense)
model = Model(inputs=[input_text], outputs=pred)
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.summary()
2.4 Преимущества и недостатки модели
преимущество:
- Эффект хороший, и в большинстве задач он лучше традиционной модели. Экспериментальные результаты показывают, что ELMo может лучше фиксировать синтаксическую и семантическую информацию, чем векторы слов.
- Традиционные предварительно обученные векторы слов могут обеспечить только один уровень представления, а размер словаря ограничен. ELMo обеспечивает представление на уровне символов без ограничения размера словарного запаса.
недостаток:
Скорость низкая, и кодировка каждого токена должна рассчитываться языковой моделью.
2.5 Применимые задачи
- Question Answering
- Textual entailment
- Semantic role labeling
- Coreference resolution
- Named entity extraction
- Sentiment analysis
3. ULMFiT
3.1 Принцип модели и архитектура
Оригинальная ссылка:Universal Language Model Fine-tuning for Text Classification
ULMFiT — это эффективный метод обучения переносу НЛП, основная идея которого заключается в выполнении других задач НЛП путем точной настройки предварительно обученной языковой модели. Языковая модель, используемая в этой статье, относится кMerity et al. 2017aизAWD-LSTMМодель, то есть трехслойная модель LSTM без внимания и ярлыков.
Процесс ULMFiT делится на три этапа:
1. General-domain LM pre-train
- Предобучение языковых моделей на Викитексте-103.
- Требования к предварительно обученному корпусу: большой объем и охват общих свойств языка
- Предварительное обучение хорошо работает для небольших наборов данных, после чего модель может обобщаться только с несколькими образцами.
2. Target task LM fine-tuning
В статье представлены два метода тонкой настройки:
- Discriminative fine-tuning
Поскольку разные уровни в сети могут захватывать разные типы информации, во время тонкой настройки также следует использовать разные скорости обучения. Автор назначает скорость обучения каждому слою, после эксперимента обнаруживается, что скорость обучения сначала определяется тонкой настройкой последнего слоя L модели, а затем рекурсивно выбрать скорость обучения предыдущего слоя для точной настройки, рекурсивная формула:
- Slanted triangular learning rates (STLR)
Чтобы выбрать параметры для конкретной задачи, идеально позволить параметрам быстро сойтись в подходящей области в начале обучения, а затем настроить их позже. Для достижения этого эффекта автор предлагает метод STLR, то есть LR кратковременно увеличивают в начале тренировки, а затем уменьшают. Как показано в правом верхнем углу рисунка б. Конкретная формула:
- T: number of training iterations
- cut_frac: fraction of iterations we increase the LR
- cut: the iteration when we switch from increasing to decreasing the LR
- p: the fraction of the number of iterations we have increased or will decrease the LR respectively
- ratio: specifies how much smaller the lowest LR is from thr max LR
- : the LR at iteration t
используется автором
3. Target task classifier fine-tuning
Чтобы завершить тонкую настройку задачи классификации, автор добавляет к последнему слою два линейных блока, каждый с пакетной нормой и отсевом, использует ReLU в качестве функции активации промежуточного слоя и, наконец, выводит распределение вероятностей классификация через softmax. Окончательная тонкая настройка включает в себя следующие этапы:
- Concat pooling
Входными данными для первого линейного слоя является объединение состояний последнего скрытого слоя. Поскольку ключевая информация для классификации текста может находиться где угодно в тексте, недостаточно просто использовать выходные данные последнего временного шага. Автор сделает окончательный временной шагс максимально возможным количеством временных шаговПосле объединения они соединяются вместе вв качестве ввода.
- Gradual unfreezing
Поскольку чрезмерная тонкая настройка приведет к тому, что модель забудет информацию, полученную в результате предыдущего предварительного обучения, автор предлагает метод постепенной разморозки слоев сети, начиная с последнего слоя для разморозки и тонкой настройки, а затем размораживания и тонкой настройки. -настройте все слои от заднего к переднему.
- BPTT for Text Classification (BPT3C)
Чтобы точно настроить модель на больших документах, автор делит документы на пакеты фиксированной длины b и записывает среднее и максимальное объединение во время обучения каждого пакета, а градиенты обратно распространяются на пакеты, которые вносят вклад в окончательный прогноз..
- Bidirectional language model
В наших экспериментах прямой и обратный LM точно настраиваются независимо, и предсказания обоих усредняются. Результаты комбинации двух имеют улучшение 0,5-0,7.
3.2 Меры предосторожности при обучении моделей
- Исходный код версии PyTorchРазобрать(Урок FastAI 10)
# location: fastai/lm_rnn.py
def get_language_model(n_tok, emb_sz, n_hid, n_layers, pad_token,
dropout=0.4, dropouth=0.3, dropouti=0.5, dropoute=0.1, wdrop=0.5, tie_weights=True, qrnn=False, bias=False):
"""Returns a SequentialRNN model.
A RNN_Encoder layer is instantiated using the parameters provided.
This is followed by the creation of a LinearDecoder layer.
Also by default (i.e. tie_weights = True), the embedding matrix used in the RNN_Encoder
is used to instantiate the weights for the LinearDecoder layer.
The SequentialRNN layer is the native torch's Sequential wrapper that puts the RNN_Encoder and
LinearDecoder layers sequentially in the model.
Args:
n_tok (int): number of unique vocabulary words (or tokens) in the source dataset
emb_sz (int): the embedding size to use to encode each token
n_hid (int): number of hidden activation per LSTM layer
n_layers (int): number of LSTM layers to use in the architecture
pad_token (int): the int value used for padding text.
dropouth (float): dropout to apply to the activations going from one LSTM layer to another
dropouti (float): dropout to apply to the input layer.
dropoute (float): dropout to apply to the embedding layer.
wdrop (float): dropout used for a LSTM's internal (or hidden) recurrent weights.
tie_weights (bool): decide if the weights of the embedding matrix in the RNN encoder should be tied to the
weights of the LinearDecoder layer.
qrnn (bool): decide if the model is composed of LSTMS (False) or QRNNs (True).
bias (bool): decide if the decoder should have a bias layer or not.
Returns:
A SequentialRNN model
"""
rnn_enc = RNN_Encoder(n_tok, emb_sz, n_hid=n_hid, n_layers=n_layers, pad_token=pad_token,
dropouth=dropouth, dropouti=dropouti, dropoute=dropoute, wdrop=wdrop, qrnn=qrnn)
enc = rnn_enc.encoder if tie_weights else None
return SequentialRNN(rnn_enc, LinearDecoder(n_tok, emb_sz, dropout, tie_encoder=enc, bias=bias))
def get_rnn_classifier(bptt, max_seq, n_class, n_tok, emb_sz, n_hid, n_layers, pad_token, layers, drops, bidir=False,
dropouth=0.3, dropouti=0.5, dropoute=0.1, wdrop=0.5, qrnn=False):
rnn_enc = MultiBatchRNN(bptt, max_seq, n_tok, emb_sz, n_hid, n_layers, pad_token=pad_token, bidir=bidir,
dropouth=dropouth, dropouti=dropouti, dropoute=dropoute, wdrop=wdrop, qrnn=qrnn)
return SequentialRNN(rnn_enc, PoolingLinearClassifier(layers, drops))
3.3 Преимущества и недостатки модели
преимущество:
По сравнению с другими методами трансферного обучения (ELMo) он больше подходит для решения следующих задач:
- Неанглийские языки, несколько помеченных данных обучения
- Новые задачи НЛП без современных моделей
- только некоторые задачи с данными тега
недостаток:
Его легче перенести для задач классификации и маркировки последовательности, а для сложных задач (вопрос-ответ и т. д.) требуются новые методы тонкой настройки.
3.4 Применимые задачи
- Classification
- Sequence labeling
4. OpenAI GPT
4.1 Принцип модели и архитектура
Оригинальная ссылка:Improving Language Understanding by Generative Pre-Training(неопубликовано)
OpenAI Transformer — это класс языковых моделей на основе Transformer, которые можно переносить на различные задачи НЛП. Его основная идея такая же, как и в ULMFiT, которая заключается в применении предварительно обученных языковых моделей к различным задачам без максимально возможного изменения структуры модели. Разница в том, что OpenAI Transformer выступает за использование структуры Transformer, а ULMFiT использует языковую модель на основе RNN. Структура сети, используемая в этой статье, выглядит следующим образом:
Процесс обучения модели делится на два этапа:
1. Unsupervised pre-training
Цель первого этапа — предварительно обучить языковую модель с учетом набора токенов.целевая функция состоит в том, чтобы максимизировать функцию правдоподобия:
Модель применяет многоголовое самовнимание, а затем добавляет слой прямого распространения с учетом положения и, наконец, выводит распределение:
2. Supervised fine-tuning
С предварительно обученной языковой моделью для помеченного обучающего набора, учитывая входную последовательностьи этикетки, который можно получить через языковую модель, после выходного слояСделать прогноз:
Тогда целевая функция:
Целевая функция всей задачи:
4.2 Меры предосторожности при обучении моделей
- Исходный код версии TFРазобрать
# location: finetune-transformer-lm/train.py
def model(X, M, Y, train=False, reuse=False):
with tf.variable_scope('model', reuse=reuse):
# n_special=3,作者把数据集分为三份
# n_ctx 应该是 n_context
we = tf.get_variable("we", [n_vocab+n_special+n_ctx, n_embd], initializer=tf.random_normal_initializer(stddev=0.02))
we = dropout(we, embd_pdrop, train)
X = tf.reshape(X, [-1, n_ctx, 2])
M = tf.reshape(M, [-1, n_ctx])
# 1. Embedding
h = embed(X, we)
# 2. transformer block
for layer in range(n_layer):
h = block(h, 'h%d'%layer, train=train, scale=True)
# 3. 计算语言模型loss
lm_h = tf.reshape(h[:, :-1], [-1, n_embd])
lm_logits = tf.matmul(lm_h, we, transpose_b=True)
lm_losses = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=lm_logits, labels=tf.reshape(X[:, 1:, 0], [-1]))
lm_losses = tf.reshape(lm_losses, [shape_list(X)[0], shape_list(X)[1]-1])
lm_losses = tf.reduce_sum(lm_losses*M[:, 1:], 1)/tf.reduce_sum(M[:, 1:], 1)
# 4. 计算classifier loss
clf_h = tf.reshape(h, [-1, n_embd])
pool_idx = tf.cast(tf.argmax(tf.cast(tf.equal(X[:, :, 0], clf_token), tf.float32), 1), tf.int32)
clf_h = tf.gather(clf_h, tf.range(shape_list(X)[0], dtype=tf.int32)*n_ctx+pool_idx)
clf_h = tf.reshape(clf_h, [-1, 2, n_embd])
if train and clf_pdrop > 0:
shape = shape_list(clf_h)
shape[1] = 1
clf_h = tf.nn.dropout(clf_h, 1-clf_pdrop, shape)
clf_h = tf.reshape(clf_h, [-1, n_embd])
clf_logits = clf(clf_h, 1, train=train)
clf_logits = tf.reshape(clf_logits, [-1, 2])
clf_losses = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=clf_logits, labels=Y)
return clf_logits, clf_losses, lm_losses
4.3 Преимущества и недостатки модели
преимущество:
- RNN захватывает меньше информации, в то время как Transformer захватывает более широкий диапазон информации.
- Скорость вычислений выше, чем у рекуррентной нейронной сети, легко распараллелить
- Экспериментальные результаты показывают, что Transformer лучше, чем сети ELMo и LSTM.
недостаток:
Некоторые типы задач требуют корректировки структуры входных данных
4.4 Применимые задачи
- Natural Language Inference
- Question Answering and commonsense reasoning
- Classification
- Semantic Similarity
5. Резюме
От Wrod Embedding к OpenAI Transformer, перенос обучения в НЛП с начального использования word2vec, GLoVe для представления вектора слов, к ELMo, обеспечивающему распределение веса для первых нескольких слоев, к ULMFiT и тонкой настройке всей модели предварительного обучения OpenAI Transformer, которая значительно улучшает эффект основных задач НЛП. В то же время ряд исследований также показал, что использование языковой модели в качестве модели для предварительного обучения позволяет не только фиксировать грамматическую информацию между словами, но и фиксировать семантическую информацию, предоставляя абстрактную информацию высокого уровня для последующих сетевых слоев. Кроме того, в некоторых аспектах модель на основе преобразователя также демонстрирует лучшие эффекты, чем модель RNN.
Наконец, есть еще много попыток выполнить конкретные задачи.Вы можете использовать вышеуказанные методы, чтобы сделать базовую модель, а затем настроить структуру сети, чтобы улучшить эффект.