[英]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
而不是英語,這就是為什么我需要先在預訓練的BERT
或SciBERT
上訓練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中編碼器的含義。 權重在編碼器中更新,這實際上可以用於多任務預訓練,如果在我的實驗中出現任何結果錯誤,它將更新。
我想經過一番研究,我發現了一些東西。 我不知道它是否會工作,但它使用transformer
和Tensorflow
和XLM
。 我認為它也適用於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.