第四门课
第一周
三维卷积
这个的输出会是一个4×4的图像,注意是4×4×1,最后一个数不是3了。
不同的卷积核
如果你有一个
n
×
n
×
n
c
n \times n \times n_{c}
n×n×nc(通道数)的输入图像,在这个例子中就是6×6×3,这里的
n
c
n_{c}
nc就是通道数目,然后卷积上一个
f
×
f
×
n
c
f×f×n_{c}
f×f×nc,这个例子中是3×3×3,按照惯例,这个(前一个
n
c
n_{c}
nc)和这个(后一个
n
c
n_{c}
nc)必须数值相同。然后你就得到了
(
n
−
f
+
1
)
×
(
n
−
f
+
1
)
×
n
c
′
(n-f+1)×(n-f+1)×n_{c^{'}}
(n−f+1)×(n−f+1)×nc′,这里
n
c
′
n_{c^{'}}
nc′其实就是下一层的通道数,它就是你用的过滤器的个数,在我们的例子中,那就是4×4×2。我写下这个假设时,用的步幅为1,并且没有padding。如果你用了不同的步幅或者padding,那么这个
n
−
f
+
1
n-f+1
n−f+1数值会变化,
卷积网络
这就是
a
[
0
]
a^{[0]}
a[0]到
a
[
1
]
a^{[1]}
a[1]的演变过程,首先执行线性函数,然后所有元素相乘做卷积,具体做法是运用线性函数再加上偏差,然后应用激活函数ReLU。这样就通过神经网络的一层把一个6×6×3的维度
a
[
0
]
a^{[0]}
a[0]演化为一个4×4×2维度的
a
[
1
]
a^{[1]}
a[1],这就是卷积神经网络的一层。
这一层是卷积层,用 f [ l ] f^{[l]} f[l]表示过滤器大小,我们说过过滤器大小为 f × f f×f f×f,上标 [ l ] \lbrack l\rbrack [l]表示 l l l层中过滤器大小为 f × f f×f f×f。通常情况下,上标 [ l ] \lbrack l\rbrack [l]用来标记 l l l层。用 p [ l ] p^{[l]} p[l]来标记padding的数量,padding数量也可指定为一个valid卷积,即无padding。或是same卷积,即选定padding,如此一来,输出和输入图片的高度和宽度就相同了。用 s [ l ] s^{[l]} s[l]标记步幅。
这一层的输入会是某个维度的数据,表示为 n × n × n c n \times n \times n_{c} n×n×nc, n c n_{c} nc某层上的颜色通道数。
我们要稍作修改,增加上标 [ l − 1 ] \lbrack l -1\rbrack [l−1],即 n [ l − 1 ] × n [ l − 1 ] × n c [ l − 1 ] n^{\left\lbrack l - 1 \right\rbrack} \times n^{\left\lbrack l -1 \right\rbrack} \times n_{c}^{\left\lbrack l - 1\right\rbrack} n[l−1]×n[l−1]×nc[l−1],因为它是上一层的激活值。
此例中,所用图片的高度和宽度都一样,但它们也有可能不同,所以分别用上下标 H H H和 W W W来标记,即 n H [ l − 1 ] × n W [ l − 1 ] × n c [ l − 1 ] n_{H}^{\left\lbrack l - 1 \right\rbrack} \times n_{W}^{\left\lbrack l - 1 \right\rbrack} \times n_{c}^{\left\lbrack l - 1\right\rbrack} nH[l−1]×nW[l−1]×nc[l−1]。那么在第 l l l层,图片大小为 n H [ l − 1 ] × n W [ l − 1 ] × n c [ l − 1 ] n_{H}^{\left\lbrack l - 1 \right\rbrack} \times n_{W}^{\left\lbrack l - 1 \right\rbrack} \times n_{c}^{\left\lbrack l - 1\right\rbrack} nH[l−1]×nW[l−1]×nc[l−1], l l l层的输入就是上一层的输出,因此上标要用 [ l − 1 ] \lbrack l - 1\rbrack [l−1]。神经网络这一层中会有输出,它本身会输出图像。其大小为 n H [ l ] × n W [ l ] × n c [ l ] n_{H}^{[l]} \times n_{W}^{[l]} \times n_{c}^{[l]} nH[l]×nW[l]×nc[l],这就是输出图像的大小。
前面我们提到过,这个公式给出了输出图片的大小,至少给出了高度和宽度, ⌊ n + 2 p − f s + 1 ⌋ \lfloor\frac{n+2p - f}{s} + 1\rfloor ⌊sn+2p−f+1⌋(注意:( n + 2 p − f s + 1 ) \frac{n + 2p - f}{s} +1) sn+2p−f+1)直接用这个运算结果,也可以向下取整)。在这个新表达式中, l l l层输出图像的高度,即 n H [ l ] = ⌊ n H [ l − 1 ] + 2 p [ l ] − f [ l ] s [ l ] + 1 ⌋ n_{H}^{[l]} = \lfloor\frac{n_{H}^{\left\lbrack l - 1 \right\rbrack} +2p^{[l]} - f^{[l]}}{s^{[l]}} +1\rfloor nH[l]=⌊s[l]nH[l−1]+2p[l]−f[l]+1⌋,同样我们可以计算出图像的宽度,用 W W W替换参数 H H H,即 n W [ l ] = ⌊ n W [ l − 1 ] + 2 p [ l ] − f [ l ] s [ l ] + 1 ⌋ n_{W}^{[l]} = \lfloor\frac{n_{W}^{\left\lbrack l - 1 \right\rbrack} +2p^{[l]} - f^{[l]}}{s^{[l]}} +1\rfloor nW[l]=⌊s[l]nW[l−1]+2p[l]−f[l]+1⌋,公式一样,只要变化高度和宽度的参数我们便能计算输出图像的高度或宽度。这就是由 n H [ l − 1 ] n_{H}^{\left\lbrack l - 1 \right\rbrack} nH[l−1]推导 n H [ l ] n_{H}^{[l]} nH[l]以及 n W [ l − 1 ] n_{W}^{\left\lbrack l - 1\right\rbrack} nW[l−1]推导 n W [ l ] n_{W}^{[l]} nW[l]的过程。
输出通道数量就是输入通道数量,所以过滤器维度等于
f
[
l
]
×
f
[
l
]
×
n
c
[
l
−
1
]
f^{[l]} \times f^{[l]} \times n_{c}^{\left\lbrack l - 1 \right\rbrack}
f[l]×f[l]×nc[l−1]。
应用偏差和非线性函数之后,这一层的输出等于它的激活值
a
[
l
]
a^{[l]}
a[l],也就是这个维度(输出维度)。
a
[
l
]
a^{[l]}
a[l]是一个三维体,即
n
H
[
l
]
×
n
W
[
l
]
×
n
c
[
l
]
n_{H}^{[l]} \times n_{W}^{[l]} \times n_{c}^{[l]}
nH[l]×nW[l]×nc[l]。当你执行批量梯度下降或小批量梯度下降时,如果有
m
m
m个例子,就是有
m
m
m个激活值的集合,那么输出
A
[
l
]
=
m
×
n
H
[
l
]
×
n
W
[
l
]
×
n
c
[
l
]
A^{[l]} = m \times n_{H}^{[l]} \times n_{W}^{[l]} \times n_{c}^{[l]}
A[l]=m×nH[l]×nW[l]×nc[l]。如果采用批量梯度下降,变量的排列顺序如下,首先是索引和训练示例,然后是其它三个变量。
该如何确定权重参数,即参数W呢?过滤器的维度已知,为 f [ l ] × f [ l ] × n c [ l − 1 ] f^{[l]} \times f^{[l]} \times n_{c}^{[l - 1]} f[l]×f[l]×nc[l−1],这只是一个过滤器的维度,有多少个过滤器,这( n c [ l ] n_{c}^{[l]} nc[l])是过滤器的数量,权重也就是所有过滤器的集合再乘以过滤器的总数量,即 f [ l ] × f [ l ] × n c [ l − 1 ] × n c [ l ] f^{[l]} \times f^{[l]} \times n_{c}^{[l - 1]} \times n_{c}^{[l]} f[l]×f[l]×nc[l−1]×nc[l],损失数量L就是 l l l层中过滤器的个数。
最后我们看看偏差参数,每个过滤器都有一个偏差参数,它是一个实数。偏差包含了这些变量,它是该维度上的一个向量。后续课程中我们会看到,为了方便,偏差在代码中表示为一个1×1×1× n c [ l ] n_{c}^{[l]} nc[l]的四维向量或四维张量。
残差网络
ResNet
在残差网络中有一点变化,我们将
a
[
l
]
a^{[l]}
a[l]直接向后,拷贝到神经网络的深层,在ReLU非线性激活函数前加上
a
[
l
]
a^{[l]}
a[l],这是一条捷径。
a
[
l
]
a^{[l]}
a[l]的信息直接到达神经网络的深层,不再沿着主路径传递,这就意味着最后这个等式(
a
[
l
+
2
]
=
g
(
z
[
l
+
2
]
)
a^{\left\lbrack l + 2 \right\rbrack} = g(z^{\left\lbrack l + 2 \right\rbrack})
a[l+2]=g(z[l+2]))去掉了,取而代之的是另一个ReLU非线性函数,仍然对
z
[
l
+
2
]
z^{\left\lbrack l + 2 \right\rbrack}
z[l+2]进行
g
g
g函数处理,但这次要加上
a
[
l
]
a^{[l]}
a[l],即:
a
[
l
+
2
]
=
g
(
z
[
l
+
2
]
+
a
[
l
]
)
\ a^{\left\lbrack l + 2 \right\rbrack} = g\left(z^{\left\lbrack l + 2 \right\rbrack} + a^{[l]}\right)
a[l+2]=g(z[l+2]+a[l]),也就是加上的这个
a
[
l
]
a^{[l]}
a[l]产生了一个残差块。
inception 网络
基本思想是Inception网络不需要人为决定使用哪个过滤器或者是否需要池化,而是由网络自行确定这些参数,你可以给网络添加这些参数的所有可能值,然后把这些输出连接起来,让网络自己学习它需要什么样的参数,采用哪些过滤器组合。
不难发现,我所描述的Inception层有一个问题,就是计算成本
改进
这里还有另外一种架构,其输入为28×28×192,输出为28×28×32。其结果是这样的,对于输入层,使用1×1卷积把输入值从192个通道减少到16个通道。然后对这个较小层运行5×5卷积,得到最终输出。请注意,输入和输出的维度依然相同,输入是28×28×192,输出是28×28×32,和上一页的相同。但我们要做的就是把左边这个大的输入层压缩成这个较小的的中间层,它只有16个通道,而不是192个。
有时候这被称为瓶颈层,瓶颈通常是某个对象最小的部分,假如你有这样一个玻璃瓶,这是瓶塞位置,瓶颈就是这个瓶子最小的部分。
第三周
目标定位
如果你还想定位图片中汽车的位置,该怎么做呢?我们可以让神经网络多输出几个单元,输出一个边界框。具体说就是让神经网络再多输出4个数字,标记为 b x b_{x} bx, b y b_{y} by, b h b_{h} bh和 b w b_{w} bw,这四个数字是被检测对象的边界框的参数化表示。
我们先来约定本周课程将使用的符号表示,图片左上角的坐标为 ( 0 , 0 ) (0,0) (0,0),右下角标记为 ( 1 , 1 ) (1,1) (1,1)。要确定边界框的具体位置,需要指定红色方框的中心点,这个点表示为( b x b_{x} bx, b y b_{y} by),边界框的高度为 b h b_{h} bh,宽度为 b w b_{w} bw。
因此训练集不仅包含神经网络要预测的对象分类标签,还要包含表示边界框的这四个数字,接着采用监督学习算法,输出一个分类标签,还有四个参数值,从而给出检测对象的边框位置。
注意上述使用了bounding box尺度归一化
下面我再具体讲讲如何为监督学习任务定义目标标签
y
y
y。
请注意,这有四个分类,神经网络输出的是这四个数字和一个分类标签,或分类标签出现的概率。目标标签
y
y
y的定义如下:
y
=
[
p
c
b
x
b
y
b
h
b
w
c
1
c
2
c
3
]
y= \ \begin{bmatrix} p_{c} \\ b_{x} \\ b_{y} \\ b_{h} \\ b_{w} \\ c_{1} \\ c_{2}\\ c_{3} \\\end{bmatrix}
y= ⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡pcbxbybhbwc1c2c3⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
它是一个向量,第一个组件 p c p_{c} pc表示是否含有对象,如果对象属于前三类(行人、汽车、摩托车),则 p c = 1 p_{c}= 1 pc=1,如果是背景,则图片中没有要检测的对象,则 p c = 0 p_{c} =0 pc=0。我们可以这样理解 p c p_{c} pc,它表示被检测对象属于某一分类的概率,背景分类除外。
如果检测到对象,就输出被检测对象的边界框参数 b x b_{x} bx、 b y b_{y} by、 b h b_{h} bh和 b w b_{w} bw。最后,如果存在某个对象,那么 p c = 1 p_{c}=1 pc=1,同时输出 c 1 c_{1} c1、 c 2 c_{2} c2和 c 3 c_{3} c3,表示该对象属于1-3类中的哪一类,是行人,汽车还是摩托车。鉴于我们所要处理的问题,我们假设图片中只含有一个对象,所以针对这个分类定位问题,图片最多只会出现其中一个对象。
如果图片中没有检测对象呢?如果训练样本是这样一张图片呢?
这种情况下,
p
c
=
0
p_{c} =0
pc=0,
y
y
y的其它参数将变得毫无意义,这里我全部写成问号,表示“毫无意义”的参数,因为图片中不存在检测对象,所以不用考虑网络输出中边界框的大小,也不用考虑图片中的对象是属于
c
1
c_{1}
c1、
c
2
c_{2}
c2和
c
3
c_{3}
c3中的哪一类。针对给定的被标记的训练样本,不论图片中是否含有定位对象,构建输入图片
x
x
x和分类标签
y
y
y的具体过程都是如此。这些数据最终定义了训练集。
我们介绍一下神经网络的损失函数,其参数为类别
y
y
y和网络输出
y
^
\hat{y}
y^,如果采用平方误差策略,则
L
(
y
^
,
y
)
=
(
y
1
^
−
y
1
)
2
+
(
y
2
^
−
y
2
)
2
+
…
(
y
8
^
−
y
8
)
2
L\left(\hat{y},y \right) = \left( \hat{y_1} - y_{1} \right)^{2} + \left(\hat{y_2} - y_{2}\right)^{2} + \ldots\left( \hat{y_8} - y_{8}\right)^{2}
L(y^,y)=(y1^−y1)2+(y2^−y2)2+…(y8^−y8)2,损失值等于每个元素相应差值的平方和。
另一种情况是,
y
1
=
0
y_{1} = 0
y1=0,也就是
p
c
=
0
p_{c} = 0
pc=0,损失值是
(
y
1
^
−
y
1
)
2
\left(\hat{y_1} - y_{1}\right)^{2}
(y1^−y1)2,因为对于这种情况,我们不用考虑其它元素,只需要关注神经网络输出
p
c
p_{c}
pc的准确度。
回顾一下,当
y
1
=
1
y_{1} =1
y1=1时,也就是这种情况(编号1),平方误差策略可以减少这8个元素预测值和实际输出结果之间差值的平方。如果
y
1
=
0
y_{1}=0
y1=0,
y
y
y 矩阵中的后7个元素都不用考虑(编号2),只需要考虑神经网络评估
y
1
y_{1}
y1(即
p
c
p_{c}
pc)的准确度。
注意
y
1
y_1
y1就是
p
c
p_c
pc
实际应用中,你可以不对
c
1
c_{1}
c1、
c
2
c_{2}
c2、
c
3
c_{3}
c3和softmax激活函数应用对数损失函数,并输出其中一个元素值,
通常做法是对边界框坐标应用平方差或类似方法,对
p
c
p_{c}
pc应用逻辑回归函数,甚至采用平方预测误差也是可以的。
卷积的滑动窗口实现
为了构建滑动窗口的卷积应用,首先要知道如何把神经网络的全连接层转化成卷积层。
如何把这些全连接层转化为卷积层,画一个这样的卷积网络,它的前几层和之前的一样,而对于下一层,也就是这个全连接层,我们可以用5×5的过滤器来实现,数量是400个(编号1所示),输入图像大小为5×5×16,用5×5的过滤器对它进行卷积操作,过滤器实际上是5×5×16,因为在卷积过程中,过滤器会遍历这16个通道,所以这两处的通道数量必须保持一致,输出结果为1×1。假设应用400个这样的5×5×16过滤器,输出维度就是1×1×400,我们不再把它看作一个含有400个节点的集合,而是一个1×1×400的输出层。从数学角度看,它和全连接层是一样的,因为这400个节点中每个节点都有一个5×5×16维度的过滤器,所以每个值都是上一层这些5×5×16激活值经过某个任意线性函数的输出结果。
最后经由1×1过滤器的处理,得到一个softmax激活值,通过卷积网络,我们最终得到这个1×1×4的输出层,而不是这4个数字(编号3所示)。
以上就是用卷积层代替全连接层的过程,结果这几个单元集变成了1×1×400和1×1×4的维度。
如何通过卷积实现滑动窗口对象检测算法
假设输入给卷积网络的图片大小是14×14×3,测试集图片是16×16×3
现在给这个输入图片加上黄色条块,在最初的滑动窗口算法中,你会把这片蓝色区域输入卷积网络(红色笔标记)生成0或1分类。接着滑动窗口,步幅为2个像素,向右滑动2个像素,将这个绿框区域输入给卷积网络,运行整个卷积网络,得到另外一个标签0或1。继续将这个橘色区域输入给卷积网络,卷积后得到另一个标签,最后对右下方的紫色区域进行最后一次卷积操作。我们在这个16×16×3的小图像上滑动窗口,卷积网络运行了4次,于是输出了了4个标签。
结果发现,这4次卷积操作中很多计算都是重复的
总结一下滑动窗口的实现过程,在图片上剪切出一块区域,假设它的大小是14×14,把它输入到卷积网络。继续输入下一块区域,大小同样是14×14,重复操作,直到某个区域识别到汽车。
但是正如在前一页所看到的,我们不能依靠连续的卷积操作来识别图片中的汽车,比如,我们可以对大小为28×28的整张图片进行卷积操作,一次得到所有预测值,如果足够幸运,神经网络便可以识别出汽车的位置。
以上就是在卷积层上应用滑动窗口算法的内容,它提高了整个算法的效率。不过这种算法仍然存在一个缺点,就是边界框的位置可能不够准确
overfeat没懂