如何计算卷积神经网络每一层的参数数量和特征图大小?
如何计算卷积神经网络每一层的参数数量和特征图大小?
在学习卷积神经网络的过程中,对每一层的参数数量和特征图的计算,一直有些疑惑。主要是必须区分一下模型中每一层的参数和特征图大小是两个概念。
下面通过一个具体的例子来进行解释。
import torch
import torch.nn as nn
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)
self.act1 = nn.Tanh()
self.pool1 = nn.MaxPool2d(2)
self.conv2 = nn.Conv2d(16, 8, kernel_size=3, padding=1)
self.act2 = nn.Tanh()
self.pool2 = nn.MaxPool2d(2)
self.fc1 = nn.Linear(8 * 8 * 8, 32)
self.act3 = nn.Tanh()
self.fc2 = nn.Linear(32, 2)
def forward(self, x):
x = self.pool1(self.act1(self.conv1(x)))
x = self.pool2(self.act2(self.conv2(x)))
x = x.view(-1, 8 * 8 * 8)
x = self.act3(self.fc1(x))
x = self.fc2(x)
return x
下面我们将详细分析代码中每一层的参数数量和特征图大小。假设输入图像的尺寸为 [3, 32, 32]
(即通道数为 3,高度和宽度均为 32)。
各层分析
1. 第一层卷积层 conv1
self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)
- 参数数量计算:
对于卷积层nn.Conv2d(in_channels, out_channels, kernel_size, padding)
,参数数量的计算公式为(kernel_size * kernel_size * in_channels + 1) * out_channels
。这里in_channels = 3
,out_channels = 16
,kernel_size = 3
。
所以参数数量为(3 * 3 * 3 + 1) * 16 = (27 + 1) * 16 = 28 * 16 = 448
。 - 特征图大小计算:
2. 第一层激活函数层 act1
self.act1 = nn.Tanh()
- 参数数量:激活函数层没有可学习的参数,所以参数数量为 0。
- 特征图大小:激活函数不改变特征图的尺寸,因此特征图大小仍为
[16, 32, 32]
。
3. 第一层池化层 pool1
self.pool1 = nn.MaxPool2d(2)
- 参数数量:池化层没有可学习的参数,参数数量为 0。
- 特征图大小计算:
4. 第二层卷积层 conv2
self.conv2 = nn.Conv2d(16, 8, kernel_size=3, padding=1)
- 参数数量计算:
依据卷积层参数计算公式,这里in_channels = 16
,out_channels = 8
,kernel_size = 3
。
所以参数数量为(3 * 3 * 16 + 1) * 8 = (144 + 1) * 8 = 145 * 8 = 1160
。 - 特征图大小计算:
5. 第二层激活函数层 act2
self.act2 = nn.Tanh()
- 参数数量:0。
- 特征图大小:
[8, 16, 16]
。
6. 第二层池化层 pool2
self.pool2 = nn.MaxPool2d(2)
- 参数数量:0。
- 特征图大小计算:
7. 第一层全连接层 fc1
self.fc1 = nn.Linear(8 * 8 * 8, 32)
- 参数数量计算:
对于全连接层nn.Linear(in_features, out_features)
,参数数量的计算公式为(in_features + 1) * out_features
。这里in_features = 8 * 8 * 8 = 512
,out_features = 32
。
所以参数数量为(512 + 1) * 32 = 513 * 32 = 16416
。 - 特征图大小:全连接层将输入展平为一维向量,这里输入是
8 * 8 * 8
个元素的一维向量,输出是 32 个元素的一维向量,可认为特征图大小变为[32]
。
8. 第三层激活函数层 act3
self.act3 = nn.Tanh()
- 参数数量:0。
- 特征图大小:
[32]
。
9. 第二层全连接层 fc2
self.fc2 = nn.Linear(32, 2)
- 参数数量计算:
依据全连接层参数计算公式,in_features = 32
,out_features = 2
。
所以参数数量为(32 + 1) * 2 = 33 * 2 = 66
。 - 特征图大小:输出是 2 个元素的一维向量,特征图大小为
[2]
。
总结
层名 | 参数数量 | 特征图大小(输入/输出) |
---|---|---|
conv1 | 448 | [3, 32, 32] -> [16, 32, 32] |
act1 | 0 | [16, 32, 32] -> [16, 32, 32] |
pool1 | 0 | [16, 32, 32] -> [16, 16, 16] |
conv2 | 1160 | [16, 16, 16] -> [8, 16, 16] |
act2 | 0 | [8, 16, 16] -> [8, 16, 16] |
pool2 | 0 | [8, 16, 16] -> [8, 8, 8] |
fc1 | 16416 | [8 * 8 * 8] -> [32] |
act3 | 0 | [32] -> [32] |
fc2 | 66 | [32] -> [2] |