Pytorch实战_Seq2seq模型
1. Sequence-to-Sequence 簡介
大多數(shù)常見的 sequence-to-sequence (seq2seq) model 為 encoder-decoder model,主要由兩個(gè)部分組成,分別是 Encoder 和 Decoder,而這兩個(gè)部分大多數(shù)是由 recurrent neural network (RNN) 實(shí)現(xiàn)。
Encoder 是將一連串的輸入,如文字、影片、聲音訊號等,編碼為單個(gè)向量,這個(gè)向量可以想像為整個(gè)輸入的抽象表示,包含了整個(gè)輸入的資訊。
Decoder 是將 Encoder 輸出的向量進(jìn)行逐步解碼,一次輸出一個(gè)結(jié)果,直到將最終的目標(biāo)全部輸出為止,每次輸出會(huì)影響下一個(gè)輸出,一般會(huì)在開始輸入 < BOS > 來表示開始解碼,會(huì)在結(jié)尾出輸出 < EOS > 來表示解碼結(jié)束。
2. 任務(wù)介紹
- 英文翻譯為中文
- 輸入: 一句英文 (e.g. tom is a student .)
- 輸出: 中文翻譯 (e.g. 湯姆 是 個(gè) 學(xué)生 。)
3. 實(shí)現(xiàn)過程
首先要做的是下載資料,主要是用來下載本次任務(wù)需要的數(shù)據(jù)集
!gdown --id '1r4px0i-NcrnXy1-tkBsIwvYwbWnxAhcg' --output data.tar.gz !tar -zxvf data.tar.gz !mkdir ckpt !ls之后導(dǎo)入需要用到的包(如果nltk包沒有下載的話,可使用第一段代碼進(jìn)行下載)
!pip3 install --user nltk import torch import torch.nn as nn import torch.optim as optim import torch.nn.functional as F import torch.utils.data as data import torch.utils.data.sampler as sampler import torchvision from torchvision import datasets, transformsimport numpy as np import sys import os import random import jsondevice = torch.device("cuda" if torch.cuda.is_available() else "cpu") # 判斷是用 CPU 還是 GPU 執(zhí)行運(yùn)算需要注意的是,不同的句子往往有著不同的長度,這無疑給訓(xùn)練帶來了不小的麻煩(因?yàn)?RNN 的輸入維度要進(jìn)行相應(yīng)的改變)。為了解決這個(gè)麻煩,我們使用 <pad> 長度較短的句子進(jìn)行填充。因此這里定義一個(gè)長度轉(zhuǎn)換的類
import numpy as npclass LabelTransform(object):def __init__(self, size, pad):self.size = sizeself.pad = paddef __call__(self, label):label = np.pad(label, (0, (self.size - label.shape[0])), mode='constant', constant_values=self.pad)return label下一步就是數(shù)據(jù)的準(zhǔn)備了,我們定義一個(gè)Dataset。
-
Data (出自manythings 的 cmn-eng):
- 訓(xùn)練資料:18000句
- 驗(yàn)證資料: 500句
- 測試資料: 2636句
-
資料預(yù)處理:
- 英文:
- 用 subword-nmt 套件將word轉(zhuǎn)為subword
- 建立字典:取出標(biāo)簽中出現(xiàn)頻率高于預(yù)定閾值的subword
- 中文:
- 用 jieba 將中文句子進(jìn)行斷句
- 建立字典:取出標(biāo)簽中出現(xiàn)頻率高于預(yù)定閾值的詞
- 特殊字元: < PAD >, < BOS >, < EOS >, < UNK >
- < PAD > :無意義,將句子拓展到相同長度
- < BOS > :Begin of sentence, 開始字元
- < EOS > :End of sentence, 結(jié)尾字元
- < UNK > :單字沒有出現(xiàn)在字典里的字
- 將字典里出現(xiàn)的 subword (詞) 用一個(gè)整數(shù)表示,分為英文和中文的字典,方便之后轉(zhuǎn)化為 one-hot vector
- 英文:
接下來就是構(gòu)建自己的模型
Encoder
- seq2seq模型的編碼器為RNN。對于每個(gè)輸入,Encoder 會(huì)輸出一個(gè)向量和一個(gè)隱藏層狀態(tài)(hidden state),并將隱藏層狀態(tài)用于下一個(gè)輸入,換句話說,Encoder 會(huì)逐步讀入輸入序列。
- 參數(shù):
- en_vocab_size 是英文字典的大小,也就是英文的 subword 的個(gè)數(shù)
- emb_dim 是 embedding 的維度,主要將 one-hot vector 的單詞向量壓縮到指定的維度,可以使用預(yù)先訓(xùn)練好的 word embedding,如 Glove 和 word2vector
- hid_dim 是 RNN 輸出和隱藏狀態(tài)的維度
- n_layers 是 RNN 要疊多少層
- dropout 是決定有多少的機(jī)率將某某個(gè)節(jié)點(diǎn)變?yōu)?0,主要是為了防止 overfitting ,一般來說是在訓(xùn)練集使用,測試集不使用
- Encoder 的輸入和輸出:
- 輸入:
- 英文的整數(shù)序列 e.g. 1, 28, 29, 205, 2
- 輸出:
- outputs: 最上層 RNN 全部的輸出,可以用 Attention 再進(jìn)行處理
- hidden: 每層最后的隱藏狀態(tài),將傳輸?shù)胶竺娴?Decoder 進(jìn)行解碼
- 輸入:
Decoder
-
Decoder 是另一個(gè) RNN,在最簡單的 seq2seq decoder 中,僅使用 Encoder 對每一層最后的隱藏狀態(tài)來進(jìn)行解碼,而這最好的的隱藏狀態(tài)有些被稱為 “content vector”,因?yàn)榭梢韵胂笏鼘φ麄€(gè)前文序列進(jìn)行了編碼, 此 “content vector” 用作 Decoder 的初始隱藏狀態(tài), 而 Encoder 的輸出通常用于 Attention Mechanism 產(chǎn)生相應(yīng)的 Attention。
-
參數(shù)
- en_vocab_size 是英文字典的大小,也就是英文的 subword 的個(gè)數(shù)
- emb_dim 是 embedding 的維度,主要將 one-hot vector 的單詞向量壓縮到指定的維度,可以使用預(yù)先訓(xùn)練好的 word embedding,如 Glove 和 word2vector
- hid_dim 是 RNN 輸出和隱藏狀態(tài)的維度
- output_dim 是最終輸出的維度,一般來說是將 hid_dim 轉(zhuǎn)到 one-hot vector 的單詞向量
- n_layers 是 RNN 要疊多少層
- dropout 是決定有多少的機(jī)率將某某個(gè)節(jié)點(diǎn)變?yōu)?0,主要是為了防止 overfitting ,一般來說是在訓(xùn)練集使用,測試集不使用
- isatt 是來決定是否使用 Attention Mechanism
-
Decoder 的輸入和輸出:
- 輸入:
- 前一次解碼出來的單詞的整數(shù)表示
- 輸出:
- hidden: 根據(jù)輸入和前一次的隱藏轉(zhuǎn)態(tài),現(xiàn)在的隱藏轉(zhuǎn)態(tài)的更新的結(jié)果
- output: 每個(gè)字有多少概率是這次解碼的結(jié)果
- 輸入:
Attention
-
當(dāng)輸入過長時(shí),或是單獨(dú)靠 “content vector” 無法獲取整個(gè)輸入的意思時(shí),用 Attention Mechanism 來提供 Decoder 更多的資訊
-
主要是根據(jù)現(xiàn)在 Decoder hidden state ,去計(jì)算在 Encoder outputs 中,那些與其有較高的關(guān)系,根據(jù)關(guān)系的數(shù)值來決定傳給 Decoder 哪些額外的資訊
-
常見 Attention 的操作是用 Neural Network / Dot Product 來計(jì)算 Decoder hidden state 和 Encoder outputs 之間的關(guān)系,再對所有算出來的數(shù)值做 softmax ,最后根據(jù)過完 softmax 的值對 Encoder outputs 做 weight sum
-
李宏毅老師的課程在此處并沒有給出具體的代碼,需要大家自己補(bǔ)充。大家可以參考這篇文章 Seq2Seq (Attention) 的 PyTorch 實(shí)現(xiàn) 或者B站的視頻 PyTorch35——基于注意力機(jī)制的Seq2Seq的PyTorch實(shí)現(xiàn)示例。
Seq2seq模型
- 由 Encoder 和 Decoder 組成
- 接收輸入并傳給 Encoder
- 將 Encoder 的輸出傳給 Decoder
- 不斷地將 Decoder 的輸出傳回 Decoder ,進(jìn)行解碼
- 當(dāng)解碼完成,將 Decoder 的輸出傳回
總結(jié)
以上是生活随笔為你收集整理的Pytorch实战_Seq2seq模型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hadoop Day06~MapRedu
- 下一篇: 利用百度定位