深度学习----------------卷积层里的填充和步幅

填充

在这里插入图片描述
其中:
在这里插入图片描述
第一层的输出:32-5+1=28
第二层的输出:28-5+1=24
第三层的输出:24-5+1=20
第四层的输出:20-5+1=16
第五层的输出:16-5+1=12
第六层的输出:12-5+1=8
第七层的输出:18-5+1=4

下面给出一部分步骤:

请添加图片描述
请添加图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述




存在的问题:
    假设不想让输入变的那么小(例如:刚刚是32×32的),特别是想用比较大的卷积核的时候。就会觉得图片的大小不是很大。可能就会用个3、4层,就无法再用了。(例如:上面只能用到第7层4×4就不能继续用了)。

如果做更深的神经网络怎么办?
使用填充。在输入周围添加额外的行和列。




例如:原始的输入

在这里插入图片描述

填充之后
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述




步幅

填充减少的输出大小与层数线性相关
    给定输入大小224×224,在使用5×5卷积核的情况下,需要55层(即:(224-4)/4=55)将输出降低到4×4.
    需要大量计算才能得到较小输出。(步幅就是解决这个问题)

在这里插入图片描述

步幅是指行/列的滑动步幅
(之前的步幅是1)
现在进行一下步幅的调整,例如:高度3宽度2的步幅

在这里插入图片描述
如果不做步幅处理,它的输出将会是4×4,而现在是2×2.

给定高度 s h s_h sh和宽度 s w s_w sw的步幅,输出形状是:

在这里插入图片描述

这里例子:
           n h n_h nh=3
           n w n_w nw=3
           k h k_h kh=2
           k w k_w kw=2
           p h p_h ph=2 (填充行数)
           p w p_w pw=2 (填充列数)
           s h s_h sh=3
           s w s_w sw=2



如果 p h p_h ph = k h k_h kh - 1, p w p_w pw = k w k_w kw - 1
在这里插入图片描述


如果输入高度和宽度可以被步幅整除
在这里插入图片描述




总结

    ①填充和步幅是卷积层的超参数。

    ②填充在输入周围添加额外的行/列,来控制输出形状的减少量。

    ③步幅是每次滑动核窗口时的行/列的步长,可以成倍的减少输出形状。




代码实现

在所有侧边填充1个像素

import torch
from torch import nn


# 为了方便起见,我们定义了一个计算卷积层的函数。
# 此函数初始化卷积层权重,并对输入和输出提高和缩减相应的维数
def comp_conv2d(conv2d, X):
    # 这里的(1,1)表示批量大小和通道数都是1
    X = X.reshape((1, 1) + X.shape)
    Y = conv2d(X)
    # 省略前两个维度:批量大小和通道,只保留空间维度
    return Y.reshape(Y.shape[2:])


# 请注意,这里每边都填充了1行或1列,因此总共添加了2行或2列
# 在输入数据的每一边都填充了 1 个单位的零,被扩展为 10x10
conv2d = nn.Conv2d(1, 1, kernel_size=3, padding=1)
X = torch.rand(size=(8, 8))
# 输出数据的空间维度保持不变,因为 (10 - 3) / 1 + 1 = 8
print(comp_conv2d(conv2d, X).shape)

输出:

在这里插入图片描述



填充不同的高度和宽度

conv2d = nn.Conv2d(1, 1, kernel_size=(5, 3), padding=(2, 1))
comp_conv2d(conv2d, X).shape

输出:
在这里插入图片描述

该部分总代码

import torch
from torch import nn


# 为了方便起见,我们定义了一个计算卷积层的函数。
# 此函数初始化卷积层权重,并对输入和输出提高和缩减相应的维数
def comp_conv2d(conv2d, X):
    # 这里的(1,1)表示批量大小和通道数都是1
    X = X.reshape((1, 1) + X.shape)
    Y = conv2d(X)
    # 省略前两个维度:批量大小和通道,只保留空间维度
    return Y.reshape(Y.shape[2:])


X = torch.rand(size=(8, 8))
# 行数是5行,列数是三列。上下填充行数为2,左右填充为1
conv2d = nn.Conv2d(1, 1, kernel_size=(5, 3), padding=(2, 1))
print(comp_conv2d(conv2d, X).shape)



将宽度和高度的步幅设置为2

conv2d = nn.Conv2d(1, 1, kernel_size=3, padding=1, stride=2)
comp_conv2d(conv2d, X).shape

输出:
在这里插入图片描述


一个稍微复杂的例子

conv2d = nn.Conv2d(1, 1, kernel_size=(3, 5), padding=(0, 1), stride=(3, 4))
comp_conv2d(conv2d, X).shape

输出:
在这里插入图片描述




问题

①为什么卷积核的边长一般选奇数?
方便对称填充,

  • 17
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值