博客專欄

EEPW首頁 > 博客 > Python 實(shí)現(xiàn)注意力機(jī)制

Python 實(shí)現(xiàn)注意力機(jī)制

發(fā)布人:AI科技大本營 時(shí)間:2021-10-18 來源:工程師 發(fā)布文章

引言

隨著信息技術(shù)的發(fā)展,海量繁雜的信息向人們不斷襲來,信息無時(shí)無刻充斥在四周。然而人類所能接收的信息則是有限的,科研人員發(fā)現(xiàn)人類視覺系統(tǒng)在有限的視野之下卻有著龐大的視覺信息處理能力。在處理視覺數(shù)據(jù)的初期,人類視覺系統(tǒng)會迅速將注意力集中在場景中的重要區(qū)域上,這一選擇性感知機(jī)制極大地減少了人類視覺系統(tǒng)處理數(shù)據(jù)的數(shù)量,從而使人類在處理復(fù)雜的視覺信息時(shí)能夠抑制不重要的刺激,并將有限的神經(jīng)計(jì)算資源分配給場景中的關(guān)鍵部分,為更高層次的感知推理和更復(fù)雜的視覺處理任務(wù)(如物體識別、場景分類、視頻理解等)提供更易于處理且更相關(guān)的信息。借鑒人類視覺系統(tǒng)的這一特點(diǎn),科研人員提出了注意力機(jī)制的思想。對于事物來說特征的重要性是不同的,反映在卷積網(wǎng)絡(luò)中即每張?zhí)卣鲌D的重要性是具有差異性的。注意力機(jī)制的核心思想是通過一定手段獲取到每張?zhí)卣鲌D重要性的差異,將神經(jīng)網(wǎng)絡(luò)的計(jì)算資源更多地投入更重要的任務(wù)當(dāng)中,并利用任務(wù)結(jié)果反向指導(dǎo)特征圖的權(quán)重更新,從而高效快速地完成相應(yīng)任務(wù)。

近兩年,注意力模型被廣泛使用在自然語言處理、圖像識別、語音識別等各種不同類型的深度學(xué)習(xí)任務(wù)當(dāng)中。

如下圖所示,顏色越深的地方表示關(guān)注度越大,即注意力的權(quán)重越大。

1.png

故本項(xiàng)目將通過搭建 BiLSTM 的注意力機(jī)制模型來實(shí)現(xiàn)對時(shí)間數(shù)據(jù)的格式轉(zhuǎn)換,實(shí)現(xiàn)的最終結(jié)果如下:

2.png

注意力機(jī)制介紹

注意力機(jī)制最初在2014年作為RNN中編碼器-****框架的一部分來編碼長的輸入語句,后續(xù)被廣泛運(yùn)用在RNN中。例如在機(jī)器翻譯中通常是用一個(gè) RNN編碼器讀入上下文,得到一個(gè)上下文向量,一個(gè)RNN****以這個(gè)隱狀態(tài)為起始狀態(tài),依次生成目標(biāo)的每一個(gè)單詞。但這種做法的缺點(diǎn)是:無論之前的上下文有多長,包含多少信息量,最終都要被壓縮成一個(gè)幾百維的向量。這意味著上下文越大,最終的狀態(tài)向量會丟失越多的信息。輸入語句長度增加后,最終****翻譯的結(jié)果會顯著變差。事實(shí)上,因?yàn)樯舷挛脑谳斎霑r(shí)已知,一個(gè)模型完全可以在解碼的過程中利用上下文的全部信息,而不僅僅是最后一個(gè)狀態(tài)的信息,這就是注意力機(jī)制的基礎(chǔ)思想。

1.1

基本方法介紹

當(dāng)前注意力機(jī)制的主流方法是將特征圖中的潛在注意力信息進(jìn)行深度挖掘,最常見的是通過各種手段獲取各個(gè)特征圖通道間的通道注意力信息與特征圖內(nèi)部像素點(diǎn)之間的空間注意力信息,獲取的方法也包括但不僅限于卷積操作,矩陣操作構(gòu)建相關(guān)性矩陣等,其共同的目的是更深層次,更全面的獲取特征圖中完善的注意力信息,于是如何更深的挖掘,從哪里去挖掘特征圖的注意力信息,將極有可能會成為未來注意力方法發(fā)展的方向之一。

目前,獲取注意力的方法基本基于通道間的注意力信息、空間像素點(diǎn)之間的注意力信息和卷積核選擇的注意力信息,是否能夠從新的方向去獲取特征圖更豐富的注意力信息,或者以新的方式或手段去獲取更精準(zhǔn)的注意力信息也是未來需要關(guān)注的一個(gè)重點(diǎn)。

