日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Tensorflow2.0 + Transformers 实现Bert FGM对抗训练惩罚梯度损失函数

發布時間:2025/3/8 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Tensorflow2.0 + Transformers 实现Bert FGM对抗训练惩罚梯度损失函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Tensorflow2.0 + Transformers 實現Bert FGM對抗訓練懲罰梯度損失函數

  • 前言
  • 變種實現
  • Transformers中的word_embeddings
  • 代碼修改
  • 實驗效果
  • 總結


前言

之前看了很多關于NLP中應用對抗訓練的文章,測試結果都很香,所以想在自己在用的模型上試一試看看能不能提升效果,參考了一些代碼找到了pytroch和keras實現,但發現對于tensorflows來說更改訓練過程非常繁瑣,而且容易出錯,如果要配合transformers實現則更難
——transformers的bert類會被打包成一個layers,在調用tf.layers時拿不到里面的embedding_layers,如果有大神知道怎么拿還望留言告知~


變種實現

但最近看了一篇文章對抗訓練淺談:意義、方法和思考(附Keras實現)
文中講到了FGM的效果等價轉化式:

***這里有個小技巧使用了一階泰勒展開:

并且文章也給出了keras的實現代碼:

def sparse_categorical_crossentropy(y_true, y_pred):"""自定義稀疏交叉熵這主要是因為keras自帶的sparse_categorical_crossentropy不支持求二階梯度。"""y_true = K.reshape(y_true, K.shape(y_pred)[:-1])y_true = K.cast(y_true, 'int32')y_true = K.one_hot(y_true, K.shape(y_pred)[-1])return K.categorical_crossentropy(y_true, y_pred)def loss_with_gradient_penalty(y_true, y_pred, epsilon=1):"""帶梯度懲罰的loss"""loss = K.mean(sparse_categorical_crossentropy(y_true, y_pred))embeddings = search_layer(y_pred, 'Embedding-Token').embeddingsgp = K.sum(K.gradients(loss, [embeddings])[0].values**2)return loss + 0.5 * epsilon * gpmodel.compile(loss=loss_with_gradient_penalty,optimizer=Adam(2e-5),metrics=['sparse_categorical_accuracy'], )

但可惜的是在loss_with_gradient_penalty部分仍然需要調用kerasbert的方法search_layer,但transformers中的get_input_embeddings在調用時一直報錯(可能我用法不對)


Transformers中的word_embeddings

但是發現tf除了通過tf.layers追蹤到相應的參數,還能通過model.variables這個方法,
調用 model.variables (model為你搭建好的模型名稱)會返回一個list,里面是按順序排列好的tensor參數,在這里通過 model.variables[0] 即可找到模型的第一層參數:word_embeddings


可以看到前三組參數分別為word_embeddings, position_embeddings, token_type_embeddings, 這里我們只要取word_embeddings(NLP中對抗訓練的擾動對象)即可。


代碼修改

因此我們可以簡單的修改原來的代碼:

def sparse_categorical_crossentropy(y_true, y_pred):y_true = tf.reshape(y_true, tf.shape(y_pred)[:-1])y_true = tf.cast(y_true, tf.int32)y_true = tf.one_hot(y_true, K.shape(y_pred)[-1])return tf.keras.losses.categorical_crossentropy(y_true, y_pred)def loss_with_gradient_penalty(model,epsilon=1):def loss_with_gradient_penalty_2(y_true, y_pred):loss = tf.math.reduce_mean(sparse_categorical_crossentropy(y_true, y_pred))embeddings = model.variables[0]gp = tf.math.reduce_sum(tf.gradients(loss, [embeddings])[0].values**2)return loss + 0.5 * epsilon * gpreturn loss_with_gradient_penalty_2

調用方法:

bert_ner_model.compile(optimizer=optimizer, loss=[loss_with_gradient_penalty(bert_ner_model,1.0)], metrics=['sparse_categorical_accuracy'])

實驗效果

原sparse_cross_entropy結果:

加入懲罰項(epsilon = 1)結果:

加入懲罰項(epsilon = 0.5)結果:


總結

可以看到使用該懲罰梯度損失函數,以為要計算兩次梯度,訓練時間增加了2倍之多,但模型效果有了一個點左右的提升,而且不容易過擬合。所以看出,盡管無法復原FGM的方法,該用效果差不多的懲罰梯度損失函數,還是可以獲得一定的提升(前提是epsilon這個超參要調好)


參考鏈接:https://spaces.ac.cn/archives/7234

總結

以上是生活随笔為你收集整理的Tensorflow2.0 + Transformers 实现Bert FGM对抗训练惩罚梯度损失函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。