首先贴出一张经典的textrnn的流程图
对应的textrnn的结构如下:
~~~python
import torch
import torch.nn as nn
rnn = nn.RNN(10,20,2)
#10为输入x的特征大小,20为隐藏层h的特征大小
#2为循环层的数量(RNN中重复的部分)
#input_size = 10,hidden_size = 20,num_layers = 2
input = torch.randn(5,3,10)
h0 = torch.randn(2,3,20)
#h0不初始化则全部为0
output,hn = rnn(input,h0)
print('output.shape = ***')
print(output.shape)
print('hn = ***')
print(hn.shape)
来观察这个简单的函数,首先rnn = nn.RNN(10,20,2)
其中input_size = 10,hidden_size = 20,num_layers = 2
input = (5,3,10),h0 = (2,3,20),经历了rnn层之后,
输出的output = (5,3,20),输出的hn = (2,3,20)
这里面的textrnn是运用了rnn相应的计算公式,对应的公式为
[
b
a
t
c
h
_
s
i
z
e
,
i
n
p
u
t
_
d
i
m
]
∗
[
i
n
p
u
t
_
d
i
m
,
n
u
m
_
h
i
d
d
e
n
s
]
+
[
b
a
t
c
h
_
s
i
z
e
,
n
u
m
_
h
i
d
d
e
n
s
]
∗
[
n
u
m
_
h
i
d
d
e
n
s
,
n
u
m
_
h
i
d
d
e
n
s
]
+
b
i
a
s
[batch\_size,input\_dim]*[input\_dim,num\_hiddens]+[batch\_size,num\_hiddens]*[num\_hiddens,num\_hiddens]+bias
[batch_size,input_dim]∗[input_dim,num_hiddens]+[batch_size,num_hiddens]∗[num_hiddens,num_hiddens]+bias
这里面的batch_size = 3(batch_size为input倒数第二个维度的对应的值),hidden_size = 20,
所以对应的维度相乘为
(
3
,
10
)
∗
(
10
,
20
)
+
(
3
,
20
)
∗
(
20
,
20
)
+
b
i
a
s
(3,10)*(10,20)+(3,20)*(20,20)+bias
(3,10)∗(10,20)+(3,20)∗(20,20)+bias
这里面的第二个(3,20)维度的矩阵为上一层计算的
(
3
,
10
)
∗
(
10
,
20
)
+
(
3
,
20
)
∗
(
20
,
20
)
+
b
i
a
s
(3,10)*(10,20)+(3,20)*(20,20)+bias
(3,10)∗(10,20)+(3,20)∗(20,20)+bias的结果
第一次输入的初始化矩阵h0 = (2,3,20)中的(3,20)用于第一次计算的时候放入(3,20)的初始化矩阵
关于输入的input的维度与h0对应的维度的参数统一问题
input_size = (5,3,10),h0 = (2,3,20),nn.RNN=(10,20,2)
1.首先input_size的最后一个维度为10,这里需要与RNN相应的第一个维度对应上,然后h0的最后一个维度为20,这里需要与RNN相应的第二个维度对应上,
2.然后再看input_size对应的第二个维度,这一维度代表batch_size,这里面的input_size的第二个维度需要与h0的第二个维度相等,保持batch_size的一致性,
3.最后再看h0的第一个维度2,这一个维度需要与RNN的最后一个参数即隐藏层的层数对应起来,因为如果隐藏层为2层的时候,就需要2个(3,20)的对应的权重矩阵。
这里面的hidden_size即num_hidden为隐藏层神经元的个数(即对应的20数值),注意隐藏层神经元的个数不一定要与对应的类别相同,比如可以在输出的神经元之后再添加一个对应的线性层,经过线性层之后得到最终的网络层的个数。num_layers为中间隐藏层网络的层数,这里面隐藏层网络的神经元个数为2。
rnn的具体公式如下:
正好对应rnn的具体的公式(当rnn上一层的状态影响下一层的状态时,对应的公式如下:
nn.rnn相当于在其中加入了一定的偏差biase)