深度学习Review【四】编解码动⼿学深度学习笔记【三】
⼀、编码-解码
编码(训练):处理输出,把输⼊编程成中甲你表达形式(特征)
解码(预测):⽣成输出,把特征解码成输出
from torch import nn
石头的夏天class Encoder(nn.Module):
"""编码器-解码器结构的基本编码器接⼝。"""
def__init__(lf,**kwargs):
super(Encoder, lf).__init__(**kwargs)手机边充电边玩对电池有影响吗
def forward(lf, X,*args):
rai NotImplementedError
class Decoder(nn.Module):
"""编码器-解码器结构的基本解码器接⼝。"""
def__init__(lf,**kwargs):
super(Decoder, lf).__init__(**kwargs)
def init_state(lf, enc_outputs,*args):
rai NotImplementedError
def forward(lf, X, state):
rai NotImplementedError
class EncoderDecoder(nn.Module):
"""编码器-解码器结构的基类。"""
def__init__(lf, encoder, decoder,**kwargs):
super(EncoderDecoder, lf).__init__(**kwargs)
lf.decoder = decoder
def forward(lf, enc_X, dec_X,*args):
enc_outputs = lf.encoder(enc_X,*args)
dec_state = lf.decoder.init_state(enc_outputs,*args)
return lf.decoder(dec_X, dec_state)
⼆、Seq2q
训练过程,即Encode的过程(⼀个RNN)是双向的
解码器是单向的两位数减两位数
RNN也不需要定长的序列作为输⼊输出
把编码器的RNN最后⼀层的输出放在解码器⾥,作为初始隐状态torch
import collections
import math
import torch
from torch import nn
from d2l import torch as d2l
class Seq2SeqEncoder(d2l.Encoder):
"""⽤于序列到序列学习的循环神经⽹络编码器Encode"""
def__init__(lf, vocab_size, embed_size, num_hiddens, num_layers,dropout=0,**kwargs): super(Seq2SeqEncoder, lf).__init__(**kwargs)
# 嵌⼊层
#对每个词embedding
< = nn.GRU(embed_size, num_hiddens, num_layers,
入党培训教材测试题dropout=dropout)
#numlayers是RNN的层数 numhiddens是隐藏层的层数
def forward(lf, X,*args):
# 输出'X'的形状:(`batch_size`, `num_steps`, `embed_size`)
X = lf.embedding(X)
# 在循环神经⽹络模型中,第⼀个轴对应于时间步,交换batchsize和numstep
X = X.permute(1,0,2)
# 如果未提及状态,则默认为0
output, state = lf.rnn(X)
# `output`的形状: (`num_steps`, `batch_size`, `num_hiddens`)
# `state[0]`的形状: (`num_layers`, `batch_size`, `num_hiddens`)
return output, state
encoder = Seq2SeqEncoder(vocab_size=10, embed_size=8, num_hiddens=16,
num_layers=2)
encoder.eval()
X = s((4,7), dtype=torch.long)
output, state = encoder(X)
#output和state的形状torch.Size([7, 4, 16]) torch.Size([2, 4, 16])
class Seq2SeqDecoder(d2l.Decoder):
"""⽤于序列到序列学习的循环神经⽹络解码器。"""
def__init__(lf, vocab_size, embed_size, num_hiddens, num_layers,
dropout=0,**kwargs):
super(Seq2SeqDecoder, lf).__init__(**kwargs)
< = nn.GRU(embed_size + num_hiddens, num_hiddens, num_layers,
dropout=dropout)
lf.den = nn.Linear(num_hiddens, vocab_size)
#分类
def init_state(lf, enc_outputs,*args):
return enc_outputs[1]#enc_outputs[1]为state
def forward(lf, X, state):
阿米尔汗简介
# 输出'X'的形状:(`batch_size`, `num_steps`, `embed_size`)
X = lf.embedding(X).permute(1,0,2)
# ⼴播`context`,使其具有与`X`相同的`num_steps`
context = state[-1].repeat(X.shape[0],1,1)
X_and_context = torch.cat((X, context),2)
拔罐出水
output, state = lf.rnn(X_and_context, state)
output = lf.den(output).permute(1,0,2)
# `output`的形状: (`batch_size`, `num_steps`, `vocab_size`)
有什么恐龙
# `state[0]`的形状: (`num_layers`, `batch_size`, `num_hiddens`)
return output, state屈原的离骚
decoder = Seq2SeqDecoder(vocab_size=10, embed_size=8, num_hiddens=16,
num_layers=2)
decoder.eval()
state = decoder.init_state(encoder(X))
output, state = decoder(X, state)
# output和state的shape(torch.Size([4, 7, 10]), torch.Size([2, 4, 16]))