首页 > 其他分享 >《动手学深度学习 Pytorch版》 6.4 多输入多输出通道

《动手学深度学习 Pytorch版》 6.4 多输入多输出通道

时间:2023-09-17 21:16:03浏览次数:46  
标签:lfloor multi 卷积 torch corr2d times 动手 Pytorch 6.4

import torch
from d2l import torch as d2l

6.4.1 多输入通道

简言之,多通道即为单通道之推广,各参数对上即可。

def corr2d_multi_in(X, K):
    # 先遍历“X”和“K”的第0个维度(通道维度),再把它们加在一起
    return sum(d2l.corr2d(x, k) for x, k in zip(X, K))

X = torch.tensor([[[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]],  # 构造双通道张量
               [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]])
K = torch.tensor([[[0.0, 1.0], [2.0, 3.0]], [[1.0, 2.0], [3.0, 4.0]]])

corr2d_multi_in(X, K)
tensor([[ 56.,  72.],
        [104., 120.]])

6.4.2 多输出通道

def corr2d_multi_in_out(X, K):
    # 迭代“K”的第0个维度,每次都对输入“X”执行互相关运算。
    # 最后将所有结果都叠加在一起
    return torch.stack([corr2d_multi_in(X, k) for k in K], 0)

K = torch.stack((K, K + 1, K + 2), 0)  # 构造一个具有三个输出通道的卷积核
K, K.shape
(tensor([[[[0., 1.],
           [2., 3.]],
 
          [[1., 2.],
           [3., 4.]]],


[[[1., 2.],
[3., 4.]],

          [[2., 3.],
           [4., 5.]]],


[[[2., 3.],
[4., 5.]],

          [[3., 4.],
           [5., 6.]]]]),
 torch.Size([3, 2, 2, 2]))
corr2d_multi_in_out(X, K)
tensor([[[ 56.,  72.],
         [104., 120.]],

        [[ 76., 100.],
         [148., 172.]],

        [[ 96., 128.],
         [192., 224.]]])

6.4.3 \(1\times1\)卷积层

\(1\times1\) 的卷积失去了卷积层在高度和宽度维度上识别相邻元素间相互作用的能力。可以将其看作再每个像素位置的全连接层。

def corr2d_multi_in_out_1x1(X, K):
    c_i, h, w = X.shape
    c_o = K.shape[0]
    X = X.reshape((c_i, h * w))  # 展开为 h*w 的张量方便计算
    K = K.reshape((c_o, c_i))  # 同样的展开
    # 全连接层中的矩阵乘法
    Y = torch.matmul(K, X)
    return Y.reshape((c_o, h, w))
X = torch.normal(0, 1, (3, 3, 3))
K = torch.normal(0, 1, (2, 3, 1, 1))

Y1 = corr2d_multi_in_out_1x1(X, K)
Y2 = corr2d_multi_in_out(X, K)
assert float(torch.abs(Y1 - Y2).sum()) < 1e-6  # 执行1*1卷积运算时上述函数相当于先前实现的互关函数

练习

(1)假设我们有两个卷积核,大小分别为 \(k_1\) 和 \(k_2\) (中间没有非线性激活函数)。

a. 证明运算可以用单次卷积来表示。

b. 这个等效的单个卷积核的维数是多少呢?

c. 单次卷积是否可以用两个卷积来表示呢?

不会


(2)假设输入为 \(c_i\times h\times w\),卷积核大小为 \(c_o\times c_i\times k_h\times k_w\),填充为 \((p_h,p_w)\),步幅为 \((s_h,s_w)\)。

a. 前向传播的计算成本(乘法和加法)是多少?
b. 内存占用空间是多大?
c. 反向传播的内存占用空间是多大?
d. 反向传播的计算成本是多少?

\(\left\lfloor(n_h-k_h+p_h+s_h)/s_h\right\rfloor\times\left\lfloor(n_w-k_w+p_w+s_w)/s_w\right\rfloor\)

a. 前向传播的计算成本为:

\[(\left\lfloor(h-k_h+p_h+s_h)/s_h\right\rfloor\times\left\lfloor(w-k_w+p_w+s_w)/s_w\right\rfloor)\times c_o\times c_i\times(k_h\times k_w+1) \]

b. 占用空间为:

\[(\left\lfloor(h-k_h+p_h+s_h)/s_h\right\rfloor\times\left\lfloor(w-k_w+p_w+s_w)/s_w\right\rfloor)\times c_o\times c_i\times4B \]

c. 不会

d. 不会


(3)如果我们将输入通道 \(c_i\) 和输出通道 \(c_o\) 的数量加倍,计算量会增加多少?如果我们把填充数翻一番会怎么样?

