Seq2SeqEncoder和mask

import collections
import math
import torch
from torch import nn
from d2l import torch as d2l


class Seq2SeqEncoder(d2l.Encoder):
    def __init__(self,vocab_size,embed_size,num_hiddens,num_layers,dropout=0,**kwargs):
        #num_hiddens是一层有多少的隐藏单元
        super(Seq2SeqEncoder, self).__init__(**kwargs)
        #vocab_size词典的大小尺寸,比如总共出现5000个词,那就输入5000
        #embed_size 嵌入向量的维度,即用多少维来表示一个符号
        self.embedding = nn.Embedding(vocab_size,embed_size)
        #输入的是:输入向量的维度、隐藏层一层有多少单元、有多少隐藏层
        self.rnn=nn.GRU(embed_size,num_hiddens,num_layers,dropout=dropout)
    def forward(self,x,*args):
        x=self.embedding(x)
        #这里需要把时间步提前
        x=x.permute(1,0,2)
        #这里取出rnn最后一层的输出和状态
        output,state=self.rnn(x)
        return output,state

encoder=Seq2SeqEncoder(vocab_size=10,embed_size=8,num_hiddens=16,num_layers=2)
encoder.eval()
#4batch_size,7为句子长度;encoder输入的就是(batch_size,句子长度)
x=torch.zeros((4,7),dtype=torch.long)
output,state=encoder(x)
# print(output.shape)
#torch.Size([7, 4, 16])(batch_size,句子长度,隐藏层单元)
# print(state.shape)
#torch.Size([2, 4, 16])(层数,batch_size,隐藏层大小)
class Seq2SeqDecoder(d2l.Decoder):
    def __init__(self, vocab_size, embed_size, num_hiddens, num_layers, dropout=0, **kwargs):
        # num_hiddens是一层有多少的隐藏单元
        super(Seq2SeqDecoder, self).__init__(**kwargs)
        # vocab_size词典的大小尺寸,比如总共出现5000个词,那就输入5000
        # embed_size 嵌入向量的维度,即用多少维来表示一个符号
        #encoder和decoder不是一个嵌入模式,有可能一个法语一个英语
        self.embedding = nn.Embedding(vocab_size, embed_size)
        # #输入的是:输入向量的维度(由于输入是encoder的输出拼接上decoder的输入)、隐藏层一层有多少单元、有多少隐藏层
        self.rnn = nn.GRU(embed_size+num_hiddens, num_hiddens, num_layers, dropout=dropout)
        #decoder有一个输出层,输入隐藏层单元数,输出就是?单词表?
        self.dense=nn.Linear(num_hiddens,vocab_size)
    #将encoder最后一个时间步的状态,输入到decoder
    def init_state(self,enc_outputs,*args):
        #enc_outputs=output,state;enc_outputs[1]=state
        return enc_outputs[1]

    def forward(self, x, state,*args):
        x = self.embedding(x)
        # 这里需要把时间步提前
        x = x.permute(1, 0, 2)
        #state是最后一个时刻所有的隐藏状态,state[-1]就是最后一个时刻最后一层的隐藏状态
        #.repeat(),在指定维度重复多少次。.repeat(x.shape[0],1,1)在时间维度上重复decoder的时间维度次
        #状态在batch_size和xxx上是一样的,不过它只取了一个时间维度,所以需要扩充
        context=state[-1].repeat(x.shape[0],1,1)
        #将encoder输入和encoder最后一层的状态拼接,embed_size+num_hiddens
        x_and_context=torch.cat((x,context),2)
        # 这里取出rnn最后一层的输出和状态
        output, state = self.rnn(x_and_context,state)
        #将最后一层的output处理一下输出,转化为batch_size放在前面的样子
        output=self.dense(output).permute(1,0,2)
        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)
print(output.shape)
#torch.Size([4, 7, 10])(batch_size,句子长度,?vocab_size词典大小,这里是一个句子建立一个词典,也就是输出句子长度?)
print(state.shape)
#torch.Size([2, 4, 16])(层数,batch_size,隐藏层大小)
def sequence_mask(x,valid_len,value=0):
    #在序列中屏蔽不相关的项
    maxlen=x.size(1)
    #[None,:]tensor([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])将行归一化
    #[:,None]tensor([[3],[4]]),将列归一化
    mask=torch.arange((maxlen),dtype=torch.float32,device=x.device)[None,:]<valid_len[:,None]
    # print(mask)
    # tensor([[True, False, False],
    #         [True, True, False]])
    #利用判断出来的true、false矩阵赋值零,~取反,将为false(取反之后就是true)赋值为0
    x[~mask]=value
    return x

你可能感兴趣的:(李沐,pytorch,深度学习,python)