- 传统RNN的内部结构图:

- 结构解释图:

- 内部结构分析: * 我们把目光集中在中间的方块部分, 它的输入有两部分, 分别是h(t-1)以及x(t), 代表上一时间步的隐层输出, 以及此时间步的输入, 它们进入RNN结构体后, 会”融合”到一起, 这种融合我们根据结构解释可知, 是将二者进行拼接, 形成新的张量[x(t), h(t-1)], 之后这个新的张量将通过一个全连接层(线性层), 该层>使用tanh作为激活函数, 最终得到该时间步的输出h(t), 它将作为下一个时间步的>输入和x(t+1)一起进入结构体. 以此类推.
- 内部结构过程演示:

- 根据结构分析得出内部计算公式:

- 激活函数tanh的作用: * 用于帮助调节流经网络的值, tanh函数将值压缩在-1和1之间.

- 构建RNN模型的代码分析:
class RNN(nn.Module):def __init__(self, input_size, hidden_size, output_size):"""初始化函数中有三个参数,分别是输入张量最后一维的尺寸大小,隐层张量最后一维的尺寸大小, 输出张量最后一维的尺寸大小"""super(RNN, self).__init__()# 传入隐含层尺寸大小self.hidden_size = hidden_size# 构建从输入到隐含层的线性变化, 这个线性层的输入尺寸是input_size + hidden_size# 这是因为在循环网络中, 每次输入都有两部分组成,分别是此时刻的输入和上一时刻产生的输出.# 这个线性层的输出尺寸是hidden_sizeself.i2h = nn.Linear(input_size + hidden_size, hidden_size)# 构建从输入到输出层的线性变化, 这个线性层的输入尺寸还是input_size + hidden_size# 这个线性层的输出尺寸是output_size.self.i2o = nn.Linear(input_size + hidden_size, output_size)# 最后需要对输出做softmax处理, 获得结果.self.softmax = nn.LogSoftmax(dim=-1)def forward(self, input, hidden):"""在forward函数中, 参数分别是规定尺寸的输入张量, 以及规定尺寸的初始化隐层张量"""# 首先使用torch.cat将input与hidden进行张量拼接combined = torch.cat((input, hidden), 1)# 通过输入层到隐层变换获得hidden张量hidden = self.i2h(combined)# 通过输入到输出层变换获得output张量output = self.i2o(combined)# 对输出进行softmax处理output = self.softmax(output)# 返回输出张量和最后的隐层结果return output, hiddendef initHidden(self):"""隐层初始化函数"""# 将隐层初始化成为一个1xhidden_size的全0张量return torch.zeros(1, self.hidden_size)
- torch.cat演示:
>>> x = torch.randn(2, 3)>>> xtensor([[ 0.6580, -1.0969, -0.4614],[-0.1034, -0.5790, 0.1497]])>>> torch.cat((x, x, x), 0)tensor([[ 0.6580, -1.0969, -0.4614],[-0.1034, -0.5790, 0.1497],[ 0.6580, -1.0969, -0.4614],[-0.1034, -0.5790, 0.1497],[ 0.6580, -1.0969, -0.4614],[-0.1034, -0.5790, 0.1497]])>>> torch.cat((x, x, x), 1)ensor([[ 0.6580, -1.0969, -0.4614, 0.6580, -1.0969, -0.4614, 0.6580,-1.0969, -0.4614],[-0.1034, -0.5790, 0.1497, -0.1034, -0.5790, 0.1497, -0.1034,-0.5790, 0.1497]])
- 代码位置: /data/doctor_offline/review_model/RNN_MODEL.py
- 实例化参数:
input_size = 768 hidden_size = 128 n_categories = 2
- 输入参数:
input = torch.rand(1, input_size) hidden = torch.rand(1, hidden_size)
调用:
from RNN_MODEL import RNN rnn = RNN(input_size, hidden_size, n_categories) outputs, hidden = rnn(input, hidden) print("outputs:", outputs) print("hidden:", hidden)输出效果:
outputs: tensor([[-0.7858, -0.6084]], grad_fn=<LogSoftmaxBackward>) hidden: tensor([[-4.8444e-01, -5.9609e-02, 1.7870e-01, -1.6553e-01, ... , 5.6711e-01]], grad_fn=<AddmmBackward>))
- 小节总结:
- 学习了RNN模型的内部结构及计算公式.
- 学习并实现了RNN模型的类: class RNN(nn.Module).
