交叉相关和卷积:
一维和三维交叉相关:一维是文本,三维可以是视频
卷积层讲=将输入和核矩阵进行交叉相关,加上偏移后得到的输出
核矩阵和偏移是可学习的参数
核矩阵的大小是超参数
互相关运算:
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))
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)
实现二维卷积层:
class Conv2D(nn.Module):
def __init__(self,kernel_size):
super().__init__()
self.weight=nn.Parameter(torch.rand(kernel_size))
self.bias=nn.Parmeter(torch.zeros(1))
def forward(self,x):
return corr2d(x,self.weight)+self.bais
卷积层的一个简单应用:检测图像中不同颜色的边缘:
X=torch.ones((6,8))
X[:,2:6]=0
X
K=torch.tensor([[1.0,-1.0]])
Y=corr2d(X,K)
Y
输出Y中的1代表从白色到黑色的边缘,-1代表从黑色到白色的边缘。
conv2d=nn.Conv2d(1,1,kernel_size=(1,2),bias=False)
X=X.reshape((1,1,6,8))
Y=Y.reshape((1,1,6,7))
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}')