关于torch.nn.Conv2d的笔记
先看一下CLASS有哪些参数:
torch.nn.Conv2d( in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros' )
可以对输入的张量进行 2D 卷积。
in_channels: 输入图片的 channel 数。
out_channels: 输出图片的 channel 数。
kernel_size: 卷积核的大小。
stride: 滑动的步长。
bias: 若设为 True,则对输出图像每个元素加上一个可以学习的 bias。
dilation: 核间点距。
padding: 控制补 的数目。padding 是在卷积之前补 ,如果愿意的话,可以通过使用 torch.nn.Functional.pad 来补非 的内容。padding 补 的策略是四周都补,如果 padding 输入是一个二元组的话,则第一个参数表示高度上面的 padding,第2个参数表示宽度上面的 padding。
关于 padding 策略的例子:
x = torch.tensor([[[[-1.0, 2.0], [3.5, -4.0]]]]) print(x, x.shape) # N = 1, C = 1, (H,W) = (2,2) layer1 = torch.nn.Conv2d(1, 1, kernel_size=(1, 1), padding=0) layer2 = torch.nn.Conv2d(1, 1, kernel_size=(1, 1), padding=(1, 2)) y = layer1(x) print(y, y.shape) z = layer2(x) print(z, z.shape)
结果:
tensor([[[[-1.0000, 2.0000], [ 3.5000, -4.0000]]]]) torch.Size([1, 1, 2, 2]) tensor([[[[-0.3515, 0.4479], [ 0.8476, -1.1510]]]], grad_fn=<ThnnConv2DBackward>) torch.Size([1, 1, 2, 2]) tensor([[[[-0.6553, -0.6553, -0.6553, -0.6553, -0.6553, -0.6553], [-0.6553, -0.6553, 0.2367, -2.4393, -0.6553, -0.6553], [-0.6553, -0.6553, -3.7772, 2.9127, -0.6553, -0.6553], [-0.6553, -0.6553, -0.6553, -0.6553, -0.6553, -0.6553]]]], grad_fn=<ThnnConv2DBackward>) torch.Size([1, 1, 4, 6])
可以看到 padding 为 时,在高度上两边各增加了 行,总共增加 行。在宽度上两边各增加 列,总共增加 列。至于为什么增加的行列不是 ,这是因为有参数 bias 存在的缘故,此时 bias 值为 (这个 bias 值初始值应该是一个随机数)。
关于 dilation:
默认情况下 dilation 为 ,就是正常的紧密排布的卷积核。
下图是 dilation 为 的情况(没有 padding,stride 为 ),蓝色的是输入图像,绿色的是输出图像。
输入图像的 shape 是 , 是 batch size, 表示 channel 数, 分别表示高和宽。
输出图像的 shape 可以通过计算得到:
这个式子很好理解,由于宽高的计算类似,所以只以高为例子来讲:
即输入图像补完 之后的高度,一个卷积核在图像上所能覆盖的高度为 (例如上面动图就是 ),这两个值相减即为,步长为 时,卷积核在图像高度上能滑动的次数。而这个次数除去实际步长 再向下取整,即卷积核在图像高度上实际能滑动的次数。这个实际滑动次数加上 即输出图像的高度。
需要注意的是:kernel_size, stride, padding, dilation 不但可以是一个单个的 int ——表示在高度和宽度使用同一个 int 作为参数,也可以使用一个 (int1, int2) 的二元组(其实本质上单个的 int 也可以看作一个二元组 (int, int))。在元组中,第1个参数对应高度维度,第2个参数对应宽度维度。
另外,对于卷积核,它其实并不是二维的,它具有长宽深三个维度;实际上它的 channel 数等于输入图像的 channel 数 ,而卷积核的个数即输出图像的 channel 数 。
以上图为例,输入图像的 shape 是 ,这里略去 batch size,第一个卷积核是 ,他在输入图像上滑动并卷积后得到一张 的特征图(feature map),第二个卷积核类似得到第二张 特征图,那么输出图像就是把这两张特征图叠在一块儿,shape 即为 。
这里顺带记录一下 Batch norm 2D 是怎么做的:
如果把一个 shape 为 类比为一摞书,这摞书总共有 N 本,每本均有 C 页,每页有 H 行,每行 W 个字符。BN 求均值时,相当于把这 本书都选同一个页码加起来(例如第1本书的第36页,第2本书的第36页......),再除以每本书的该页上的字符的总数 ,因此可以把 BN 看成求“平均书”的操作(注意这个“平均书”每页只有一个字),求标准差时也是同理。
例如下图,输入的张量 shape 为 ,对于所有 batch 中的同一个 channel 的元素进行求均值与方差,比如对于所有的 batch,都拿出来最后一个channel,一共有 个元素,然后去求这 个元素的均值与方差。
求取完了均值与方差之后,对于这 个元素中的每个元素分别进行归一化,然后乘以 加上 ,公式如下
batch norm层能够学习到的参数,对于一个特定的 channel 而言实际上是两个参数 ,而对于所有的channel而言实际上就是 channel 数的两倍。
关于其他的 Normalization 做法的形象理解可以参考https://zhuanlan.zhihu.com/p/69659844
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
2019-02-24 CCPC-Wannafly Winter Camp Day1 Div1 - 爬爬爬山 - [最短路][堆优化dijkstra]
2019-02-24 CCPC-Wannafly Winter Camp Day1 Div1 - 夺宝奇兵 - [贪心+线段树]