模型實(shí)驗(yàn)

2.1

數(shù)據(jù)處理

讀取數(shù)據(jù)集json文件,并將每一個(gè)索引轉(zhuǎn)換為對應(yīng)的one-hot編碼形式,并設(shè)置輸入數(shù)據(jù)最大長度為41。代碼如下:

with open('data/Time Dataset.json','r') as f:
    dataset = json.loads(f.read())
with open('data/Time Vocabs.json','r') as f:
    human_vocab, machine_vocab = json.loads(f.read())
human_vocab_size = len(human_vocab)
machine_vocab_size = len(machine_vocab)
m = len(dataset)
def preprocess_data(dataset, human_vocab, machine_vocab, Tx, Ty):
    m = len(dataset)
    X = np.zeros([m, Tx], dtype='int32')
    Y = np.zeros([m, Ty], dtype='int32')
    for i in range(m):
        data = dataset[i]
        X[i] = np.array(tokenize(data[0], human_vocab, Tx))
        Y[i] = np.array(tokenize(data[1], machine_vocab, Ty))
    Xoh = oh_2d(X, len(human_vocab))
    Yoh = oh_2d(Y, len(machine_vocab))
    return (X, Y, Xoh, Yoh)

3.png

2.2 網(wǎng)絡(luò)模型設(shè)置

其中Tx=41為序列的最大長度,Ty=5為序列長度,layer1 size設(shè)置為32為網(wǎng)絡(luò)層,1ayer2 size=64為注意力層,human vocab size=41表述human時(shí)間會用到41個(gè)不同的字符,machine vocab size=11表述machine時(shí)間會用到11個(gè)不同的字符。這里雙向LSTM作為Encoder編碼器,全連接層作為Decoder****。

代碼如下:

layer3 = Dense(machine_vocab_size, activation=softmax)
def get_model(Tx, Ty, layer1_size, layer2_size, x_vocab_size, y_vocab_size):
    X = Input(shape=(Tx, x_vocab_size))
    a1 = Bidirectional(LSTM(layer1_size, return_sequences=True), merge_mode='concat')(X)
    a2 = attention_layer(a1, layer2_size, Ty)
    a3 = [layer3(timestep) for timestep in a2]
    model = Model(inputs=[X], outputs=a3)
    return model

4.png

2.3

注意力網(wǎng)絡(luò)

為了達(dá)到反饋更新的作用,注意力網(wǎng)絡(luò)在每個(gè)輸出時(shí)間步上關(guān)注輸入的某些部分。_attention_表示哪些輸入與當(dāng)前輸出步驟最相關(guān)。如果一個(gè)輸入步驟是相關(guān)的,那么它的注意力權(quán)重為1,否則為0。_context_是“輸入的摘要”。全局定義部分注意力層,以便每個(gè)注意力都有相同的層次。代碼如下:

5.png

def one_step_of_attention(h_prev, a):
    h_repeat = at_repeat(h_prev)
    i = at_concatenate([a, h_repeat])
    i = at_dense1(i)
    i = at_dense2(i)
    attention = at_softmax(i)
    context = at_dot([attention, a])
    return context
def attention_layer(X, n_h, Ty):
    h = Lambda(lambda X: K.zeros(shape=(K.shape(X)[0], n_h)))(X)
    c = Lambda(lambda X: K.zeros(shape=(K.shape(X)[0], n_h)))(X)
    at_LSTM = LSTM(n_h, return_state=True)
    output = []
    for _ in range(Ty):
        context = one_step_of_attention(h, X)
        h, _, c = at_LSTM(context, initial_state=[h, c])
        output.append(h)
    return output

2.4 模型訓(xùn)練評估

通過調(diào)用get_model函數(shù)獲取整個(gè)模型架構(gòu),并使用adam優(yōu)化器迭代更新,創(chuàng)建交叉熵?fù)p失函數(shù)最后訓(xùn)練和評估。

代碼如下:

model = get_model(Tx, Ty, layer1_size, layer2_size, human_vocab_size, machine_vocab_size)
opt = Adam(lr=0.05, decay=0.04, clipnorm=1.0)
model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])
outputs_train = list(Yoh_train.swapaxes(0,1))
model.fit([Xoh_train], outputs_train, epochs=30, batch_size=100)
outputs_test = list(Yoh_test.swapaxes(0,1))
score = model.evaluate(Xoh_test, outputs_test) 
print('Test loss: ', score[0])

圖片

完整代碼:

鏈接:

https://pan.baidu.com/s/1d9delZAQ7gepH9T9um4dMQ

提取碼:a2ed

*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請聯(lián)系工作人員刪除。



關(guān)鍵詞: AI

相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