cs231n-Lecture 4: Neural Networks and Backpropagation

The problem of linear classifier

根据前几讲,对于某些特殊情况linear classifier无法正确分类。
为了解决这一问题,采用两种方式:
1.applying feasture transform.即使用图像变化,此时数据点可以进行线性分类。
以二维为例(即X只有两个元素,W也只有两个元素,本质上是一个二维问题)
在这里插入图片描述
所谓图像变化,本质上是坐标轴变化,变化后就可以用线性分类器进行分类,利用之前学习的KNN、SVM和softmax算法。
坐标变化主要有两种,一种是颜色直方图Color Histogram,另一种是HoG梯度方向直方图
在这里插入图片描述
2.采用卷积神经网络来解决,即ConvNets
在这里插入图片描述

Nerual Networks

本质上是在原本的线性分类的基础上将结果代入激活函数,再把结果继续进行线性分类,以此类推,建立多层的神经网络。

在这里插入图片描述
其中 m a x ( 0 , W 1 x ) max(0,W_1x) max(0,W1x)可称为激活函数,常用的激活函数如下:
在这里插入图片描述
神经网络的结构如下图所示,其中,最后一个隐藏层和输出层也称为全连接层
在这里插入图片描述
神经网络每一层,每一组权重的概念可近似等效为生物上的神经元,输入的数据为电信号,从突触方向引入,从神经细胞上传递,最终得到结果。
在这里插入图片描述
但实际上生物神经元是十分复杂的,是多连接的模式,则说明神经网络的随机连接一样可以工作,而不是采用多层结构。
生物神经元有如下特点:
1.许多种类型
2.树突可以执行复杂的非线性运算
3.突触不是单一的权重,而是复杂的非线性动力学系统

Backpropagation

计算损失函数的梯度是十分困难的,需要大量的矩阵计算和很多张纸,对于复杂的模型是不可行的。
反向传播本质上是链式传播法则,假设权重为x,y,需要得到, ∂ L ∂ x , ∂ L ∂ y \frac{\partial L}{\partial x},\frac{\partial L}{\partial y} xL,yL
网络的输出结果为z,可先求出 ∂ L ∂ z \frac{\partial L}{\partial z} zL,从输出向输入方向传播, ∂ L ∂ z ∗ ∂ z ∂ x = ∂ L ∂ x \frac{\partial L}{\partial z} * \frac{\partial z}{\partial x} = \frac{\partial L}{\partial x} zLxz=xL,可得到结果,多层情况则以此类推。
可得,梯度值是逐层传播的,一直传播到权重层。
在这里插入图片描述
基础的反向传播示例:
在这里插入图片描述
请注意copy gate等例子,是典型的单输入多输出示例。
注意:矢量形式下,计算会更加简便

vector-valued functions

设权重为x,y,激活函数为f,结果为z,损失函数为L,则 D x D_x Dx为x的矢量形式, D y D_y Dy为y的矢量形式, D z D_z Dz为z的矢量形式,值得注意的是,L为标量,其梯度与原变量具有相同的形式。
示意图如下:
在这里插入图片描述
当输入数据为多组时,则此时输出数据也应该是多组的,输入、权重都是矩阵,输出也是矩阵。则之前的点乘相加的方式转化为输入与输出矩阵的的乘积,而对于反向传播而言,则是将上游梯度矩阵乘以雅可比矩阵,得到下游梯度矩阵。
假设没有权重,考虑最简单的形式:
在这里插入图片描述
注意雅可比矩阵一般要隐式给出:
在这里插入图片描述
不考虑激活函数,实际形式如图所示:
在这里插入图片描述

代码总结

features.ipynb

核心在于进行Image Features Exercises

Extract Features

对于每一张图像,对提取的特征进行处理,比对原始像素进行处理效果更好。如The problem of linear classifer中所述,图像特征提取有几种方法,一种是定向梯度直方图HoG,另一种是颜色直方图。
这两部分算法在features.py中进行编写,用api的形式被调用。
彩色和灰度图像都可以进行梯度计算,对于彩色图像而言,转化为灰度图进行处理。
使用图像卷积来计算梯度。
在这里,使用HoG和颜色直方图的数据作为一个向量,进行处理。

卷积与梯度

图像卷积:
其形式如图所示
在这里插入图片描述
核心公式如下:
f ∗ w = ∑ ( a , b ) ∈ w ( x − a , y − b ) ∈ f w ( a , b ) f ( x − a , y − b ) f*w=\sum_{(a,b) \in w (x - a,y - b) \in f}w(a,b)f(x - a,y - b) fw=(a,b)w(xa,yb)fw(a,b)f(xa,yb)
梯度可以表示为
▽ f = [ G x G y ] = [ ∂ f ( x , y ) ∂ x ∂ f ( x , y ) ∂ y ] \bigtriangledown f = \begin{bmatrix} G_x \\ G_y \end{bmatrix}=\begin{bmatrix} \frac{\partial f(x,y)}{\partial x} \\ \frac{\partial f(x,y)}{\partial y} \end{bmatrix}\quad f=[GxGy]=[xf(x,y)yf(x,y)]
根据两点差分原则,进一步可以表示为
∂ f ∂ x = f ( x + 1 , y ) − f ( x , y ) \frac{\partial f}{\partial x} = f(x + 1,y) - f(x,y) xf=f(x+1,y)f(x,y)
∂ f ∂ y = f ( x , y + 1 ) − f ( x , y ) \frac{\partial f}{\partial y} = f(x,y + 1) - f(x,y) yf=f(x,y+1)f(x,y)
由此可以得到导数,即梯度。
幅值梯度为 g = G x 2 + G y 2 g = \sqrt{G_x^2 + G_y^2} g=Gx2+Gy2
方向梯度为 θ = a r c t a n ( G y G x ) \theta = arctan(\frac{G_y}{G_x}) θ=arctan(GxGy)

