关于torch.nn.Conv2d的笔记

关于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: 控制补 00 的数目。padding 是在卷积之前补 00,如果愿意的话,可以通过使用 torch.nn.Functional.pad 来补非 00 的内容。padding 补 00 的策略是四周都补,如果 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 为 (1,2)(1,2) 时,在高度上两边各增加了 11 行,总共增加 22 行。在宽度上两边各增加 22 列,总共增加 44 列。至于为什么增加的行列不是 00,这是因为有参数 bias 存在的缘故,此时 bias 值为 −0.6553−0.6553(这个 bias 值初始值应该是一个随机数)。

 

关于 dilation:

默认情况下 dilation 为 (1,1)(1,1),就是正常的紧密排布的卷积核。

下图是 dilation 为 (2,2)(2,2) 的情况(没有 padding,stride 为 (1,1)(1,1)),蓝色的是输入图像,绿色的是输出图像。

 

 

输入图像的 shape 是 (N,Cin,Hin,Win)(N,Cin,Hin,Win),NN 是 batch size,CinCin 表示 channel 数,H,WH,W 分别表示高和宽。

输出图像的 shape (N,Cout,Hout,Wout)(N,Cout,Hout,Wout) 可以通过计算得到:

这个式子很好理解,由于宽高的计算类似,所以只以高为例子来讲:

Hin+2×padding[0]Hin+2×padding[0] 即输入图像补完 00 之后的高度,一个卷积核在图像上所能覆盖的高度为 (kernel_size[0]−1)×dilation[0]+1(kernel_size[0]−1)×dilation[0]+1(例如上面动图就是 (3−1)×2+1=5(3−1)×2+1=5),这两个值相减即为,步长为 11 时,卷积核在图像高度上能滑动的次数。而这个次数除去实际步长 stride[0]stride[0] 再向下取整,即卷积核在图像高度上实际能滑动的次数。这个实际滑动次数加上 11 即输出图像的高度。

 

需要注意的是:kernel_size, stride, padding, dilation 不但可以是一个单个的 int ——表示在高度和宽度使用同一个 int 作为参数,也可以使用一个 (int1, int2) 的二元组(其实本质上单个的 int 也可以看作一个二元组 (int, int))。在元组中,第1个参数对应高度维度,第2个参数对应宽度维度。

 

另外,对于卷积核,它其实并不是二维的,它具有长宽深三个维度;实际上它的 channel 数等于输入图像的 channel 数 CinCin,而卷积核的个数即输出图像的 channel 数 CoutCout。

以上图为例,输入图像的 shape 是 (C=3,H=6,W=6)(C=3,H=6,W=6),这里略去 batch size,第一个卷积核是 (C=3,H=3,W=3)(C=3,H=3,W=3),他在输入图像上滑动并卷积后得到一张 (C=1,H=4,W=4)(C=1,H=4,W=4) 的特征图(feature map),第二个卷积核类似得到第二张 (C=1,H=4,W=4)(C=1,H=4,W=4) 特征图,那么输出图像就是把这两张特征图叠在一块儿,shape 即为 (C=2,H=4,W=4)(C=2,H=4,W=4)。

 

 


 

这里顺带记录一下 Batch norm 2D 是怎么做的:

如果把一个 shape 为 (N,C,H,W)(N,C,H,W) 类比为一摞书,这摞书总共有 N 本,每本均有 C 页,每页有 H 行,每行 W 个字符。BN 求均值时,相当于把这 NN 本书都选同一个页码加起来(例如第1本书的第36页,第2本书的第36页......),再除以每本书的该页上的字符的总数 N×H×WN×H×W,因此可以把 BN 看成求“平均书”的操作(注意这个“平均书”每页只有一个字),求标准差时也是同理。

例如下图,输入的张量 shape 为 (4,3,2,2)(4,3,2,2),对于所有 batch 中的同一个 channel 的元素进行求均值与方差,比如对于所有的 batch,都拿出来最后一个channel,一共有 f1+f2+f3+f4=4+4+4+4=16f1+f2+f3+f4=4+4+4+4=16 个元素,然后去求这 1616 个元素的均值与方差。

 

求取完了均值与方差之后,对于这 1616 个元素中的每个元素分别进行归一化,然后乘以 γγ 加上 ββ,公式如下

batch norm层能够学习到的参数,对于一个特定的 channel 而言实际上是两个参数 γ,betaγ,beta,而对于所有的channel而言实际上就是 channel 数的两倍。

nn.leakyrelu和nn.sigmoid是PyTorch库中的激活函数。 nn.leakyrelu是一个带有负斜率的整流线性单元(rectified linear unit)。它可以通过引入一个小的负斜率来解决ReLU函数在负数输入时导致的神经元死亡问题。nn.leakyrelu函数可以通过调用torch.nn.LeakyReLU()来使用。它可以应用于标量、向量和多维数组输入。例如,对于输入x,可以使用LeakyReLU进行激活,如下所示: leakyrelu = nn.LeakyReLU() out = leakyrelu(x) nn.sigmoid是一个Sigmoid函数,它将输入映射到0和1之间的值。它常用于二分类问题的输出层。nn.sigmoid函数可以通过调用torch.nn.Sigmoid()来使用。它也可以应用于标量、向量和多维数组输入。例如,对于输入x,可以使用Sigmoid进行激活,如下所示: sigmoid = nn.Sigmoid() out = sigmoid(x) 需要注意的是,nn.leakyrelu和nn.sigmoid可以在网络层定义时使用nn.LeakyReLU()和nn.Sigmoid(),也可以作为函数调用在forward函数中使用F.leaky_relu()和F.sigmoid()。两者的使用场景有所不同,具体取决于你的需求和网络结构。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [常用激活函数:Sigmoid/Softmax/ELU/ReLU/LeakyReLU/Tanh...(Pytorch)](https://blog.csdn.net/qq_43665602/article/details/126573992)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [PyTorch学习笔记(1)nn.Sequential、nn.Conv2dnn.BatchNorm2dnn.ReLU和nn.MaxPool2d](https://blog.csdn.net/weixin_42495721/article/details/111518564)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值