Я тонко настраиваю модель BERT из трансформаторов huggingface для задачи распознавания именованных сущностей. Входными данными для модели является одно слово, а выходными данными - тег этого слова. Я создал пользовательскую функцию генератора (data_generator), откуда я получаю данные во время обучения. Я заморозил слой bert в режиме обучения и добавил несколько слоев поверх него, чтобы предсказать тег данного слова.
Код следующий:
from tensorflow.keras.layers import Input, Dense, Activation, Dropout, LSTM, GlobalMaxPool1D
from tensorflow.keras.models import Model
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.preprocessing.sequence import pad_sequences
from transformers import BertTokenizer, TFBertModel, BertConfig
# Load the BERT tokenizer.
print('Loading BERT tokenizer...')
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased', do_lower_case=True)
bert = 'bert-base-uncased'
config = BertConfig(dropout=0.2, attention_dropout=0.2)
config.output_hidden_states = False
transformer_model = TFBertModel.from_pretrained(bert, config = config)
input_ids_in = Input(shape=(max_len,), name='input_token', dtype='int32')
input_masks_in = Input(shape=(max_len,), name='masked_token', dtype='int32')
embedding_layer = transformer_model(input_ids_in, attention_mask=input_masks_in)[0]
X = LSTM(50, return_sequences=True)(embedding_layer)
X = GlobalMaxPool1D()(X)
X = Dense(50, activation='relu')(X)
X = Dropout(0.2)(X)
X = Dense(num_labels, activation='softmax')(X)
model = Model(inputs=[input_ids_in, input_masks_in], outputs = X)
for layer in model.layers[:3]:
layer.trainable = False
model.compile(loss='categorical_crossentropy', optimizer='adam')
train_gen = data_generator(sentences, tags, tag2ix, max_len, number_sent_per_batch)
model.fit(train_gen, epochs=1, steps_per_epoch=steps, verbose=1)
Функция генератора это:
# data generator, intended to be used in a call to model.fit_generator()
def data_generator(sentences, tags, tag2ix, max_len, num_samples_per_batch):
X1, X2, y = list(), list(), list()
n=0
while 1:
for i in range(len(sentences)):
n += 1
encoded_dict = tokenizer.encode_plus(
sentences[i], # Sentence to encode.
add_special_tokens = True, # Add '[CLS]' and '[SEP]'
max_length = max_len, # Pad & truncate all sentences.
pad_to_max_length = True,
return_attention_mask = True, # Construct attn. masks.
#return_tensors = 'tf',
truncation=True
)
for idx in encoded_dict['input_ids']:
#idx = [encoded_dict['input_ids'][j]]
# Add the encoded sentence to the list.
idx = pad_sequences([[idx]], maxlen=max_len, padding='post')[0]
X1.append(idx)
for att_mask in encoded_dict['attention_mask']:
#att_mask = [encoded_dict['attention_mask'][j]]
# And its attention mask (simply differentiates padding from non-padding).
att_mask = pad_sequences([[att_mask]], maxlen=max_len, padding='post')[0]
X2.append(att_mask)
for k in tags[i]:
out = to_categorical([tag2ix[k]], num_classes=num_labels)[0]
y.append(out)
if n == num_samples_per_batch:
yield [[array(X1), array(X2)], array(y)]
X1, X2, y = list(), list(), list()
n=0
Я получаю следующую ошибку:
--------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-64-a19b18bb0230> in <module>()
----> 1 model.fit(train_gen, epochs=1, steps_per_epoch=steps, verbose=1)
2 #, validation_data=val_gen, validation_steps=val_steps
10 frames
/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/func_graph.py in wrapper(*args, **kwargs)
966 except Exception as e: # pylint:disable=broad-except
967 if hasattr(e, "ag_error_metadata"):
--> 968 raise e.ag_error_metadata.to_exception(e)
969 else:
970 raise
ValueError: in user code:
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:571 train_function *
outputs = self.distribute_strategy.run(
/usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py:951 run **
return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py:2290 call_for_each_replica
return self._call_for_each_replica(fn, args, kwargs)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py:2649 _call_for_each_replica
return fn(*args, **kwargs)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:541 train_step **
self.trainable_variables)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:1804 _minimize
trainable_variables))
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/optimizer_v2/optimizer_v2.py:521 _aggregate_gradients
filtered_grads_and_vars = _filter_grads(grads_and_vars)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/optimizer_v2/optimizer_v2.py:1219 _filter_grads
([v.name for _, v in grads_and_vars],))
ValueError: No gradients provided for any variable: ['lstm_2/lstm_cell_2/kernel:0', 'lstm_2/lstm_cell_2/recurrent_kernel:0', 'lstm_2/lstm_cell_2/bias:0', 'dense_8/kernel:0', 'dense_8/bias:0', 'dense_9/kernel:0', 'dense_9/bias:0'].
Я просмотрел множество ссылок, например:
https://github.com/tensorflow/tensorflow/issues/1511
https://github.com/tensorflow/tensorflow/issues/27949
и многие другие.
В этих проблемах с github есть много решений, но я не могу найти решение ошибка. Думаю, у меня ошибка в коде не в библиотеке тензорного потока. Вот почему я не знаю, в чем я ошибаюсь. Пожалуйста помоги. Заранее спасибо.
И я также хочу знать, в чем причина этой ошибки, поскольку я видел, как люди получали одну и ту же ошибку при различных проблемах (см. Ссылки выше). Я новичок в тензорном потоке, поэтому, если вы это знаете, дайте мне знать.