赞
踩
1.平移不变性:(通俗理解)卷积核Vab是一个找猫猫的特征器,识别猫的特征器不会因为图片中猫藏的位置不同而发生变化,即同一张卷积核遍历整张图片。
2.局部性:(通俗理解)卷积核是一个试探模板,不想考虑某个位置的时候,就置0,想重点考虑某个位置的时候就设置值为大,即限制卷积核的宽高ab
在全连接层W是权重矩阵,Wij是矩阵第i行第j列的一个值(标量),在第i行第j列引入“宽高”两个维度(k,l)就变成四维,推广后的Wij就是一个二维矩阵,有宽也有高。
i,j对应filter内参数的位置,k,l是输入矩阵输入特征的位置,第一个等号说明Wij要和所有的特征相乘。
对全连接层使用平移不变性和局部性得到卷积层
1.卷积层将输入和核矩阵进行交叉相关,加上偏移后得到输出
2.核矩阵和偏移都是可学习的参数
3.核矩阵的大小是超参数
互相关运算
import torch
from torch import nn
from d2l import torch as d2l
def corr2d(X,K):
'''计算二维互相关运算。'''
h,w = K.shape # 行、列
Y = torch.zeros((X.shape[0]-h+1, X.shape[1]-w+1)) # 输出: 输入的高-核的高+1,输入的宽度-核的宽度+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.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]])
corr2d(X,K) # 哈马达积
tensor([[19., 25.],
[37., 43.]])
实现二维卷积层
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
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 = torch.tensor([[1.0, -1.0]])
输出Y中的1代表从白色到黑色的边缘,-1代表从黑色到白色的边缘
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) # X.t():转置
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.]])
学习由X生成Y的卷积核
conv2d = nn.Conv2d(1, 1, kernel_size=(1,2), bias=False) # 输入的通道是1,输出的通道是1,kernel_size核:2d的vector(学1*2的核),目前不需要bias
# 核设置了1*2,X是6*8,最后的结果会少1列(矩阵),所以Y是6*7
X = X.reshape((1,1,6,8)) # 批量大小、通道、高度、宽度
Y = Y.reshape((1,1,6,7)) # corr2d(X,K)
for i in range(10):
Y_hat = conv2d(X)
l = (Y_hat-Y)**2
conv2d.zero_grad()
l.sum().backward()
conv2d.weight.data[:] -= 3e-2 * conv2d.weight.grad
if (i+1)%2 == 0:
print(f'batch{i+1}, loss{l.sum():.3f}')
batch2, loss4.515
batch4, loss0.822
batch6, loss0.165
batch8, loss0.039
batch10, loss0.011
所学的卷积核的权重张量
conv2d.weight.data.reshape((1,2))
tensor([[ 0.9983, -0.9803]])
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。