不变性
- 在图像中,检测对象并不受它所在的位置影响
当我们在图片中寻找某个物体时,目光聚焦在图片的局部,慢慢扫过整张图片
隐藏表示H,偏置U,卷积核V(卷积层的权重),输入X
i,j为(i,j)处的像素,a,b为索引
卷积核按照索引从左到右,从上往下扫描整张图片
局部性
- 只需检测整张图片局部而不是全部输入
当我们开看书的时候,想要了解某一页的内容,可能会去翻阅上下文,而不是整本书,远处的物体对当前内容的特征提取没有太大意义
将a,b限制在 的范围内,将局部之外的权重设为0
通道
- 图片通常不是黑白的
- 需要多种特征,例如:深度,边缘…
颜色c,每个像素的多维表示
通道d,不同的检测目的
卷积
输出的第一个元素为
输出大小为核的可移动次数=输入大小-核大小+1
定义二维互相关运算
def corr2d(X, K):
# 获取核的大小
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
定义[[常用函数归档#torch.nn#torch.nn.Conv2d|卷积层]]
卷积层对输入和卷积核权重进行互相关运算后添加标量偏置后输出
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
训练
# 构造一个二维卷积层,它具有1个输入\输出通道和形状为(1,2)的卷积核
conv2d = nn.Conv2d(1,1, kernel_size=(1, 2), bias=False)
# 这个二维卷积层使用四维输入和输出格式(批量大小1、灰度通道、高度、宽度),
# 其中批量大小和通道数都为1
X = X.reshape((1, 1, 6, 8))
Y = Y.reshape((1, 1, 6, 7))
lr = 3e-2 # 学习率
optimizer = torch.nn.SGD(conv2d.parameters(),lr=lr)
loss_fn = torch.nn.MSELoss()
for i in range(10):
optimizer.zero_grad()
Y_hat = conv2d(X)
l = loss_fn(Y,Y_hat)
l.backword()
optimizer.step()
if (i + 1) % 2 == 0:
print(f'epoch {i+1}, 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
特征映射和感受野
特征映射是经过卷积核后的输出数据,它提取了输入数据(上一层)的特征
感受野是输出特征映射的某个点在输入图像(所有层)的范围