1、CNN中常见的名词
- padding:padding(填充)参数的作用是决定在进行卷积或池化操作时,是否对输入的图像矩阵边缘补0
- stride:滑动卷积核时的步长stride(例如每次滑动一个或两个)
- kernal:卷积核,通常为3x3或者5x5
- filter:卷积核的数量(神经元的数量)。这个地方怎么理解呢,一个3x3的卷积核有9个参数,这些参数是通过learning出来的,一个卷积核扫过一幅图后,会生成一幅新的图,因为卷积核的参数是不同的,因此生成的图片也是不同的。但是卷积核的作用是侦查patten的对吧,一个图片中不可能只有一个patten吧,比如说一幅图片有100个patten,鸟嘴、鸟爪、牛蹄、猪头等特征都是patten,当将一头猪的图片输入到网络中,猪头这个patten的权重就会非常大,相反鸟嘴、鸟爪、牛蹄的patten权重就很低。所以filter的个数也就代表了神经元的数目。
- pooling:池化
2、整体流程理解
卷积(Conv2d) -> BN(batch normalization) -> 激励函数(ReLU) -> 池化(MaxPooling) ->
全连接层(Linear) -> 输出
1 # 定义网络结构 2 class CNNnet(torch.nn.Module): 3 def __init__(self): 4 super(CNNnet,self).__init__() 5 self.conv1 = torch.nn.Sequential( 6 torch.nn.Conv2d(in_channels=1, 7 out_channels=16, 8 kernel_size=3, 9 stride=2, 10 padding=1), 11 torch.nn.BatchNorm2d(16), 12 torch.nn.ReLU() 13 ) 14 self.conv2 = torch.nn.Sequential( 15 torch.nn.Conv2d(16,32,3,2,1), 16 torch.nn.BatchNorm2d(32), 17 torch.nn.ReLU() 18 ) 19 self.conv3 = torch.nn.Sequential( 20 torch.nn.Conv2d(32,64,3,2,1), 21 torch.nn.BatchNorm2d(64), 22 torch.nn.ReLU() 23 ) 24 self.conv4 = torch.nn.Sequential( 25 torch.nn.Conv2d(64,64,2,2,0), 26 torch.nn.BatchNorm2d(64), 27 torch.nn.ReLU() 28 ) 29 self.linear = torch.nn.Linear(2*2*64,100) 30 self.linear = torch.nn.Linear(100,10) 31 def forward(self, x): 32 x = self.conv1(x) 33 x = self.conv2(x) 34 x = self.conv3(x) 35 x = self.conv4(x) 36 x = self.linear(x.view(x.size(0),-1)) 37 x = self.linear(x) 38 return x 39 model = CNNnet() 40 print(model)
首先图片经过卷积层。卷积层第一个参数是input channel ,如果是RGB图像,就是3维,如果是灰度图就是1维。
第二个参数是output channel,也就是filter,设置多少个卷积核,每个卷积核做运算后输出新的“图片”,后续的参数再是卷积核的大小、步长、填充等等。
重点要理解这个output channel
那么问题来了,怎么判断做完卷积后新图片的大小?假设输入的tensor size为C H W,若in_channels=C,out_channels=Cout,kernel_size=k,stride=s,padding=p,那么输出的tensor size是:
Cout*((H + 2*p - k)/s+1) * ((W + 2*p - k)/s+1)
这种方法需要手动计算,有时候还可能计算错误,
这里再提供一种方法,执行完下述程序后,加上一句 print(x.size())
将数据打印出来,
然后再填到torch.nn.Linear(input,100)里
1 def forward(self, x): 2 x = self.conv1(x) 3 x = self.conv2(x) 4 x = self.conv3(x) 5 x = self.conv4(x) 6 print(x.size())
3、关于Pytorch默认的参数初始化问题
用自己的话总结一下:Pytorch中默认会初始化参数,这个初始化在调用神经网络时已经给初始好了,不需要自己手动初始化。系统默认初始化参数时也是用random
的相关函数,这也是为什么我们需要设置seed了,因为设置seed后,每次初始化的参数值是一模一样的。
此外,也可以手动初始化参数。自动初始化参数是可以满足大多数情况的,但是针对有些特定的RNN、CNN的网络,有更适合收敛的参数,因此可以默认,但也可以手动初始化参数。
random.seed() | random模块的随机数种子 |
torch.manual_seed() | 为CPU设置随机数种子 |
torch.cuda.manual_seed() | 为GPU设置随机数种子 |
torch.cuda.manual_seed_all() |
为所有的GPU设置随机数种子 |
4、transforms.ToTensor()
这个函数的用法?
ToTensor()
将shape
为(H, W, C)
的nump.ndarray
或img
转为shape
为(C, H, W)
的tensor
,
其将每一个数值归一化到[0,1]
,其归一化方法比较简单,直接除以255即可。
总结一下:① 、起到了一个reshape的作用 ;②、起到归一化的作用。
其实不难理解为什么起到这两点作用,因为PIL的读取的图片格式本来就是(H, W, C),所以肯定要进行一步转换;
且transforms这个库就是针对图像的,而将图像像素的归一化是最基础的操作之一,所以totensor都替我们做好了。
标签:初始化,nn,卷积,self,torch,神经网络,理解,参数 From: https://www.cnblogs.com/Zhouce/p/17999750