簡體   English   中英

如何在 MLM 任務上訓練 Tensorflow 的預訓練 BERT? (僅在 Tensorflow 中使用預訓練的 model)

[英]How to train Tensorflow's pre trained BERT on MLM task? ( Use pre-trained model only in Tensorflow)

在有人建議pytorch和其他東西之前,我專門尋找Tensorflow +預訓練+傳銷任務。 我知道,有很多關於PyTorch的博客和很多關於 Tensorflow 的微調(分類)博客。

遇到問題,我得到了一種語言 model 即英語 + LaTex,其中文本數據可以表示物理、化學、數學和生物學中的任何文本,任何典型示例都可以看起來像這樣:鏈接到 OCR 圖像

"Find the value of function x in the equation: \n \\( f(x)=\\left\\{\\begin{array}{ll}x^{2} & \\text { if } x<0 \\\\ 2 x & \\text { if } x \\geq 0\\end{array}\\right. \\)"

所以我的語言 model 需要理解\geq \\begin array \eng \left \right而不是英語,這就是為什么我需要先在預訓練的BERTSciBERT上訓練MLM以同時具備兩者。 所以我去挖掘互聯網並找到了一些教程:

  1. Tensorflow BUT 從零開始進行MLM培訓; 我需要預先訓練
  2. 預訓練但在Pytorch中的MLM 我需要Tensorflow
  3. 使用 Keras 進行微調; 這是分類但我想要MLM

我已經有了一個微調分類 model。 部分代碼如下:

tokenizer = transformers.BertTokenizer.from_pretrained('bert-large-uncased')

def regular_encode(texts, tokenizer, maxlen=maxlen):
  enc_di = tokenizer.batch_encode_plus(texts,  return_token_type_ids=False,padding='max_length',max_length=maxlen,truncation = True,)
  return np.array(enc_di['input_ids'])

Xtrain_encoded = regular_encode(X_train.astype('str'), tokenizer, maxlen=maxlen)
ytrain_encoded = tf.keras.utils.to_categorical(y_train, num_classes=classes,dtype = 'int32')

def build_model(transformer, loss='categorical_crossentropy', max_len=maxlen, dense = 512, drop1 = 0.3, drop2 = 0.3):
    input_word_ids = tf.keras.layers.Input(shape=(max_len,), dtype=tf.int32, name="input_word_ids")
    sequence_output = transformer(input_word_ids)[0]
    cls_token = sequence_output[:, 0, :]

    #Fine Tuning Model Start
    x = tf.keras.layers.Dropout(drop1)(cls_token)  
    x = tf.keras.layers.Dense(512, activation='relu')(x)
    x = tf.keras.layers.Dropout(drop2)(x)
    out = tf.keras.layers.Dense(classes, activation='softmax')(x)
    model = tf.keras.Model(inputs=input_word_ids, outputs=out)
    return model

我能得到的唯一有用的東西是在HuggingFace

With the tight interoperability between TensorFlow and PyTorch models, you can even save the model and then reload it as a PyTorch model (or vice-versa)

from transformers import AutoModelForSequenceClassification

model.save_pretrained("my_imdb_model")
pytorch_model = AutoModelForSequenceClassification.from_pretrained("my_imdb_model", from_tf=True)

所以也許我可以訓練一個pytorch MLM ,然后將其加載為tensorflow微調分類 model? 還有其他方法嗎?

我也遇到了這個問題,做了一些研究。 一種可能的解決方案是使用支持 mlm 的 tensorflow_hub 模型。

比如https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-10_H-128_A-2/2這個model有一個比較完整的教程,介紹如何創建mlm任務。 但是,如果您正在設計多任務,就會出現問題。 因為:

import tensorflow_hub as hub

encoder = hub.load(model_path)
mlm = hub.KerasLayer(encoder.mlm, trainable=True)

我不太確定這對多任務有幫助,因為我不知道編碼器是否已更新。 希望這可能有用,也許有人也可以幫助我。 謝謝。

一些更新:我查看了tfhub 的官方文檔,我想我弄錯了這個model中編碼器的含義。 權重在編碼器中更新,這實際上可以用於多任務預訓練,如果在我的實驗中出現任何結果錯誤,它將更新。

我想經過一番研究,我發現了一些東西。 我不知道它是否會工作,但它使用transformerTensorflowXLM 我認為它也適用於BERT

PRETRAINED_MODEL = 'jplu/tf-xlm-roberta-large'
from tensorflow.keras.optimizers import Adam
import transformers
from transformers import TFAutoModelWithLMHead, AutoTokenizer

def create_mlm_model_and_optimizer():
    with strategy.scope():
        model = TFAutoModelWithLMHead.from_pretrained(PRETRAINED_MODEL)
        optimizer = tf.keras.optimizers.Adam(learning_rate=LR)
    return model, optimizer


mlm_model, optimizer = create_mlm_model_and_optimizer()




def define_mlm_loss_and_metrics():
    with strategy.scope():
        mlm_loss_object = masked_sparse_categorical_crossentropy

        def compute_mlm_loss(labels, predictions):
            per_example_loss = mlm_loss_object(labels, predictions)
            loss = tf.nn.compute_average_loss(
                per_example_loss, global_batch_size = global_batch_size)
            return loss

        train_mlm_loss_metric = tf.keras.metrics.Mean()
        
    return compute_mlm_loss, train_mlm_loss_metric


def masked_sparse_categorical_crossentropy(y_true, y_pred):
    y_true_masked = tf.boolean_mask(y_true, tf.not_equal(y_true, -1))
    y_pred_masked = tf.boolean_mask(y_pred, tf.not_equal(y_true, -1))
    loss = tf.keras.losses.sparse_categorical_crossentropy(y_true_masked,
                                                          y_pred_masked,
                                                          from_logits=True)
    return loss

            
            
def train_mlm(train_dist_dataset, total_steps=2000, evaluate_every=200):
    step = 0
    ### Training lopp ###
    for tensor in train_dist_dataset:
        distributed_mlm_train_step(tensor) 
        step+=1

        if (step % evaluate_every == 0):   
            ### Print train metrics ###  
            train_metric = train_mlm_loss_metric.result().numpy()
            print("Step %d, train loss: %.2f" % (step, train_metric))     

            ### Reset  metrics ###
            train_mlm_loss_metric.reset_states()
            
        if step  == total_steps:
            break


@tf.function
def distributed_mlm_train_step(data):
    strategy.experimental_run_v2(mlm_train_step, args=(data,))


@tf.function
def mlm_train_step(inputs):
    features, labels = inputs

    with tf.GradientTape() as tape:
        predictions = mlm_model(features, training=True)[0]
        loss = compute_mlm_loss(labels, predictions)

    gradients = tape.gradient(loss, mlm_model.trainable_variables)
    optimizer.apply_gradients(zip(gradients, mlm_model.trainable_variables))

    train_mlm_loss_metric.update_state(loss)
    

compute_mlm_loss, train_mlm_loss_metric = define_mlm_loss_and_metrics()

現在將其訓練為train_mlm(train_dist_dataset, TOTAL_STEPS, EVALUATE_EVERY)

上面的頌歌來自這個筆記本,你需要做所有必要的事情。

作者最后說:

這個經過微調的 model 可以像原來一樣加載,從中構建一個分類 model

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM