Большие потери и низкая точность данных обучения в BERT и ALBERT - PullRequest
0 голосов
/ 23 апреля 2020

Я использую huggingface TFBertModel для выполнения задачи классификации (отсюда: https://huggingface.co/transformers/model_doc/bert.html#tfbertmodel), я использую голый TFBertModel с добавленным плотным слоем головы, а не TFBertForSequenceClassification, так как Я не видел, как я мог бы использовать последние с использованием предварительно обученных весов только для тонкой настройки модели.

Насколько я знаю, точная настройка должна дать мне около 80% или более точности как в BERT, так и в ALBERT. , но я не подойду даже к этому числу:

Train on 3600 samples, validate on 400 samples
Epoch 1/2
3600/3600 [==============================] - 177s 49ms/sample - loss: 0.6531 - accuracy: 0.5792 - val_loss: 0.5296 - val_accuracy: 0.7675
Epoch 2/2
3600/3600 [==============================] - 172s 48ms/sample - loss: 0.6288 - accuracy: 0.6119 - val_loss: 0.5020 - val_accuracy: 0.7850

Больше эпох не имеет большого значения.

Я использую набор данных CoLA publi c для точной настройки (https://nyu-mll.github.io/CoLA/), вот как выглядят данные:

gj04    1       Our friends won't buy this analysis, let alone the next one we propose.
gj04    1       One more pseudo generalization and I'm giving up.
gj04    1       One more pseudo generalization or I'm giving up.
gj04    1       The more we study verbs, the crazier they get.
...

А вот код, который загружает данные в python:

import csv


def get_cola_data(max_items=None):
    csv_file = open('cola_public/raw/in_domain_train.tsv')

    reader = csv.reader(csv_file, delimiter='\t')
    x = []
    y = []

    for row in reader:
        x.append(row[3])
        y.append(float(row[1]))

    if max_items is not None:
        x = x[:max_items]
        y = y[:max_items]

    return x, y

Я проверил, что данные в том формате, в котором я хочу, чтобы они были в списках, и это код самой модели:

#!/usr/bin/env python

import tensorflow as tf
from tensorflow import keras
from transformers import BertTokenizer, TFBertModel
import numpy as np
from cola_public import get_cola_data


tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
bert_model = TFBertModel.from_pretrained('bert-base-uncased')

bert_model.trainable = False

x_input = keras.Input(shape=(512,), dtype=tf.int64)
x_mask = keras.Input(shape=(512,), dtype=tf.int64)

_, output = bert_model([x_input, x_mask])
output = keras.layers.Dense(1)(output)

model = keras.Model(
    inputs=[x_input, x_mask],
    outputs=output,
    name='bert_classifier',
)

model.compile(
    loss=keras.losses.BinaryCrossentropy(from_logits=True),
    optimizer=keras.optimizers.Adam(),
    metrics=['accuracy'],
)

train_data_x, train_data_y = get_cola_data(max_items=4000)

encoded_data = [tokenizer.encode_plus(data, add_special_tokens=True, pad_to_max_length=True) for data in train_data_x]

train_data_x = np.array([data['input_ids'] for data in encoded_data])
mask_data_x = np.array([data['attention_mask'] for data in encoded_data])

train_data_y = np.array(train_data_y)

model.fit(
    [train_data_x, mask_data_x],
    train_data_y,
    epochs=2,
    validation_split=0.1,
)

cmd_input = ''

while True:
    print("Type an opinion: ")
    cmd_input = input()
    # print('Your opinion is: %s' % cmd_input)

    if cmd_input == 'exit':
        break

    cmd_input_tokens = tokenizer.encode_plus(cmd_input, add_special_tokens=True, pad_to_max_length=True)
    cmd_input_ids = np.array([cmd_input_tokens['input_ids']])
    cmd_mask = np.array([cmd_input_tokens['attention_mask']])

    model.reset_states()
    result = model.predict([cmd_input_ids, cmd_mask])

    print(result)

Теперь, независимо от того, использую ли я другой набор данных, другое число элементов из наборов данных, если я использую выпадающий слой перед последним плотным слоем, если я дам еще один плотный слой перед Последний имеет большее количество единиц или если я использую Альберта вместо BERT, у меня всегда низкая точность и большие потери, и часто точность проверки выше точности обучения.

У меня те же результаты, если Я пытаюсь использовать BERT / ALBERT для задачи NER, всегда один и тот же результат, что заставляет меня поверить, что я систематически совершаю фундаментальную ошибку в тонкой настройке.

Я знаю, что у меня bert_model.trainable = False, и это то, что я хочу , поскольку я хочу тренировать только последнюю голову, а не предварительно подготовленные гири, и я знаю, что люди тренируются таким образом успешно. Даже если я тренируюсь с предтренированными весами, результаты намного хуже.

Я вижу, что у меня очень низкое телосложение, но я просто не могу положить палец туда, где я мог бы улучшить свое положение, особенно учитывая, что люди склонны Для достижения хороших результатов достаточно одного плотного слоя поверх модели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...