刚刚开始入门深度学习的过程艰苦异常,没有一点相关的基础甚至于Python都不能熟练掌握。学习cs231n课程的时候眼睛都跟不上字幕,讲的是什么东西也基本听不懂,在这种煎熬的环境下磕磕绊绊了好久才学到Lecture3,给自己做个总结吧。
Lecrure1:引言
这一节课主要讲两个方面的内容:
计算机视觉的发展历史
从生物拥有视觉开始讲起,中间经过无数科学家的研究和尝试,使用了各种方式试图让机器能够拥有人类一样的视觉和理解能力。发展到现在计算机在许多场景下对于图片的识别能力已经超过了人类。
cs231n课程概况
- cs231n主要围绕在视觉识别的一个最重要的问题之一 —— 图像分类
- 有大量的视觉识别问题和图像分类有关,例如目标检测,图像说明
- 卷积神经网络(CNN)已经成为一个物体识别的一个重要工具
- 卷积神经网络(CNN)不是突然被发明出来的
- 对于视觉智能的追求远远不止于物体识别
第一节课由于是引言,没有什么关键性的知识点,就不详细展开了。
Lecture 2:图像分类的途径
图像分类:计算机视觉中的一个核心问题
图像分类是什么呢?给了计算机一张图片和各种标签的集合,计算机能准确的判断出这张图片所对应的标签是什么。
问题:语义鸿沟
人类眼里看到的一张照片在计算机看起来就是一大堆的数字,在理解照片上有着巨大的语义鸿沟。
挑战
- 观测点变化
- 光照
- 变形
- 遮挡
- 背景干扰
- 类内差异
一个图像分类器
def classify_image(image):
# 一些神奇的代码
return class_label
向上面那样形式的代码肯定是不会存在的。不像对于一个数字列表进行排序,没有一个明显的方法去强行写一个算法可以识别猫或者其他的类别。
曾经做过的尝试
我们先找到图片的边缘并且找到其中的边角,对于其特征进行分析从而判断是什么类别。如果采用这种方法进行分类,我们需要对所有类别的边角特征都进行分析,这种分类方法显然不适用于日常场景。
数据驱动的方法
既然上面的方法行不通,后来产生了数据驱动的方法,即使用大量的数据训练出一个分类器。主要有如下三个步骤:
- 收集一个包含图片和标签的数据集
- 使用机器学习去训练一个分类器
- 使用新的图片来评估这个分类器
第一个分类器:k最近邻
这个分类器我专门写过博客详细描写了如何实现,链接如下:
k最近邻分类器的原理和实现过程
线性分类
在后面的各种神经网络中,都是由一层一层的线性分类器堆积起来的。
参数方法:线性分类器
f
(
x
,
W
)
=
W
x
+
b
\Large f(x,W) = Wx + b
f(x,W)=Wx+b
W 权重参数 (10,3072)
x 图片数据(32,32,3),被处理为向量(3072,1)
把图片输入上面的函数,会得到10个数字分别对应着10个分类的分数,分数最高的即预测的图片标签。
举个例子来使用一下上面的函数:下面的图片有四个像素,并且有三个分类标签
从计算结果可以看到,狗的得分最高,猫的得分反而最低,这个预测是失败的,但这个例子就是线性分类器的大概工作流程。
阐述一个线性分类器
对于函数f(x,W),这到底是个什么东西?该怎么看待它?
- 这里有一个CIFAR-10训练的一个线性分类器的权重W的例子。
- 从另一个角度来看这个分类器
线性分类器的任务就是划分决策面,使得更多的图片划归到正确的标签范围里面。
线性分类器的困难情况
暂时没看懂,以后明白了再补充吧。
###########################################
TODO:
###########################################
Lecture 3: 损失函数和优化
上节课学到了线性分类器,构造一个线性分类器需要找到好的权重矩阵W,在这里有两个关键步骤:
- 定义一个可以通过训练数据使用分数定量我们错误的损失函数
- 提出一个方法有效地找到一个最小化损失的参数(优化)
损失函数
一个损失函数可以告诉我们当下的这个分类器性能如何
例如给一个数据集样例:
{
(
x
i
,
y
i
)
}
i
=
1
N
\Large \left\{ (x_i,y_i) \right\}_{i=1}^N
{(xi,yi)}i=1N
在这个数据集中
x
i
x_i
xi是图片,
y
i
y_i
yi是标签(整数)
一个数据集的损失值是每一个样例的损失的和:
L
=
1
N
∑
i
L
i
(
f
(
x
i
,
W
)
,
y
i
)
\Large L = \frac{1}{N}\sum_{i} L_i(f(x_i,W),y_i)
L=N1i∑Li(f(xi,W),yi)
其中函数
L
i
L_i
Li 有不同的实现方式,例如如下两种:
Multiclass SVM Loss
使用这种损失函数的线性分类器已经专门介绍过:
使用SVM 损失函数的线性分类器原理与实现
Softmax Classifier
使用这种损失函数的线性分类器已经专门介绍过:
使用softmax损失函数的线性分类器原理与实现
回顾
- 我们有一些 ( x , y ) (x,y) (x,y)的数据集
- 我们有一个分数函数: s = f ( x , W ) = e . g . W x s=f(x,W)\xlongequal{e.g.}Wx s=f(x,W)e.g.Wx
- 我们有一个损失函数:
L
i
=
−
l
o
g
(
e
s
y
i
∑
j
e
s
j
)
\Large L_i = -log(\frac{e^sy_i}{\sum_{j} e^sj})
Li=−log(∑jesjesyi)
L
i
=
∑
j
≠
y
i
m
a
x
(
0
,
s
j
−
s
y
i
+
1
)
\Large L_i = \sum_{ j \neq y_i}max(0,s_j-s_{y_i}+1)
Li=∑j̸=yimax(0,sj−syi+1)
L
=
1
N
∑
i
=
1
N
L
i
+
R
(
W
)
\large L = \frac{1}{N}\sum_{i=1}^NL_i+R(W)
L=N1∑i=1NLi+R(W)
优化
在我们训练线性分类器的过程中,肯定想要得到最好的权重矩阵W,使之得到最小的损失。
方法1:一个很差的方法:随机寻找
这种方法就是我们尝试很多个W,从中挑选损失值最小的。这种方法效率很低并且得到的分类器准确率不高。
方法2:跟随坡度
在一维中,导数的一个公式为:
d
f
(
x
)
d
x
=
lim
h
→
0
f
(
x
+
h
)
−
f
(
x
)
h
\large\frac{df(x)}{dx} = \lim\limits_{h\rightarrow 0}\frac{f(x+h)-f(x)}{h}
dxdf(x)=h→0limhf(x+h)−f(x)
在多个维度中,梯度是沿着每个维度(偏导数)的向量。
在任何方向上坡度是方向和梯度的点积,下降的方向是负梯度
如果我们逐个去求W的梯度,效率也太低了。于是我们使用微积分来计算解析梯度。
总结
- 数值梯度:近似,慢,容易写出来
- 解析梯度:准确,快速,容易出错
在实际的练习中总会使用解析梯度,但是会使用数值梯度来检查结果,这称为梯度检验