目录
红点的部分表示有两个通道,通道0和1,并且每个通道都有单独的卷积和,最后再按元素相加。
C是chanel,输出是一个单通道。
ci代表了一个卷积核的维度,比如输入是三维的rgb图片,那卷积核也就是三维的。而co表示有多少个卷积核,有多少个卷积核就对应多少个输出通道,是这个意思。
就是原本是单通道,输入三通道,那就是三个卷积核,运算后得到单输出通道。现在需要三个通道输出,则需要九个卷积核 ,三个分别运算得到一层,最后汇总得到三层也就是三通道输出。
每个输出通道在识别特定的模式,比如,假设输入是猫,通过设置不同核得到边缘、锐化还是模糊的效果,通过学习不一样的卷积和的参数去匹配某一个特定的模式。多输入通道假设把我把以上6个通道丢给下一个层,下一个层就组合这些模式(按权重相加),就得到一个组合的模式识别。就是通过底层细小的特征,多个角度的边提取特在,越往上层,就把局部的纹理组合起来,比如识别一个猫,先底层识别猫的胡须的纹理,猫的耳朵的纹理。。。最后组合起来,发现某个通道识别的是猫头,猫眼睛,猫脚,然后最上层输出的是猫,就成功识别了猫。
1*1的卷积和只看一个像素不会看像素的周围,所以不识别空间的模式,只融合通道。以上的例子说的是输入通道为3,高和宽都是3的输入,假设输出通道为2,浅蓝色是为输出0的通道,深蓝色是输出1的通道,将某个像素的输出通道为0的浅蓝色的三个通道做加权和,融和。这个图里的ci=3,c0=2,两个c0分别对应kernel里的深蓝和浅蓝,每个蓝都各有ci=3个权重。(输入三通道,如果只有一类卷积核且也为三通道,卷积核的三通道是为了和输入的三通道匹配,那么输出就是一通道,如果卷积核有两类,且每类都是三通道,那么输出就是两通道。)
这里有疑问待解决:弹幕里说偏差是C0。一个卷积和有一个偏差,偏差个数应对应卷积核数。
import torch
from d2l import torch as d2l
#实现一下多输入通道互相关运算。 简而言之,我们所做的就是对每个通道执行互相关操作,
#然后将结果相加。
def corr2d_multi_in(X,K):
return sum(del_corr2d(x,k) for x,k in zip(X,K))
#zip函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些
#元组组成的列表。这里的X是3d的,K是3d的
#验证互相关运算的输出
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]]])
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.]])
"""
#和前面PPT上的一样
#实现一个计算多个通道的输出的互相关函数。
def corr2d_multi_in_out(X,K):
return torch.stack([corr2d_multi_in(X,k) for k in K],0)
#X是3d的,K是4D的,最外面一维是输出通道,对于每一个输出通道的K拿出小k(3d),0就是0维
#沿着一个新维度对输入张量序列进行连接。
K=torch.stack((K,K+1,K+2),0)
#将核张量K与K+1(K中每个元素加1)和K+2连接起来,构造了一个具有个3输出通道的卷积核。
#因为原来的K是3d的,原来一个K就能有一个输出(把3个通道加起来),现在要求K是4d的(多输出),
#因此就创建3个输出通道
K.shape
"""结果输出:
torch.Size([3, 2, 2, 2])"""
#因为每个核的大小是[2*2],2个输入通道需要2个核,就是[2,2,2],有3个输出通道,因此是[3,2,2,2]
corr2d_multi_in_out(X,K)
"""结果输出:
tensor([[[ 56., 72.],
[104., 120.]],
[[ 76., 100.],
[148., 172.]],
[[ 96., 128.],
[192., 224.]]])
"""
#1*1的卷积等价于全连接
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))
#c_i是多数入的维数,把高和宽拉成一条向量,现在X(2,9)
K=K.reshape((c_o,c_i))
#把最后两个维度拿掉,K(3,2)
Y=torch.matmul(K,X)
#调换括号里面的位置就相当于转置,刚好可以矩阵乘法
return Y.reshape((c_o,h,w))
#把原来的一条向量还原成h,w
X=torch.normal(0,1,(3,3,3))
#均值维为0,方差为1,形状为(3,3,3)
K=torch.normal(0,1,(2,3,1,1))
Y1=corr2d_multi_in_out1x1(X,K)
Y2=corr2d_multi_in_out(X,K)
assert float(torch.abs(Y1-Y2).sum())<1e-6
#结果应该输出的是True
总结:
多输入多输出通道可以用来扩展卷积层的模型。
当以每像素为基础应用时,卷积层相当于全连接层。
卷积层通常用于调整网络层的通道数量和控制模型复杂性。
参考: