主要內容:
(1)瞭解Transformer的原理和基於預訓練語言模型(Bert)的詞表示
(2)學會Bert的使用,具體包括pretrain和finetune(預訓練與微調)
一個手把手教原理和實現的up主視訊,超讚!!!!就是手把手教論文細節!和他的有詳細註釋的github程式碼以及知乎專欄
transformer block:
(1)自向量與位置編碼
(2)自注意力機制 機製
(3)殘差連線(resnet)與layer normolization
(4)feed forward
具體看這裏
最後講這些block堆疊組合(一般12個layer)
藉助sin cos用以表示文字之間的位置關係(因爲bert裏面沒有像LSTM一樣的前後迭代的過程)
這樣對於一個詞:
表示位置的編碼+文字本身的嵌入編碼=文字的初始embedding(或者理解爲初始的特徵也行?)
把embedding dimension平等分成h塊
h是embedding dimension分成的份數
得到三個矩陣:Q,K,V維度:[batch size,h,sequence length,embedding dim/h ]
self_attention:
K的轉置只轉置後面兩維,這樣做出來的內積能夠表示出前後的距離關係(因爲sequence length所在的維度表現了語句元的位置關係)
是爲了使得注意力矩陣標準化
兩層線性變換後用啓用函數啓用再傳入(3)
15%的內容(token)做掩碼:
(1)80%機率換成[mask]
(2)10%機率換成其它的任意詞
(3)10%機率不改變
用模型預測這些被掩蓋的內容,計算這些內容的loss
=[batch_size,seq_len,embedding_dim]
[embedding_dim,vocab_size] (vocab_size是字典中所有詞的個數)
對vocab_size softmax
在原語句中加入以下部分:
每個句子的
開頭[cls]:開始符
結尾[seq]:句子間間隔符
input中對每個詞的嵌入(類似於詞向量)有:
[tokem embedding]:每個字的嵌入
[segment embedding]:每句話的嵌入
[position embedding]:位置的嵌入
最後取中的[:,0,:]來代表每一個句子,得到結果cls_vector=[batch_size,embedding_dim]
輸出分類依據:
對於模型的使用方面有以下情況:
(1)使用自己的數據集進行預訓練(適用於專業性較強或數據集已經過編碼的情況)
這時候參考下面 下麪模型訓練的部分,需要自己做分詞,構造詞典,進行預訓練
(2)呼叫官方的預訓練模型,後面就只需要進行微調
裏面的內容包含:
(1)怎樣分詞
(2)bert模型訓練
(3)構造特徵
內容具體而全面,程式碼簡潔易懂,在這裏就不做複述了。
微調的過程可以理解爲原來的預訓練模型得到了詞語的特徵和關聯,預訓練結束後房子的大致形狀已經確定了,現在在原來的房子裏面加電線水管,通水電煤氣進行測試,測試過程中除了裝管道還需要對房子的一些部分做修改,這就是對測試集的X,Y進行擬合調整參數(之前的預訓練只使用了X)。
官方預訓練模型,其中包含多種大的小的,中文的英文的預訓練模型,進去選擇點集下載
非官方例子,(基於keras),強烈安利
(1)文字分類
(2)關係抽取
(3)主體抽取
主要就是在預訓練模型的基礎上加入一個全連線層&sigmoid函數進行分類
from keras_bert import load_trained_model_from_checkpoint
#匯入模型
bert_model = load_trained_model_from_checkpoint(config_path, checkpoint_path, seq_len=None)
#讓原來的模型可訓練
for l in bert_model.layers:
l.trainable = True
#設定輸入格式,每個詞的輸入有兩部分
#(第一部分是這個詞的詞向量,x1代表這一部分的維度;另一部分x2是segment_id代表句子的id,即這個詞屬於哪一個句子)
#上面兩個維度使用Tokenizer中的encode函數能直接輸出
#實際上還可以加上第三個維度來體現詞在句子中的位置.
x1_in = Input(shape=(None,))
x2_in = Input(shape=(None,))
x = bert_model([x1_in, x2_in])
x = Lambda(lambda x: x[:, 0])(x) # 取出句子起始符[CLS]對應的向量用來做分類
p = Dense(1, activation='sigmoid')(x)
#x1_in是預訓練輸入的維度
#x2_in是
model = Model([x1_in, x2_in], p)
model.compile(
loss='binary_crossentropy',#二分類的情況,多分類用交叉熵
optimizer=Adam(1e-5), # 用足夠小的學習率
metrics=['accuracy']
)
model.summary()
ps:由於算力問題&不想再裝包了就不寫這個的demo了
對於大量數據加速計算可以使用TPU,現在在colab上可以氪金用遼。