PyTorch搭建循环神经网络(RNN)实现字符串转换

RNN介绍

循环神经网络(Recurrent Neural Network, RNN)是一类以序列(sequence)数据为输入,在序列的演进方向进行递归(recursion)且所有节点(循环单元)按链式连接的递归神经网络(recursive neural network)

RNN网络结构

1.一般使用如下RNN展开后的结构:

RNN Cell本质上是一个线性层,而且这个线性层上的权重是共享的。为什么说他是线性层呢,比如输入一个3维数据,我们可以通过RNN Cell之后输出一个5维的数据,所以可以视为一个线性层。

PyTorch搭建循环神经网络(RNN)实现字符串转换

现在我们假设有一份数据,里面有5天的天气状况,属性里面有温度,气压和天气。假设让我们预测一下第6天的数据,我们就可以使用RNN来进行预测。还有像一些股票这些数据,数据里面带有时间序列的都是可以使用RNN来进行预测。

日期温度气压天气
2022.2.151522晴天
2022.2.161224阴天
2022.2.171122晴天
2022.2.181223晴天
2022.2.191221下雨

下面我们具体解释下RNN中参数的意思:

其中x1,x2,x3,x4是输入,如果拿上面的例子来说 x1 就是2022.2.15那天的一整行数据包括温度,气压,天气。

h0 称为 hidden(隐层),刚开始的时候一般初始化 h0 为全0。

h0 和 x1 通过RNN Cell后会输出一个 h1,这个 h1 也是 hidden(隐层),其中 h1 输出后也顺手送到了 x2 所在的RNN Cell里面,目的是为了使前后数据进行融合在一起。

下面我们看一下RNN Cell是具体怎么工作的,它是怎么把x和h融合到一块的:

我们通过下面这张图可以很清晰看到 ht 是怎么得到的,其中Wih,Whh,是权重,bih和bhh是偏置量,对于学过机器学习的应该不会陌生。

PyTorch搭建循环神经网络(RNN)实现字符串转换

2.但有时候也会使用如下的结构:

因为RNN网络架构所有使用的RNN Cell是一样的,通过循环后就是这样的结构。

PyTorch搭建循环神经网络(RNN)实现字符串转换

PyTorch中RNN写法

如果我们使用RNN Cell实现RNN,那么我们需要写一个循环,其中循环的内部可以这样写:

cell=torch.nn.RNNCell(input_size=input_size,hidden_size=hidden_size)

hidden1=cell(input,hidden)

其中input_size是输入的维度,hidden_size是隐层的维度,如果上面的input=x0,hidden=h0,那么最后通过cell()函数后得到的就是h1。

input大小为(batch,input_size)

hidden大小为(batch,input_size)

hidden1大小为(batch,hidden_size)

如果我们直接使用RNN函数,就不用再自己写循环。

其中RNN的参数主要如下所示:

PyTorch搭建循环神经网络(RNN)实现字符串转换

简单介绍几个参数:

input_size :拿上面天气的数据举例就是 每个样本中有几个属性,也就是用几维的向量表示,上面的数据input_size=4

batchSize:表示批次处理的大小,可以自定义

seq_len:比如拿上面的天气数据举例就是有几个样本,这个有5个样本就是sql_len=5

hidden_size:这里的hidden_size,你可以看做是隐含层中,隐含节点的个数

一般施工数据需要满足:

input.shape=(batchSize,input_size)

output.shape=(batchSize,hidden_size)

dataset.shape=(seq_len,batchSize,input_size)

RNN各返回值代表什么?

其中输入的inputs代表x1,x2,x3….

输入的hidden就是h0

然后通过cell()函数会返回两个值,out代表所有隐层的输出h1,h2,h3….。输出的hidden是最后输出的hN

PyTorch搭建循环神经网络(RNN)实现字符串转换

数据大小需要满足什么?

PyTorch搭建循环神经网络(RNN)实现字符串转换

任务

最后我们实现一个字符串转换任务,把hello这个字符串转换成ohlol字符,也就是如下图所示:

PyTorch搭建循环神经网络(RNN)实现字符串转换

首先,我们将字符串转换为 one-hot 向量表示

PyTorch搭建循环神经网络(RNN)实现字符串转换

然后计算交叉熵损失

PyTorch搭建循环神经网络(RNN)实现字符串转换

具体代码实现:

import torch
input_size=4
hidden_size=4#最后的输出
batch_size=1
num_layers=1
seq_len=5
idx2char=['e','h','l','o']
x_data=[1,0,2,2,3] #编码出hello对应的数值
y_data=[3,1,2,3,2]#编码出ohlol对应的数值

#定义独热向量表
one_hot_lookup=[
    [1,0,0,0],
    [0,1,0,0],
    [0,0,1,0],
    [0,0,0,1]
]
#将x_data中的每个数据取出来,并查one_hot_lookup这个表,转换成01组成的表
x_one_hot=[one_hot_lookup[x] for x in x_data]

inputs=torch.Tensor(x_one_hot).view(seq_len,batch_size,input_size)
labels=torch.LongTensor(y_data)
class Model(torch.nn.Module):
    def __init__(self,input_size,hidden_size,batch_size,num_layers=1):
        super(Model, self).__init__()
        self.num_layers=num_layers
        self.batch_size=batch_size
        self.input_size=input_size
        self.hidden_size=hidden_size
        self.rnn=torch.nn.RNN(input_size=self.input_size,
                              hidden_size=self.hidden_size,
                              num_layers=self.num_layers)
    def forward(self,input):
        hidden=torch.zeros(self.num_layers,
                           self.batch_size,
                           self.hidden_size)
        out,_=self.rnn(input,hidden)
        return out.view(-1,self.hidden_size)
net=Model(input_size,hidden_size,batch_size,num_layers)
criterion=torch.nn.CrossEntropyLoss()
optimizer=torch.optim.Adam(net.parameters(),lr=0.1)#Adam是改进的随机梯度优化器

for epoch in range(15000):
    optimizer.zero_grad()
    outputs=net(inputs)
    loss=criterion(outputs,labels)
    loss.backward()
    optimizer.step()
    _,idx=outputs.max(dim=1)
    idx=idx.data.numpy()
    print('Predicted:',''.join(idx2char[x] for x in idx),end='')
    print(',Epoch [%d/15] loss=%.4f'%(epoch+1,loss.item()))

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
乘风的头像乘风管理团队
上一篇 2022年3月16日 下午4:31
下一篇 2022年3月16日 下午4:49

相关推荐