深圳建设银行分行网站,信主网站,网站建设联系我们,公司企业网站建设目录 一、互相关运算
二、卷积层
三、图像中目标的边缘检测
四、学习卷积核
五、特征映射和感受野 一、互相关运算 严格来说#xff0c;卷积层是个错误的叫法#xff0c;因为它所表达的运算其实是互相关运算#xff08;cross-correlation#xff09;#xff0c;而不是…目录 一、互相关运算
二、卷积层
三、图像中目标的边缘检测
四、学习卷积核
五、特征映射和感受野 一、互相关运算 严格来说卷积层是个错误的叫法因为它所表达的运算其实是互相关运算cross-correlation而不是卷积运算。在卷积层中输入张量和核张量通过互相关运算产生输出张量。 首先我们暂时忽略通道第三维这一情况看看如何处理二维图像数据和隐藏表示。在 下图中输入是高度为 、宽度为 的二维张量即形状为 。卷积核的高度和宽度都是 而卷积核窗口或卷积窗口的形状由内核的高度和宽度决定即 。 在二维互相关运算中卷积窗口从输入张量的左上角开始从左到右、从上到下滑动。当卷积窗口滑动到新一个位置时包含在该窗口中的部分张量与卷积核张量进行按元素相乘得到的张量再求和得到一个单一的标量值由此我们得出了这一位置的输出张量值。 在如上例子中输出张量的四个元素由二维互相关运算得到这个输出高度为 、宽度为 如下所示 注意输出大小略小于输入大小。这是因为卷积核的宽度和高度大于1而卷积核只与图像中每个大小完全适合的位置进行互相关运算。所以输出大小等于输入大小 减去卷积核大小 加 即 接下来我们在corr2d函数中实现如上过程该函数接受输入张量X和卷积核张量K并返回输出张量Y。
import torch
from torch import nn
from d2l import torch as d2l
def corr2d(X, K):计算二维互相关运算h, w K.shapeY torch.zeros((X.shape[0] - h 1, X.shape[1] - w 1)) # 先算出输出张量的形状并初始化为0for i in range(Y.shape[0]):for j in range(Y.shape[1]):Y[i, j] (X[i:i h, j:j w] * K).sum() # 输出张量的每一个元素都是X与K经过某种计算得到的return Y # 返回二维互相关运算后的结果Y 我们来验证上述二维互相关运算的输出。
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]])
print(corr2d(X, K))
tensor([[19., 25.],[37., 43.]])
二、卷积层 卷积层对输入和卷积核权重进行互相关运算并在添加标量偏置之后产生输出。所以卷积层中的两个被训练的参数是卷积核权重和标量偏置如下图所示。就像我们之前随机初始化全连接层一样在训练基于卷积层的模型时我们也随机初始化卷积核权重。 基于上面定义的corr2d函数实现二维卷积层。在__init__构造函数中将weight和bias声明为两个模型参数。前向传播函数调用corr2d函数并添加偏置。
class Conv2D(nn.Module):def __init__(self, kernel_size):super().__init__()self.weight nn.Parameter(torch.rand(kernel_size))self.bias nn.Parameter(torch.zeros(1))def forward(self, x):return corr2d(x, self.weight) self.bias 高度和宽度分别为 和 的卷积核可以被称为 卷积或 卷积核。我们也将带有 卷积核的卷积层称为 卷积层。
三、图像中目标的边缘检测 如下是卷积层的一个简单应用通过找到像素变化的位置来检测图像中不同颜色的边缘。 首先我们构造一个 像素的黑白图像。中间四列为黑色其余像素为白色。
X torch.ones((6, 8))
X[:, 2:6] 0
print(X)
tensor([[1., 1., 0., 0., 0., 0., 1., 1.],[1., 1., 0., 0., 0., 0., 1., 1.],[1., 1., 0., 0., 0., 0., 1., 1.],[1., 1., 0., 0., 0., 0., 1., 1.],[1., 1., 0., 0., 0., 0., 1., 1.],[1., 1., 0., 0., 0., 0., 1., 1.]]) 接下来我们构造一个高度为 、宽度为 的卷积核K。当进行互相关运算时如果水平相邻的两元素相同则输出为零否则输出为非零。
K torch.tensor([[1.0, -1.0]]) 现在我们对参数X输入和K卷积核执行互相关运算。如下所示输出Y中的1代表从白色到黑色的边缘-1代表从黑色到白色的边缘其他情况的输出为0。
Y corr2d(X, K)
Y
tensor([[ 0., 1., 0., 0., 0., -1., 0.],[ 0., 1., 0., 0., 0., -1., 0.],[ 0., 1., 0., 0., 0., -1., 0.],[ 0., 1., 0., 0., 0., -1., 0.],[ 0., 1., 0., 0., 0., -1., 0.],[ 0., 1., 0., 0., 0., -1., 0.]]) 现在我们将输入的二维图像转置再进行如上的互相关运算。其输出如下之前检测到的垂直边缘消失了。不出所料这个卷积核K只可以检测垂直边缘无法检测水平边缘。
corr2d(X.t(), K)
tensor([[0., 0., 0., 0., 0.],[0., 0., 0., 0., 0.],[0., 0., 0., 0., 0.],[0., 0., 0., 0., 0.],[0., 0., 0., 0., 0.],[0., 0., 0., 0., 0.],[0., 0., 0., 0., 0.],[0., 0., 0., 0., 0.]])
四、学习卷积核 如果我们只需寻找黑白边缘那么以上[1, -1]的边缘检测器足以。然而当有了更复杂数值的卷积核或者连续的卷积层时我们不可能手动设计滤波器。那么我们可以学习由X生成Y的卷积核。 现在让我们看看是否可以通过仅查看“输入-输出”对来学习由X生成Y的卷积核。我们先构造一个卷积层并将其卷积核初始化为随机张量。接下来在每次迭代中我们比较Y与卷积层输出的平方误差然后计算梯度来更新卷积核。为了简单起见我们在此使用内置的二维卷积层并忽略偏置。
# 构造一个二维卷积层它具有1个输入通道、1个输出通道和形状为(12)的卷积核
conv2d nn.Conv2d(1, 1, kernel_size(1, 2), biasFalse) # 因为我们前面用的是二维互相关运算corr2d()由X生成的Y因此不需要bias# 这个二维卷积层使用四维输入和输出格式批量大小、通道、高度、宽度
# 其中批量大小和通道数都为1
X X.reshape((1, 1, 6, 8))
Y Y.reshape((1, 1, 6, 7))
lr 3e-2 # 学习率for i in range(10):Y_hat conv2d(X)l (Y_hat - Y) ** 2 # 使用均方误差conv2d.zero_grad()l.sum().backward()# 迭代卷积核conv2d.weight.data[:] - lr * conv2d.weight.grad # 手写实现梯度下降if (i 1) % 2 0:print(fepoch {i1}, loss {l.sum():.3f})
epoch 2, loss 6.422
epoch 4, loss 1.225
epoch 6, loss 0.266
epoch 8, loss 0.070
epoch 10, loss 0.022 在10次迭代之后误差已经降到足够低。现在我们来看看我们所学的卷积核的权重张量。
conv2d.weight.data.reshape((1, 2))
tensor([[ 1.0010, -0.9739]]) 我们学习到的卷积核权重非常接近我们之前定义的卷积核K。
五、特征映射和感受野 下图中输出的卷积层有时被称为特征映射feature map因为它可以被视为一个输入映射到下一层的空间维度的转换器。 在卷积神经网络中对于某一层的任意元素 其感受野receptive field是指在前向传播期间可能影响 计算的所有元素来自所有先前层。 请注意感受野可能大于输入的实际大小。让我们用上图为例来解释感受野给定 卷积核阴影输出元素值 的感受野是输入阴影部分的四个元素。假设之前输出为 其大小为 现在我们在其后附加一个卷积层该卷积层以 为输入输出单个元素。在这种情况下 上的 的感受野包括 的所有四个元素而输入的感受野包括最初所有九个输入元素。 因此当一个特征图中的任意元素需要检测更广区域的输入特征时我们可以构建一个更深的网络。