Pytorch 从CNN到YOLOv1
CNN

.png)

分类猫和狗
使用一个还不错的相机采集图片(12M)
RGB figure 36M 元素
使用100大小的单隐藏层MLP 模型有3.6B = 14GB 元素
远多于世界上所有的猫狗总数(900M dog 600M cat)
两个原则
平移不变性
局部性
重新考察全连接层
将输入和输出变形为矩阵(宽度,高度)
将权重变形为4-D张量(h,w)到(h',w')
\[h_{i,j}=\sum_{k,l}w_{i,j,k,l}x_{k,l}=\sum_{a,b}=v_{i,j,a,b}x_{i+a,j+b} \]V是W的重新索引
\[v_{i,j,a,b}=w_{i,j,i+a,j+b} \]原则#1 - 平移不变性
x的平移导致h的平移
\[h_{i,j}=\sum_{a,b}v_{i,j,a,b}x_{i+a,j+b} \]v不应依赖于(i, j)
解决方案:
\[v_{i,j,a,b}=v_{a, b}, h_{i,j}=\sum_{a,b}v_{a,b}x_{i+a,j+b} \]这就是交叉相关
原则#2 - 局部性
局部性
\[\begin{aligned} &为了收集用来训练参数[\mathbf{H}]_{i, j}的相关信息,\\ &我们不应偏离到距(i, j)很远的地方。\\ &这意味着在|a|> \Delta或|b| > \Delta的范围之外,\\ &我们可以设置[\mathbf{V}]_{a, b} = 0。\\ &因此,我们可以将[\mathbf{H}]_{i, j}重写为:\\ &[\mathbf{H}]*_{i, j} = u + \sum_*{a = -\Delta}^{\Delta} \sum*_{b = -\Delta}^{\Delta} [\mathbf{V}]_*{a, b} [\mathbf{X}]_{i+a, j+b}. \end{aligned} \]当图像处理的局部区域很小时,卷积神经网络与多层感知机的训练差异可能是巨大的:以前,多层感知机可能需要数十亿个参数来表示网络中的一层,而现在卷积神经网络通常只需要几百个参数,而且不需要改变输入或隐藏表示的维数。
参数大幅减少的代价是,我们的特征现在是平移不变的,并且当确定每个隐藏活性值时,每一层只包含局部的信息。
以上所有的权重学习都将依赖于归纳偏置。当这种偏置与现实相符时,我们就能得到样本有效的模型,并且这些模型能很好地泛化到未知数据中。
但如果这偏置与现实不符时,比如当图像不满足平移不变时,我们的模型可能难以拟合我们的训练数据。







Sharing-Weight










import torch
from torch import nn
from d2l import torch as d2l
def corr2d(X, K): #@save
"""计算二维互相关运算"""
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)
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
高度和宽度分别为\(h\)和\(w\)的卷积核可以被称为\(h \times w\)卷积或\(h \times w\)卷积核。
我们也将带有\(h \times w\)卷积核的卷积层称为\(h \times w\)卷积层。
图像中目标的边缘检测
如下是[卷积层的一个简单应用:]通过找到像素变化的位置,来(检测图像中不同颜色的边缘)。
首先,我们构造一个\(6\times 8\)像素的黑白图像。中间四列为黑色(\(0\)),其余像素为白色(\(1\))。
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 = 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.]])
corr2d(X.t(), K) #卷积核`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,2)的卷积核
conv2d = nn.Conv2d(1,1, kernel_size=(1, 2), bias=False)
# 这个二维卷积层使用四维输入和输出格式(批量大小、通道、高度、宽度),
# 其中批量大小和通道数都为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(f'epoch {i+1}, loss {l.sum():.3f}')
epoch 2, loss 4.723
epoch 4, loss 0.793
epoch 6, loss 0.134
epoch 8, loss 0.023
epoch 10, loss 0.004
conv2d.weight.data.reshape((1, 2))# 在 10 次迭代之后,误差已经降到足够低
tensor([[ 0.9875, -0.9899]])
Pooling - Max Pooling


Max-Pooling:选取最大的值 也可选取其他的采用 当然也可不做采用前提是性能足够



但CNN无法直接对一个放大的图像做识别,需要data augmentation(对数据集进行旋转,放大,缩小,等操作)
YOLOv1
Bounding-Box
将一张图片分割为有限个单元格(Cell,图中红色网格)

每一个输出和标签都是针对每一个单元格的物体中心(midpiont,图中蓝色圆点)
每一个单元格会有[X1, Y1, X2, Y2]
对应的物体中心会有一个[X, Y, W, H]

X, Y 在[0, 1]内表示水平或垂直的距离
W, H > 1 表示物体水平或垂直方向上高于该单元格 数值表示水平或垂直方向的单位长度的倍数
[0.95, 0.55, 0.5, 1.5]=>显然图像靠近右下角 单元格不能表示出完整的物体

根据 [X, Y, W, H] => [0.95, 0.55, 0.5, 1.5] 计算得到Bounding Box(图中蓝色网格)

Image-Label
\[\begin{aligned} &label_{cell}=[C_1,C_2,\cdots,C_{20},P_c,X,Y,W,H]\\ &[C_1,C_2,\cdots,C_{20}]:20\space different\space classes\\ &[P_c]:Probability\space for\space there\space is\space an\space object(0\or1)\\ &[X,Y,W,H]:Bounding-Box\\ &pred_{cell}=[C_1,C_2,\cdots,C_{20},P_{c1},X_1,Y_1,W_1,H_1,P_{c2},X_2,Y_2,W_2,H_2]\\ &Taget\space shape\space for\space one \space images:(S, S, 25)\\ &Predication\space shape \space for\space one\space images:(S,S,30)\\ \end{aligned} \]Model-Framework
