?????作者簡(jiǎn)介:一位即將上大四,正專攻機(jī)器學(xué)習(xí)的保研er
??上期文章:機(jī)器學(xué)習(xí)&&深度學(xué)習(xí)——注意力提示、注意力池化(核回歸)
??訂閱專欄:機(jī)器學(xué)習(xí)&&深度學(xué)習(xí)
希望文章對(duì)你們有所幫助
接下來就要慢慢開始實(shí)戰(zhàn)了,把這邊過了,我們接下來就要進(jìn)行機(jī)器翻譯的實(shí)戰(zhàn)了。實(shí)戰(zhàn)完,我們需要開始學(xué)習(xí)當(dāng)今很先進(jìn)的transformer以及BERT,并且做點(diǎn)模型出來了。最近有點(diǎn)累了,做完這個(gè)以后會(huì)休息一兩天然后繼續(xù)肝,預(yù)推免前一定要肝出一些不錯(cuò)科研項(xiàng)目出來。
編碼器-解碼器結(jié)構(gòu)
機(jī)器翻譯是序列轉(zhuǎn)換模型的一個(gè)核心問題,其輸入和輸出都是長(zhǎng)度可變的序列。為了處理這種類型的輸入和輸出,我們可以設(shè)計(jì)一個(gè)包含兩個(gè)主要組件的架構(gòu):第一個(gè)組件是一個(gè)編碼器(encoder):它接受一個(gè)長(zhǎng)度可變的序列作為輸入,并將其轉(zhuǎn)換為具有固定形狀的編碼狀態(tài)。 第二個(gè)組件是解碼器(decoder):它將固定形狀的編碼狀態(tài)映射到長(zhǎng)度可變的序列。這被稱為編碼器-解碼器。結(jié)構(gòu)如圖:
所以我們之前遇到的CNN與RNN,某種程度上也可以看成這種結(jié)構(gòu)的。
比如之前分類貓狗的例子,CNN的特征抽取可以看成編碼器,其作用是將輸入編程成中間表達(dá)形式(特征);而softmax回歸就可以看成是解碼器,其將中間表示解碼成輸出。
而對(duì)于RNN,編碼器就是將文本表示成了向量,解碼器就是將向量表示成輸出。
這里將把“編碼器-解碼器”架構(gòu)轉(zhuǎn)換為接口方便后面的代碼實(shí)現(xiàn)。
編碼器
在編碼器接口中,我們只指定長(zhǎng)度可變的序列作為編碼器的輸入X。任何繼承這個(gè)Encoder基類的模型將完成代碼實(shí)現(xiàn)。
from torch import nn
#@save
class Encoder(nn.Module):
"""編碼器-解碼器架構(gòu)的基本編碼器接口"""
def __init__(self, **kwargs):
super(Encoder, self).__init__(**kwargs)
def forward(self, X, *args):
raise NotImplementedError
解碼器
解碼器接口中,我們新增一個(gè)init_state函數(shù),用于將編碼器的輸出(enc_outputs)轉(zhuǎn)換為編碼后的狀態(tài)(此步驟可能需要額外的輸入,例如:輸入序列的有效長(zhǎng)度)。 為了逐個(gè)地生成長(zhǎng)度可變的詞元序列,解碼器在每個(gè)時(shí)間步都會(huì)將輸入 (例如:在前一時(shí)間步生成的詞元)和編碼后的狀態(tài)映射成當(dāng)前時(shí)間步的輸出詞元。
#@save
class Decoder(nn.Module):
"""編碼器-解碼器架構(gòu)的基本解碼器接口"""
def __init__(self, **kwargs):
super(Decoder, self).__init__(**kwargs)
def init_state(self, enc_outputs, *args):
raise NotImplementedError
def forward(self, X, state):
raise NotImplementedError
合并編碼器和解碼器
總而言之,“編碼器-解碼器”架構(gòu)包含了一個(gè)編碼器和一個(gè)解碼器,并且還擁有可選的額外的參數(shù)。在前向傳播中,編碼器的輸出用于生成編碼狀態(tài),這個(gè)狀態(tài)又被解碼器作為其輸入的一部分。
#@save
class EncoderDecoder(nn.Module):
"""編碼器-解碼器架構(gòu)的基類"""
def __init__(self, encoder, decoder, **kwargs):
super(EncoderDecoder, self).__init__(**kwargs)
self.encoder = encoder
self.decoder = decoder
def forward(self, enc_X, dec_X, *args):
enc_outputs = self.encoder(enc_X, *args)
dec_state = self.decoder.init_state(enc_outputs, *args)
return self.decoder(dec_X, dec_state)
“編碼器-解碼器”體系架構(gòu)中的術(shù)語狀態(tài)會(huì)啟發(fā)人們使用具有狀態(tài)的神經(jīng)網(wǎng)絡(luò)來實(shí)現(xiàn)該架構(gòu)。
小結(jié)
1、“編碼器-解碼器”架構(gòu)可以將長(zhǎng)度可變的序列作為輸入和輸出,因此適用于機(jī)器翻譯等序列轉(zhuǎn)換問題。
2、編碼器將長(zhǎng)度可變的序列作為輸入,并將其轉(zhuǎn)換為具有固定形狀的編碼狀態(tài)。
3、解碼器將具有固定形狀的編碼狀態(tài)映射為長(zhǎng)度可變的序列。
序列到序列學(xué)習(xí)(seq2seq)
機(jī)器翻譯中的輸入序列和輸出序列都是長(zhǎng)度可變的。為了解決這個(gè)問題才提出了“編碼器-解碼器”架構(gòu)。這里將使用兩個(gè)循環(huán)神經(jīng)網(wǎng)絡(luò)的編碼器和解碼器,并將其應(yīng)用到序列到序列,也就是seq2seq類的學(xué)習(xí)任務(wù)。
循環(huán)神經(jīng)網(wǎng)絡(luò)編碼器使用長(zhǎng)度可變的序列作為輸入,將其轉(zhuǎn)換為固定形狀的隱狀態(tài)(可理解為輸入序列的信息被編碼到循環(huán)神經(jīng)網(wǎng)絡(luò)編碼器的隱狀態(tài)中)。為了連續(xù)生成輸出序列的詞元,獨(dú)立的循環(huán)神經(jīng)網(wǎng)絡(luò)解碼器是基于輸入序列的編碼信息和輸出序列已經(jīng)看見的或者生成的詞元來預(yù)測(cè)下一個(gè)詞元。
如下圖是機(jī)器翻譯英文為法語的過程圖,可以看出我們解碼器不僅會(huì)接受編碼器編碼出來的結(jié)果,還會(huì)接受其真正翻譯為法語的信息,因此我們根本不用擔(dān)心解碼器太長(zhǎng),然后預(yù)測(cè)錯(cuò)誤以后會(huì)一直錯(cuò),因?yàn)楸緛砭陀姓_的信息了。文章來源:http://www.zghlxwxcb.cn/news/detail-644072.html
再剖析一下這張圖,特定的“eos”表示序列結(jié)束詞元。一旦輸出序列生成此詞元,模型就會(huì)停止預(yù)測(cè)。
在循環(huán)神經(jīng)網(wǎng)絡(luò)解碼器的初始化時(shí)間步,有兩個(gè)特定的設(shè)計(jì)決定:首先,特定的“bos”表示序列開始詞元;其次,使用循環(huán)神經(jīng)網(wǎng)絡(luò)編碼器最終的隱狀態(tài)來初始化解碼器的隱狀態(tài)。
接下來將會(huì)利用seq2seq來實(shí)現(xiàn)機(jī)器翻譯。文章來源地址http://www.zghlxwxcb.cn/news/detail-644072.html
到了這里,關(guān)于機(jī)器學(xué)習(xí)&&深度學(xué)習(xí)——從編碼器-解碼器架構(gòu)到seq2seq(機(jī)器翻譯)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!