pytorch 递归神经网络,递归神经网络是循环神经网络的推广,循环神经网络的提出是基于记忆模型的想法,期望网络能够记住前面出现的特征,并依据特征推断后面的结果,而且整体的网络结构不断循环。归神经网络具有树状阶层结构且网络节点按其连接顺序对输入信息进行递归的人工神经网络。
递归神经网络支持单输出和多输出。在单输出模式下,其最末端子节点的系统状态会通过输出函数(例如分类器)得到结果。多输出模式下递归神经网络的输出取决于拓扑结构,在理论上其任意一个节点的系统状态都可以参与输出。循环神经网络的工作方式如下图所示:
在上图中,c1
,c2
,c3
和x1
为输入值,中间输出值为h1
,h2
,h3
,最终输出值为o1
现在将专注于实现PyTorch,以在递归神经网络的帮助下创建正弦波。训练期间,将遵循模型的训练方法,一次只有一个数据点。输入序列x
由20
个数据点组成,并且目标序列与输入序列相同。
第1步,导入需要的包名
import torch
from torch.autograd import Variable
import numpy as np
import pylab as pl
import torch.nn.init as init
第2步,设置模型参数,设置输入层的大小值为7,将有6个上下文神经元和1个输入神经元用于创建目标序列。
dtype = torch.FloatTensor
input_size, hidden_size, output_size = 7, 6, 1
epochs = 300
seq_length = 20
lr = 0.1
data_time_steps = np.linspace(2, 10, seq_length + 1)
data = np.sin(data_time_steps)
data.resize((seq_length + 1, 1))
x = Variable(torch.Tensor(data[:-1]).type(dtype), requires_grad=False)
y = Variable(torch.Tensor(data[1:]).type(dtype), requires_grad=False)
我们将生成训练数据,其中x为输入数据序列,y为需要的目标序列。
第3步,在递归神经网络中,采用零均值正态分布初始化权值。W1
表示对输入变量,w2表示生成的输出,如下所示:
w1 = torch.FloatTensor(input_size, hidden_size).type(dtype)
init.normal(w1, 0.0, 0.4)
w1 = Variable(w1, requires_grad = True)
w2 = torch.FloatTensor(hidden_size, output_size).type(dtype)
init.normal(w2, 0.0, 0.3)
w2 = Variable(w2, requires_grad = True)
第4步,现在创建一个预测函数,它唯一地定义了神经网络。
def forward(input, context_state, w1, w2):
xh = torch.cat((input, context_state), 1)
context_state = torch.tanh(xh.mm(w1))
out = context_state.mm(w2)
return (out, context_state)
第5步,启动递归神经网络正弦波实现的训练程序。外循环遍历每个循环,内循环遍历序列元素。在这里,还将计算均方误差(MSE),它有助于预测连续变量。
for i in range(epochs):
total_loss = 0
context_state = Variable(torch.zeros((1, hidden_size)).type(dtype), requires_grad = True)
for j in range(x.size(0)):
input = x[j:(j+1)]
target = y[j:(j+1)]
(pred, context_state) = forward(input, context_state, w1, w2)
loss = (pred - target).pow(2).sum()/2
total_loss += loss
loss.backward()
w1.data -= lr * w1.grad.data
w2.data -= lr * w2.grad.data
w1.grad.data.zero_()
w2.grad.data.zero_()
context_state = Variable(context_state.data)
if i % 10 == 0:
print("Epoch: {} loss {}".format(i, total_loss.item()))
context_state = Variable(torch.zeros((1, hidden_size)).type(dtype), requires_grad = False)
predictions = []
for i in range(x.size(0)):
input = x[i:i+1]
(pred, context_state) = forward(input, context_state, w1, w2)
context_state = context_state
predictions.append(pred.data.numpy().ravel()[0])
第6步,绘制正弦波,通过图形呈现训练结果。
plt.title("geek-docs.com", fontsize=20, fontname="Times New Roman")
pl.scatter(data_time_steps[:-1], x.data.numpy(), s = 90, label = "Actual")
pl.scatter(data_time_steps[1:], predictions, label = "Predicted")
pl.legend()
pl.show()
上述过程的输出结果如下: