1. 输入矩阵x格式:四个维度,依次为:样本数、图像高度、图像宽度、图像通道数
- 输入 x:[batch, height, width, in_channel] 四个维度
- 权重 w:[height, width, in_channel, out_channel]
- 输出 y:[batch, height, width, out_channel]
如图所示:
Input:batch=1, height=8, width=8, in_channel=3 (四维矩阵)
Kernels:卷积核大小 3x3 (决定输出层特征尺寸) 卷积核通道数:3 (RGB) 卷积核个数:5 决定输出通道数
Feature Maps: 特征尺寸 6x6 in_channel: 5(由卷积核的输出通道数所决定) out_channel
Feature Vector:输出
卷积核的输入通道数(in depth)由输入矩阵的通道数所决定。
输出矩阵的通道数(out depth)由卷积核输出通道数所决定。
卷积核心数:输入通道数x输出通道数(几组卷积核)
输出尺寸计算公式:
2. 卷积计算举例
2.1 标准卷积
以 AlexNet 模型的第一个卷积层为例,
- 输入图片的尺寸统一为 227 x 227 x 3 (高度 x 宽度 x 颜色通道数),
- 本层一共具有96个卷积核,
- 每个卷积核的尺寸都是 11 x 11 x 3。
- 已知 stride = 4, padding = 0,
- 假设 batch_size = 256,
- 则输出矩阵的高度/宽度为 (227 - 11) / 4 + 1 = 55
2.2 1 x 1 卷积计算举例
后期 GoogLeNet、ResNet 等经典模型中普遍使用一个像素大小的卷积核作为降低参数复杂度的手段。
从下面的运算可以看到,其实 1 x 1 卷积没有什么神秘的,其作用就是将输入矩阵的通道数量缩减后输出(512 降为 32),并保持它在宽度和高度维度上的尺寸(227 x 227)。
2.3 全连接层计算举例
实际上,全连接层也可以被视为是一种极端情况的卷积层,其卷积核尺寸就是输入矩阵尺寸,因此输出矩阵的高度和宽度尺寸都是1。
总结下来,虽然输入的每一张图像本身具有三个维度,但是对于卷积核来讲依然只是一个一维向量。卷积核做的,其实就是与感受野范围内的像素点进行点积(而不是矩阵乘法)。 (卷积核大小决定输出大小,卷积核个数决定输出矩阵通道数。
3. 卷积过程示意图(注意偏执大小)
输入尺寸7x7,通道数3,2个卷积核w0和w1,大小都是3x3, 所以卷积核函数形式为3x3x3x2
4. pytorch查看通道数 维数 尺寸大小方式
查看tensor
x.shape # 尺寸
x.size() # 形状
x.ndim # 维数
pytorch中与维度/变换相关的几个函数
torch.size ():可用来查看变换后的矩阵的维度
>>>import torch
>>>a = torch.Tensor([[[1, 2, 3], [4, 5, 6]]])
>>>a.size()
torch.Size([1, 2, 3])
torch.view():把原本的tensor尺寸,转变为你想要的尺寸
#可以设其中一个尺寸为-1,表示机器内部自己计算,但同时只能有一个为-1,用法如下:
>>> b=a.view(-1, 3, 2)
>>> b
tensor([[[1., 2.],
[3., 4.],
[5., 6.]]])
>>> b.size()
torch.Size([1, 3, 2])
torch.squeeze() / torch.unsqueeze()
torch.squeeze(n)函数表示压缩tensor中第n维为1的维数,比如下面第一个,b.squeeze(2).size(),原始的b为上面的torch.Size([1, 3, 2]),第二维是2≠1,所以不压缩,尺寸保持不变;而若b.squeeze(0).size(),则发现第一维为1,因此压缩为3x2的tensor。
>>> b.squeeze(2).size()
torch.Size([1, 3, 2])
>>> b.squeeze(0).size()
torch.Size([3, 2])
相反的,torch.unsqueeze(n)则是在第n维增加一个维数=1,如下,表示在原始的b的第二维增加一维,则尺寸变为1 * 3 * 1 * 2
>>> b.unsqueeze(2).size()
torch.Size([1, 3, 1, 2])
>>> b.unsqueeze(2)
tensor([[[[1., 2.]],
[[3., 4.]],
[[5., 6.]]]])
torch.permute()
这个函数表示,将原始的tensor,按照自己期望的位置重新排序,例如原始tensor的第0、1、2维分别是1、3、2,那么当我执行permute(2, 0, 1),则将第三维放在最前,第一维放在中间,第二维放在最后,也就变成了2 * 1 * 3,注意这里表示的维数的index,而不是具体几维:
>>> b.permute(2, 0, 1).size()
torch.Size([2, 1, 3])
>>> b.permute(2, 0, 1)
tensor([[[1., 3., 5.]],
[[2., 4., 6.]]])
参考:
https://zhuanlan.zhihu.com/p/29119239
https://segmentfault.com/q/1010000016667038
https://www.jb51.net/article/187394.htm