计算梯度有很多方法。
可通过对原图像进行卷积计算得到。
可卷积两次,第一次得到水平梯度,第二次得到垂直梯度。
1.Prewitt 算子。
[ − 1 0 1 − 1 0 1 − 1 0 1 ] \begin{bmatrix} -1 & 0 & 1 \\ -1& 0 & 1 \\ -1& 0 & 1 \end{bmatrix}\quad 111000111
用于计算水平梯度,检测垂直边缘
[ − 1 − 1 − 1 0 0 0 1 1 1 ] \begin{bmatrix} -1 & -1 & -1 \\ 0 & 0 & 0 \\ 1& 1 & 1 \end{bmatrix}\quad 101101101
用于计算垂直梯度,检测水平边缘
2.Sobel算子
[ − 1 0 1 − 2 0 2 − 1 0 1 ] \begin{bmatrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1& 0 & 1 \end{bmatrix}\quad 121000121
用于计算水平梯度,检测垂直边缘
[ − 1 − 2 − 1 0 0 0 1 2 1 ] \begin{bmatrix} -1& -2 & -1 \\ 0& 0 & 0 \\ 1& 2 & 1 \end{bmatrix}\quad 101202101
用于计算垂直梯度,检测水平边缘

HoG

第一步是计算整个图像的x、y方向的梯度。
可采取卷积的方式,但在这里采用两点差分的原则。

gx = np.zeros(image.shape)
gy = np.zeros(image.shape)
gx[:, :-1] = np.diff(image, n=1, axis=1)  # compute gradient on x-direction
gy[:-1, :] = np.diff(image, n=1, axis=0)  # compute gradient on y-direction

之后将横向和纵向的梯度平方求和,在开根号,得到幅值梯度。
值得注意的是,gx,gy的形状是相同的。
计算图像任意一点的方向梯度,由于得到的是弧度,所以先转化为角度,因为actan的大小为[-90,90],所以要加上90度,使范围达到[0,180]

 grad_mag = np.sqrt(gx ** 2 + gy ** 2)  # gradient magnitude
 grad_ori = np.arctan2(gy, (gx + 1e-15)) * (180 / np.pi) + 90  # gradient orientation

之后将整个图像划分为若干个8 * 8的cell,将每个cell转化为长度为9的数组,为9bins,即将180°分解为9份,根据方向矩阵将,对应度数的梯度幅值加到数组中。
如图所示:
在这里插入图片描述
若度数为10°,则按比例加载到0°,20°中。如图所示,幅值为4,则0°加2,20°加2。
若度数为160°-180°之间,则需按比例加到0°,160°的bin中。
这就是梯度向量直方图。
可以生成n_cellsx * n_cellsy个cell
建立对应的向量

sx, sy = image.shape  # image size
orientations = 9  # number of gradient bins
cx, cy = (8, 8)  # pixels per cell

n_cellsx = int(np.floor(sx / cx))  # number of cells in x
n_cellsy = int(np.floor(sy / cy))  # number of cells in y
# compute orientations integral images
orientation_histogram = np.zeros((n_cellsx, n_cellsy, orientations))

遍历9个相邻的角度之间,如0-20°,20-40°等,将方向梯度矩阵所有超过角度范围内的值设置为0,据此得到标记矩阵,保留所有角度矩阵非零的幅值矩阵的值,其他值都设置为0。
在这里使用了均值滤波。
均值滤波是指在图像的一个方块区域内,中心像素的值是整个像素的平均值。以cell的形状为方块大小,遍历整个图像,得到图像各个点的像素值。
为了使取方块区域恰好在图像范围内,且方块之间互相不重叠,则规定只从cell横纵坐标的一半开始取值,每隔cell的横纵坐标的大小,开始取值。
最终得到结果,并保存在每隔cell对应的角度矩阵里。

for i in range(orientations):
    # create new integral image for this orientation
    # isolate orientations in this range
    temp_ori = np.where(grad_ori < 180 / orientations * (i + 1), grad_ori, 0)
    temp_ori = np.where(grad_ori >= 180 / orientations * i, temp_ori, 0)
    # select magnitudes for those orientations
    cond2 = temp_ori > 0
    temp_mag = np.where(cond2, grad_mag, 0)
    orientation_histogram[:, :, i] = uniform_filter(temp_mag, size=(cx, cy))[round(cx / 2) :: cx, round(cy / 2) :: cy].T
颜色直方图

根据图像的通道分为n个向量。
每个向量为该通道对应像素值的比例。
例如:
H通道,向量共有30个数,第一个数表示,像素值在[0,5]范围内的个数,第二个数就是像素在[6,11]范围内的个数,以此类推。
在这里插入图片描述
颜色直方图可以用现成的api调用,方法很多。
可以采用opencv,或者是matplotlib来实现。
在此,不做过多的说明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值