个人笔记,不喜勿喷。
举例说明(结合pytorch,最后会给出代码)
构建的网络nn.LSTM:(28,4,num_layers=2),即图中是4层
输入lstm_input:维度是(10,3,28)
初始化隐藏状态h_init:维度是(2,3,4)
初始化初始化细胞状态c_init:维度是(2,3,4)
计算结果out:维度是(10,3,4)
计算后最后一个时间步h隐藏状态:维度是(2,3,4)
计算后最后一个时间步c细胞状态:维度是(2,3,4)
计算过程中,input计算参数维度:(16,28)
计算过程中,隐藏层计算参数维度:(16,4)
结合上图来分析:
图中绿色的方框代表LSTM中的神经元;
左边蓝色的椭圆是初始化的h和c参数,由于它们维度一致,就将它们合起来一起表示,当然,在pytorch中可以使用系统自定义的h和c参数,不必自定义。在这里,我们定义了h和c的维度均是(2,3,4),其中2代表有两层网络,3代表着时序输入(图中下边蓝色3个输入,每个输入维度28),4代表着特征维度(自定义的,即想要提取的特征数);
下边蓝色的椭圆是输入,在这里我们看到,有3个时序输入,每个时序输入是28维度。在上面的例子中,输入维度是10,3,28),其中10代表着分10次批量输入,3代表着时序输入,28代表着每个时序的输入是28维度;
右边黄色的椭圆是h和c参数的输出,输出后的参数的维度和初始化的是一致的。在上面的例子中,h和c的初始和计算后维度均为(10,3,4)。
上边黄色的椭圆是网络的输出。在上面的例子中,其维度为(10,3,4),其中10是批量数,3是时序(即每个时序都有输出),4代表每个时序的输出的维度,在这里虽然网络有两层,但是仅取最后一层作为输出
计算过程中,结合上面例子,input计算参数维度是(16,28)。16代表着啥,代表4*4,第一个4是固定的,因为LSTM中有四个类似‘门’计算(三个门和一个状态计算),后面的4代表着特征数,就是参数h和c中的4(即神经元每一列个数,因为他们一样)。28代表啥,代表着每个时序输入的特征数28。
计算过程中,结合上面例子,隐藏层计算参数维度:(16,4)。16代表啥,和input计算参数维度一样。4代表啥,特征数,就是参数h和c中的4(即神经元每一列个数,因为他们一样)。
接下来上代码:
import torch
from torch.autograd import Variable
from torch import nn
lstm_seq = nn.LSTM(28, 4, num_layers=2) # 构建LSTM网络
lstm_input = Variable(torch.randn(10, 3, 28)) # 构建输入
h_init = Variable(torch.randn(2, 3, 4)) # 构建h输入参数
c_init = Variable(torch.randn(2, 3, 4)) # 构建c输出参数
out, (h, c) = lstm_seq(lstm_input, (h_init, c_init)) # 计算
print(lstm_seq.weight_ih_l0.shape)
print(lstm_seq.weight_hh_l0.shape)
print(out.shape, h.shape, c.shape)
结果如下: