本文参考资料
卷积神经网络
随着CV的发展,卷积神经网络有越来越多的应用,但是在写代码的时候,size、channel匹配常常是我们关心的问题。
图片大小计算公式
卷积示意图:
- 两个Filter(卷积核),输出两个矩阵,深度也就是2
- 初始图片+pad1是周围加了1圈0,从5x5x3(3代表RGB三个颜色)变为7x7x3,但笔者下文给出的计算公式是根据原图片大小给出的,因Pytorch默认pad层为1,若考虑容易导致重复。
- 因为图片有三个颜色通道,深度是3,因此filter的深度也是3,再加上大小为3x3,故filter矩阵是3x3x3矩阵
- 图片中最右侧的绿色框为输出,相当于对三个颜色通道进行了加权平均
- 输出矩阵的大小计算为(5(原图)+1(pad层)-3(卷积核大小))=3(输出大小),因此输出3x3矩阵,加上两个filter,为3x3x3
看不太懂?下面还有例子。
Conv2d代码详解
笔者将使用Pytorch的Conv2d搭建一个简单的卷积神经网络例子,并将卷积核大小设置为5x5。
Conv2d参数:
下面是使用28*28的MNIST数据集的模型初始化,备注里包含了卷积核的大小、模型传递方式。
conv net的结构设计比较复杂,一般是:
input->[ [conv->RELU]*N -> POOL ]*M(重复M次) ->(前面拿到的是图片的表述) - > [ FC-RELU] *K(重复K次) ->FC(得到输出)
代码示例(重复两次卷积,两次relu):
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms#torchversion提供了一些常用的数据集,transform是改变这些数据集的方法
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(1, 20, 5, 1) # 1,20表示1个channel到20个channel 因为kneral sieze是5,从28 * 28 -> (28+1-5) =24 * 24
self.conv2 = nn.Conv2d(20, 50, 5, 1) # 又来一个kneral size是5的,(24+1-5)=20 * 20
self.fc1 = nn.Linear(4*4*50, 500)#reshape成全连接层,中间维度500维
self.fc2 = nn.Linear(500, 10)#10因为是10分类问题,从500变回10
def forward(self, x):
# x: 1 * 28 * 28,1表示channel,因为黑白图片
x = F.relu(self.conv1(x)) # 20 * 24 * 24
x = F.max_pool2d(x,2,2) # 12 * 12#因为pool
x = F.relu(self.conv2(x)) # 8 * 8#因为pool
x = F.max_pool2d(x,2,2) # 4 *4
x = x.view(-1, 4*4*50) # reshape (5 * 2 * 10), view(5, 20) -> (5 * 20)
x = F.relu(self.fc1(x))
x= self.fc2(x)
# return x
return F.log_softmax(x, dim=1) # log probability计算归类的可能性
练习
下面是LeNet的示意图。
已知初始图片大小32x32,经过一层卷积后成为28x28,深度为6的网络,请问卷积核大小是多少?
答:因(32+1-5)=28,故模型第一次卷积使用的是加一次pad,卷积核为5,同时使用6个卷积核的卷积操作。
来源:CSDN
作者:Haorui.L
链接:https://blog.csdn.net/weixin_46233323/article/details/104588639