网络结构-RNN
RNN称为循环神经网络,大家不要被他的名字吓到了,其实他只是和线性层的区别就是计算方式不一样。他是一种用来被用来处理序列的层,对于下列信息“What time is it ?”假设我们把它分成5个样本,如下图所示,对于线性层来说,就是把5个文本的信息一起输入线性层,而对于RNN来说是一个一个信息输入后计算,最终取最后一层信息作为输出。
计算公式
说了那么多,那他的计算公式是怎么样的呢?
h
(
t
)
=
t
a
n
h
(
b
+
W
∗
h
(
t
−
1
)
+
U
∗
x
(
t
)
)
h^{(t)}=tanh(b+W*h^{(t-1)}+U*x^{(t)})
h(t)=tanh(b+W∗h(t−1)+U∗x(t))
对于上面的公式,我们的样本是一个一个输入进去的对于t=1,则有:
h
(
1
)
=
t
a
n
h
(
b
+
W
∗
h
(
0
)
+
U
∗
x
(
1
)
)
h^{(1)}=tanh(b+W*h^{(0)}+U*x^{(1)})
h(1)=tanh(b+W∗h(0)+U∗x(1))
h
(
0
)
h^{(0)}
h(0)可以取全0矩阵,
h
(
1
)
=
t
a
n
h
(
b
+
U
∗
x
(
1
)
)
h^{(1)}=tanh(b+U*x^{(1)})
h(1)=tanh(b+U∗x(1))
之后不断代入
x
x
x值便可以不断迭代出后面的
h
h
h值。对于各个参数的维度,我们需要知道
x
x
x的输入维度以及我们定义所要的
h
h
h的输出维度,便可以倒推出剩余参数的维度。
总结
主要思想:将整个序列划分成多个时间步,将每一个时间步的信息依次输入模型,同时将模型输出的结果传给下一个时间步。
对于最终的输出值,大家有没有发现最终的维度只有一个样本的维度,相比线性层的一口气将所有样本代入,RNN层对数据还对数据进行了一个压缩处理,这样我们便不需要进行池化的一个操作了,而且相比池化,还保留了样本的更多信息。
手撕代码
以下是RNN的实现代码
import torch
import torch.nn as nn
import numpy as np
"""
手动实现简单的神经网络
使用pytorch实现RNN
手动实现RNN
对比
"""
class TorchRNN(nn.Module):
def __init__(self, input_size, hidden_size):
super(TorchRNN, self).__init__()
self.layer = nn.RNN(input_size, hidden_size, bias=False, batch_first=True)
def forward(self, x):
return self.layer(x)
#自定义RNN模型
class DiyModel:
def __init__(self, w_ih, w_hh, hidden_size):
self.w_ih = w_ih
self.w_hh = w_hh
self.hidden_size = hidden_size
def forward(self, x):
ht = np.zeros((self.hidden_size))
output = []
for xt in x:
ux = np.dot(self.w_ih, xt)
wh = np.dot(self.w_hh, ht)
ht_next = np.tanh(ux + wh)
output.append(ht_next)
ht = ht_next
return np.array(output), ht
x = np.array([[1, 2, 3],
[3, 4, 5],
[5, 6, 7]]) #网络输入
#torch实验
hidden_size = 4
torch_model = TorchRNN(3, hidden_size)
# print(torch_model.state_dict())
w_ih = torch_model.state_dict()["layer.weight_ih_l0"]
w_hh = torch_model.state_dict()["layer.weight_hh_l0"]
print(w_ih, w_ih.shape)
print(w_hh, w_hh.shape)
#
torch_x = torch.FloatTensor([x])
output, h = torch_model.forward(torch_x)
print(h)
print(output.detach().numpy(), "torch模型预测结果")
print(h.detach().numpy(), "torch模型预测隐含层结果")
print("---------------")
diy_model = DiyModel(w_ih, w_hh, hidden_size)
output, h = diy_model.forward(x)
print(output, "diy模型预测结果")
print(h, "diy模型预测隐含层结果")