缘由
自己在学校上课学的CNN算法都忘了差不多了,自己在官网弄了一个图片分类的算法准备优化精度居然完全看不懂!这就蛋疼了,弄了一下午终于明白各个参数之间的含义以及如何计算参数的值了!
参数及如何计算
self.conv1 = nn.Conv2d(1, 6, 5) # 定义conv1函数的是图像卷积函数:输入为图像(1个频道,即灰度图),输出为 6张特征图, 卷积核为5x5正方形
self.conv2 = nn.Conv2d(6, 16, 5)# 定义conv2函数的是图像卷积函数:输入为6张特征图,输出为16张特征图, 卷积核为5x5正方形
self.fc1 = nn.Linear(16*5*5, 120) # 定义fc1(fullconnect)全连接函数1为线性函数:y = Wx + b,并将16*5*5个节点连接到120个节点上。
self.fc2 = nn.Linear(120, 84)#定义fc2(fullconnect)全连接函数2为线性函数:y = Wx + b,并将120个节点连接到84个节点上。
self.fc3 = nn.Linear(84, 10)#定义fc3(fullconnect)全连接函数3为线性函数:y = Wx + b,并将84个节点连接到10个节点上。
参数计算
- 不考虑padding
N:输入width/height, F: 卷积核大小/filter_size, stride:步长
-
考虑padding
N:输入width/height, F: 卷积核大小/filter_size, stride:步长, Pad: paddings大小
示例
以下
- 第一次卷积:
{3x32x32 | 3X3(卷积核)} => {1000(任意值)x30x30}
30 = {(32-3)/1}+1
- 池化:
1000x30x30 => 1000x15x15
15 = 30/2
- 第二次卷积:
{1000x15x15 | 4X4(卷积核)} => {100(任意值)x12x12}
12 = {(15-4)/1}+1
- 第二次池化:
100x12x12 => 100x6x6
6 = 12/2
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(3, 1000, 3) #输入信号通道3(RGB三通道,即一个彩色图片对于的RGB三个图),卷积核(Kernel,卷积核,有时也称为filter)尺寸:3,卷积产生100个特征图(该数字为自己填写的,可大可小,但超出图片像素综合则感觉毫无意义)
self.pool = nn.MaxPool2d(2, 2)#处理后的特征图片是30×30的,我们对其进行下采样,采样窗口为15X15,最终将其下采样成为一个2×2大小的特征图。
self.conv2 = nn.Conv2d(1000, 5, 4)#输入信号通道100(RGB三通道),卷积核(Kernel,卷积核,有时也称为filter)尺寸:3,卷积产生100个特征图(该数字为自己填写的,可大可小,但超出图片像素综合则感觉毫无意义)
#三个全连接池
self.fc1 = nn.Linear(5*6*6, 360)#处理后的特征图片是12×12的,我们对其进行下采样,采样窗口为6X6,最终将其下采样成为一个2×2大小的特征图。
self.fc2 = nn.Linear(360, 250)
self.fc20 = nn.Linear(250, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = x.view(-1, 5*6*6)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = F.relu(self.fc20(x))
x = self.fc3(x)
return x