如上题,将输入通道 \(c_i\) 和输出通道 \(c_o\) 的数量加倍则计算量会增加 4 倍。

填充数翻一倍还要考虑步长。


(4)如果卷积核的高度和宽度是 \(k_h=k_w=1\),前向传播的计算复杂的是多少?

\(c_o\times c_i\times h\times w\)


(5)本节最后一个示例中的变量 Y1 和 Y2 是否完全相同?为什么?

浮点数有误差,肯定不可能完全相同。


(6)当卷积窗口不是 \(1\times1\) 时,如何使用矩阵乘法实现卷积?

?一直用的就是矩阵乘法哇

标签:lfloor,multi,卷积,torch,corr2d,times,动手,Pytorch,6.4
From: https://www.cnblogs.com/AncilunKiang/p/17709808.html

相关文章

  • 《动手学深度学习 Pytorch版》 6.5 汇聚层
    importtorchfromtorchimportnnfromd2limporttorchasd2l6.5.1最大汇聚和平均汇聚汇聚层和卷积层类似,区别在于汇聚层不带包含参数,汇聚操作是确定性的,通常计算汇聚窗口中所有元素的最大值或平均值,即最大汇聚和平均汇聚。defpool2d(X,pool_size,mode='max'):p......
  • 《动手学深度学习 Pytorch版》 6.6 卷积神经网络
    importtorchfromtorchimportnnfromd2limporttorchasd2l6.6.1LeNetLetNet-5由两个部分组成:-卷积编码器:由两个卷积核组成。-全连接层稠密块:由三个全连接层组成。模型结构如下流程图(每个卷积块由一个卷积层、一个sigmoid激活函数和平均汇聚层组成):全连接......
  • 一起动手打造个人娱乐级linux
    我们使用电脑,一直以来用的都是windows,但是对于像我这种爱折腾的人来说,尝试使用linux系统应该是一种不错的体验。说到linux,许多人可能都没听过,或者知道的人对它印象是这样的:然而,linux发展这么久,桌面应用也已经发展得非常成熟了,现在我们linux可以是这样的:ubuntu16.04archlinux......
  • 《动手学深度学习 Pytorch版》 6.7 填充和步幅
    6.3.1填充虽然我们用的卷积核较小,每次只会丢失几像素,但是如果应用多层连续的卷积层,累积的像素丢失就会很多。解决此问题的方法为填充。填充后的输出形状将为\((n_h-k_h+p_h+1)\times(n_w-k_w+p_w+1)\)importtorchfromtorchimportnndefcomp_conv2d(conv2d,X):X......
  • 用Rust手把手编写一个Proxy(代理), 准备篇, 动手造轮子
    用Rust手把手编写一个Proxy(代理),准备篇,动手造轮子wmproxy将实现http/https代理,socks5代理,后续将实现websocket代理,内外网穿透等,会将实现过程分享出来,希望感兴趣的可以一起参与参与项目++wmproxy++gite:https://gitee.com/tickbh/wmproxygithub:https://git......
  • 课后动手动脑
    publicstaticvoidmain(String[]args){floata=(float)1.0;floatb=(float)0.965;doublea1=1.0;doubleb1=0.965;BigDecimala2=newBigDecimal(a1);BigDecimalb2=newBigDecimal(b1);BigDecimala3=newBigDecimal(......
  • 课后动手动脑
    对于Java的float和double类型,都存在精度损失的问题。精度损失产生的原因在于Java的数据存储采用的都是2进制形式,二进制不能准确的表示1/10等分数,只能无限趋近。publicstaticvoidmain(String[]args){floata=(float)1.0;floatb=(float)0.965;doubl......
  • Pytorch
    创建项目的方式DataSet类代码实战read_data.pyfromtorch.utils.dataimportDatasetfromPILimportImageimportosclassMyData(Dataset):def__init__(self,root_dir,label_dir):self.root_dir=root_dirself.label_dir=label_dir......
  • 《动手学深度学习 Pytorch版》 6.2 图像卷积
    importtorchfromtorchimportnnfromd2limporttorchasd2l6.2.1互相关计算X=torch.tensor([[0.0,1.0,2.0],[3.0,4.0,5.0],[6.0,7.0,8.0]])K=torch.tensor([[0.0,1.0],[2.0,3.0]])此处应为:012345678*0123=......
  • 课堂动手动脑问题
    Enum是一种类类型,他的对象的值智能是其所有列举项目中的一个。并且,各个枚举项的对象都是不相同的。定义static的value的范围更大,但在主函数中的value里输出近,所以输出结果为2输入输出反码补码原码在计算机中,原码、反码和补码是表示有符号整数的三种常见方式。在Java中,整数......