В случае, если кому-то еще нужна помощь с этим, это было довольно сложное исправление, но вот что я сделал:
Изменено использование numpy массивов для наборов данных tf
Я не думаю, что это совершенно необходимо, поэтому, если вы все еще используете numpy массивы, тогда проигнорируйте этот абзац и соответственно измените приведенные ниже функции изменения формы (от tf.reshape до методов преобразования np)
С:
return [np.asarray(input_ids, dtype=np.int32),
np.asarray(attention_masks, dtype=np.int32),
np.asarray(token_type_ids, dtype=np.int32)]
До:
input_ids = tf.convert_to_tensor(input_ids)
attention_masks = tf.convert_to_tensor(attention_masks)
return input_ids, attention_masks
(поэтому списки преобразуются в тензор)
Функция преобразования входных вызовов (обратите внимание на пропуск token_type_ids)
Из документации маски внимания и идентификаторы типа токена являются необязательными для BERT. В этом примере я использую только input_ids и Внимание_Маски
train_ids, train_masks = create_input_array(df[:], tokenizer=tokenizer)
Изменение формы ввода
train_ids = tf.reshape(train_ids, (-1, 128, 1) )
train_masks = tf.reshape(train_masks, (-1, 128, 1) )
Преобразование меток в тензор
labels = tf.convert_to_tensor(y[:])
n_classes = np.unique(y).max() + 1
Импорт всех тензоров в набор данных tf
dataset = tf.data.Dataset.from_tensors(( (train_ids, train_masks), labels ))
Загрузите модель BERT и добавьте слои
Прежде чем все, что у меня было была однострочная модель = TFBert ... теперь я создаю входной слой для каждого из input_ids и масок, возвращая только первый вывод из слоя bert, сглаживаю, а затем добавляю плотный слой.
model = TFBertForSequenceClassification.from_pretrained('bert-base-uncased', trainable=False)
# Input layers
input_layer = Input(shape=(128, ), dtype=np.int32)
input_mask_layer = Input(shape=(128, ), dtype=np.int32)
# Bert layer, return first output
bert_layer = model([input_layer, input_mask_layer])[0]
# Flatten layer
flat_layer = Flatten() (bert_layer)
# Dense layer
dense_output = Dense(n_classes, activation='softmax') (flat_layer)
model_ = Model(inputs=[input_layer, input_mask_layer], outputs=dense_output)
Скомпилировать модель
optimizer = tf.keras.optimizers.Adam(learning_rate=1e-3, epsilon=1e-08, clipnorm=1.0)
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
metric = tf.keras.metrics.SparseCategoricalAccuracy('accuracy')
model_.compile(optimizer=optimizer, loss=loss, metrics=[metric])
Здесь весь набор данных передается в качестве первого аргумента, который также содержит метки.
model_.fit(dataset, epochs=4, batch_size=4, verbose=1)
Надеюсь, это помогает.