[pytorch、学习] - 5.1 二维卷积层

参考

5.1 二维卷积层

卷积神经网络(convolutional neural network)是含有卷积层(convolutional layer)的神经网络。本章介绍的卷积神经网络均使用最常见的二维卷积层。它有高和宽两个空间维度,常用来处理图像数据。本节中,我们将介绍简单形式的二维卷积层的工作原理。

5.1.1 二维互相关运算

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R6BW7Hcg-1594090508304)(attachment:image.png)]

# 将上述过程实现在 corr2d 函数里.它接受输入数组 X 与核数组 K,并输出数组 Y
import torch 
from torch import nn

def corr2d(X, K):  # 本函数已保存在d2lzh_pytorch包中方便以后使用
    h, w = K.shape
    Y = torch.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1))
    for 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()
    return Y
X = torch.tensor([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
K = torch.tensor([[0, 1], [2, 3]])
corr2d(X, K)

在这里插入图片描述

5.1.2 二维卷积层

二维卷积层将输入和卷积核做互相运算,并加上一个标量偏差来得到输出。卷积层的模型参数包括了卷积核和标量偏差。在训练模型的时候,通常我们先对卷积核进行随机初始化,然后不断迭代卷积核和偏差。

下面基于corr2d函数实现一个自定义的二维卷积层。在构造函数__init__里,我们声明了weightbias这两个模型参数。前向计算函数forward则是直接调用corr2d函数在加上偏差

class Conv2D(nn.Module):
    def __init__(self, kernel_size):
        super(Conv2D, self).__init__()
        self.weight = nn.Parameter(torch.randn(kernel_size))
        self.bias = nn.Parameter(torch.randn(1))

    def forward(self, x):
        return corr2d(x, self.weight) + self.bias

5.1.3 图像中物体边缘检测

下面我们来看一个卷积的简单应用: 检测图像物体的边缘,即找到像素变化的位置。首先我们构造一张 6 * 8 的图像。它中间4列为黑(0),其余为白(1)

X = torch.ones(6, 8)
X[:, 2:6] = 0.
X

在这里插入图片描述
然后我们构造一个高和宽分别为1和2的卷积核K。当它与输入做相关运行时,如果横向相邻元素相同,输出为0; 否则输出为非0.

K = torch.tensor([[1., -1.]])
K

在这里插入图片描述

下面将输入X和我们设计的卷积核K做相关运算。可以看出,我们将从白到黑和从黑到白的边缘分别检测成了1和-1。其余部分的输出全是0

Y = corr2d(X, K)
Y

在这里插入图片描述

5.1.4 通过数据学习核数组

最后我们来看一个例子,它使用物体边缘检测中的输入数据X和输出数据Y来学习我们构造的核数组K。我们首先构造一个卷积层,其卷积核将被初始化成随机数组。接下来在每一次迭代中,我们使用平方误差来比较Y和卷积层的输出,然后计算梯度来更新权重。

# 构造一个核数组
conv2d = Conv2D(kernel_size=(1, 2))

step ,lr = 60 , 0.01

for i in range(step):
    Y_hat = conv2d(X)
    l = ((Y_hat - Y) ** 2).sum()
    l.backward()
    
    # 梯度下降
    conv2d.weight.data -= lr * conv2d.weight.grad
    conv2d.bias.data -= lr * conv2d.bias.grad
    
    # 梯度清0
    conv2d.weight.grad.fill_(0)
    conv2d.bias.grad.fill_(0)
    if(i + 1) % 5 == 0:
        print("Step %d, loss %.5f "% (i+1, l.item()))

在这里插入图片描述

print(conv2d.weight)
print(conv2d.bias)

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/piano9425/article/details/107176556
5.1