0%

常见神经网络模型量估计

对于常见的深度学习,如CNN,RNN,DNN,GRU,LSTM,如果可以在设计模型时就能设计出模型的参数量,那对于后续的性能优化、模型部署调优都会有一个直观上的感受和帮助。

1. CNN参数个数

常见CNN模型一般包含以下几种类型的层:卷积层、池化层和全连接层。假设卷积核大小为H*W, input channel为I,out channel为O。

  1. 卷积层(Convolutional Layer):

该层filter数量总数为(H x W x I),每个将被映射到新的输出通道上,加上每个filter的计算要有一个bias,所以总的参数数量为:(H x W x I + 1) x O

  1. 池化层(Pooling Layer):

一般的池化层属于固定操作,没有权重传播

2. 全连接层参数个数

前后是n,m维的输入输出,所以其参数数量为(n+1) x m

以下循环神经网络均已单层为例

3. RNN参数个数

图上W,U,V在RNN的每一步中都是共享的参数,所以其参数量为:

  • n- 隐藏层的维度
  • k- 输出层的维度
  • m- 输入层的维度

$n^2$ 就是 $W*W$部分
$kn$ 就是$WV$部分
$nm$ 就是$UW$部分

4. LSTM参数个数

LSTM一共维护四套参数,分别对应输入门、输出门、遗忘门和候选态,总参数数量:

  • n- 隐藏层的维度
  • m- 输入层的维度
  • 1 表示的是偏置项

例如:

1
2
import torch.nn as nn
rnn = nn.LSTM(input_size=100, hidden_size=512, num_layers=1)

所以参数个数为:

5. GRU参数个数

和LSTM类似,但是只有三套参数,更新门、重置门、候选态,总参数量为:

  • n- 隐藏层的维度
  • m- 输入层的维度
  • 1 表示的是偏置项
  1. 实验:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class MyModel(nn.Module):
def __init__(self):
super(MyModel, self).__init__()
self.lstm = nn.LSTM(input_size=100, hidden_size=512, num_layers=1)
# self.rnn = nn.RNN(input_size=100, hidden_size=512, num_layers=1)
# self.gru = nn.GRU(input_size=100, hidden_size=512, num_layers=1)

def forward(self, x):
return x

net = MyModel()
params = list(net.parameters())
k = 0
all_num = 0
for i in params:
l = 1
print("该层的结构:" + str(list(i.size())))
for j in i.size():
l *= j
print("该层参数和:" + str(l))
k = k + l
print("参数总和:"+str(k))

以lstm为例输出:

可以看到LSTM输出比预期的参数多了 512*4 = 2048

同样,GRU会比预期的参数多 512*3 = 1536

似乎是多一个偏置项,但是从参考连接他人用keras好像没有问题,难道是框架的问题?之后再做一下实验。。

参考:

RNN参数量

LSTM参数量

GRU参数量

pytorch参数量计算