> For the complete documentation index, see [llms.txt](https://baozoulin.gitbook.io/dl-ai-special-notebook/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://baozoulin.gitbook.io/dl-ai-special-notebook/course4/di-er-zhou-shen-du-juan-ji-wang-luo-shi-li-tan-jiu-deepconvolutionalmodelscasestudiescourse4.md).

# 第二周 深度卷积网络：实例探究（Deep convolutional models: case studies）

## 2.1 经典网络（Classic networks）

### **LeNet-5**

**LeNet-5**可以识别图中的手写数字，是针对灰度图片训练的，所以图片的大小只有32×32×1。该LeNet模型总共包含了大约6万个参数，典型的LeNet-5结构包含CONV layer，POOL layer和FC layer，顺序一般是CONV layer->POOL layer->CONV layer->POOL layer->FC layer->FC layer->OUTPUT layer，即$$\hat y$$：

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/5e59b38c9b2942a407b49da84677dae9.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/5e59b38c9b2942a407b49da84677dae9.png)

随着网络越来越深，图像的高度和宽度在缩小，从最初的32×32缩小到28×28，再到14×14、10×10，最后只有5×5，通道数量一直在增加，从1增加到6个，再到16个

这个神经网络中还有一种模式就是一个或多个卷积层后面跟着一个池化层，然后又是若干个卷积层再接一个池化层，然后是全连接层，最后是输出

### **AlexNet**

**AlexNet**包含约6000万个参数。当用于训练图像和数据集时，**AlexNet**能够处理非常相似的基本构造模块，这些模块往往包含着大量的隐藏单元或数据，**AlexNet**比**LeNet**表现更为出色的另一个原因是它使用了**ReLu**激活函数

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/92575493ecd20003b0b76ac51de0efbb.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/92575493ecd20003b0b76ac51de0efbb.png)

### **VGG-16**

**VGG**，也叫作**VGG-16**网络。**VGG-16**网络没有那么多超参数，是一种只需要专注于构建卷积层的简单网络。首先用3×3，步幅为1的过滤器构建卷积层，**padding**参数为**same**卷积中的参数。然后用一个2×2，步幅为2的过滤器构建最大池化层。**VGG**网络的一大优点是简化了神经网络结构

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/a645bff2623ba6f30f01fbc6e3149484.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/a645bff2623ba6f30f01fbc6e3149484.png)

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/781ddc74bcc8da430c99b196d0c4c6d4.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/781ddc74bcc8da430c99b196d0c4c6d4.png)

假设要识别这个图像，在最开始的两层用64个3×3的过滤器对输入图像进行卷积，输出结果是224×224×64，因为使用了**same**卷积，通道数量也一样

接下来创建一个池化层，池化层将输入图像进行压缩，减少到112×112×64。然后又是若干个卷积层，使用128个过滤器，以及一些**same**卷积，输出112×112×128。然后进行池化，池化后的结果是56×56×128。再用256个相同的过滤器进行三次卷积操作，然后再池化，然后再卷积三次，再池化。如此进行几轮操作后，将最后得到的7×7×512的特征图进行全连接操作，得到4096个单元，然后进行**softmax**激活，输出从1000个对象中识别的结果

![](https://baozou.gitbooks.io/neural-networks-and-deep-learning/content/assets/20180116225416971.png)

**VGG-16**的数字16指在这个网络中有13个卷积层和3个全链接层

![](https://baozou.gitbooks.io/neural-networks-and-deep-learning/content/assets/v2-266bf05d27220b875849507a98703791_hd.jpg)

总共包含约1.38亿个参数，这种网络结构很规整，都是几个卷积层后面跟着可以压缩图像大小的池化层，池化层缩小图像的高度和宽度。同时，卷积层的过滤器数量变化存在一定的规律，由64翻倍变成128，再到256和512。主要缺点是需要训练的特征数量非常巨大

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/0a29aeae65a311c56675ad8f1fec2824.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/0a29aeae65a311c56675ad8f1fec2824.png)

随着网络的加深，图像的高度和宽度都在以一定的规律不断缩小，每次池化后刚好缩小一半，而通道数量在不断增加，而且刚好也是在每组卷积操作后增加一倍。即图像缩小的比例和通道数增加的比例是有规律的

## 2.2 残差网络（Residual Networks (ResNets)）

人为地让神经网络某些层跳过下一层神经元的连接，隔层相连，弱化每层之间的强联系，这种神经网络被称为**Residual Networks(ResNets)**

Residual Networks由许多隔层相连的神经元子模块组成，称之为Residual block（残差块）。单个Residual block的结构如下图所示：

[\
![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/f0a8471f869d8062ba59598c418da7fb.png)](https://legacy.gitbook.com/book/baozou/neural-networks-and-deep-learning/edit#)

紫色线是skip connection（跳跃连接），直接建立$$a^{\[l]}$$与$$a^{\[l+2]}$$之间的隔层联系。相应的表达式如下：

$$
z^{\[l+1]}=W^{\[l+1]}a^{\[l]}+b^{\[l+1]}
$$

$$
a^{\[l+1]}=g(z^{\[l+1]})
$$

$$
z^{\[l+2]}=W^{\[l+2]}a^{\[l+1]}+b^{\[l+2]}
$$

$$
a^{\[l+2]}=g(z^{\[l+2]}+a^{\[l]})
$$

$$a^{\[l]}$$直接隔层与下一层的线性输出相连，$$a^{\[l]}$$插入的时机是在线性激活之后，**ReLU**激活之前，与$$z^{\[l+2]}$$共同通过激活函数（ReLU）输出$$a^{\[l+2]}$$

这种模型结构对于训练非常深的神经网络效果很好。非Residual Networks称为Plain Network

[\
![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/131e538bb527859430280becd65b049b.png)](https://legacy.gitbook.com/book/baozou/neural-networks-and-deep-learning/edit#)

> Residual Network的结构

[\
![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/48bded15cca17581084e3fe0853673b5.png)](https://legacy.gitbook.com/book/baozou/neural-networks-and-deep-learning/edit#)

> Plain Network

与Plain Network相比，Residual Network能够训练更深层的神经网络，有效避免发生发生梯度消失和梯度爆炸

* 随着神经网络层数增加，Plain Network实际性能会变差，training error甚至会变大
* Residual Network的训练效果却很好，training error一直呈下降趋势

[\
![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/6077958a616425d76284cecb43c2f458.png)](https://legacy.gitbook.com/book/baozou/neural-networks-and-deep-learning/edit#)

## 2.3 残差网络为什么有用？（Why ResNets work?）

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/e1106db40c78c2e384305d6474c40d69.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/e1106db40c78c2e384305d6474c40d69.png)

输入$$X$$ 经过一个大型神经网络输出激活值$$a^{\[l]}$$，再给这个网络额外添加两层作为一个**ResNets**块，输出$$a^{\left\lbrack l + 2 \right\rbrack}$$：

$$
a^{\[l+2]}=g(z^{\[l+2]}+a^{\[l]})=g(W^{\[l+2]}a^{\[l+1]}+b^{\[l+2]}+a^{\[l]})
$$

假设在整个网络中使用**ReLU**激活函数，所以激活值都大于等于0，包括输入$$X$$的非零异常值。因为**ReLU**激活函数输出的数字要么是0，要么是正数

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/f60f5ca514d4bad1288fc7cbd666dd99.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/f60f5ca514d4bad1288fc7cbd666dd99.png)

如果使用L2正则化或权重衰减，会压缩$$W^{\left\lbrack l + 2\right\rbrack}$$的值。$$W$$是关键项，如果$$W^{\left\lbrack l + 2 \right\rbrack} = 0$$，方便起见，假设$$b^{\left\lbrack l + 2 \right\rbrack} = 0$$，假定使用ReLU激活函数，并且所有激活值都是非负的，$$g\left(a^{\[l]} \right)$$是应用于非负数的ReLU函数，所以$$a^{\[l+2]} =a^{\[l]}$$

可以看出，即使发生了梯度消失，$$W^{\[l+2]}\approx0$$，$$b^{\[l+2]}\approx0$$，也能直接建立$$a^{\[l+2]}$$与$$a^{\[l]}$$的线性关系，且$$a^{\[l+2]}=a^{\[l]}$$，这就是identity function（恒等函数）。$$a^{\[l]}$$直接连到$$a^{\[l+2]}$$，相当于直接忽略了$$a^{\[l]}$$之后的这两层神经层。这样看似很深的神经网络，由于许多Residual blocks的存在，弱化削减了某些神经层之间的联系，实现隔层线性传递，而不是一味追求非线性关系，模型本身也就能“容忍”更深层的神经网络了。从性能上来说，这两层额外的Residual blocks也不会降低Big NN的性能，所以给大型神经网络增加两层，不论是把残差块添加到神经网络的中间还是末端位置，都不会影响网络的表现

如果Residual blocks确实能训练得到非线性关系，那么也会忽略short cut，跟Plain Network起到同样的效果

如果Residual blocks中$$a^{\[l+2]}$$与$$a^{\[l]}$$的维度不同，可以引入矩阵$$W\_s$$与$$a^{\[l]}$$相乘，使得$$W\_s\*a^{\[l]}$$的维度与$$a^{\[l+2]}$$一致

[\
![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/cefcaece17927e14eb488cb52d99aaef.png)](https://legacy.gitbook.com/book/baozou/neural-networks-and-deep-learning/edit#)

参数矩阵$$W\_s$$有来两种方法得到：

* 将$$W\_s$$作为学习参数，通过模型训练得到
* 固定$$W\_s$$值（类似单位矩阵），不需要训练，$$W\_s$$与$$a^{\[l]}$$的乘积仅使得$$a^{\[l]}$$截断或者补零

CNN中ResNets的结构：

[\
![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/70062fa97916ab79c7ad37282ba1a5f4.png)](https://legacy.gitbook.com/book/baozou/neural-networks-and-deep-learning/edit#)

ResNets同类型层之间，例如CONV layers，大多使用same类型，这也解释了添加项$$z^{\[l+2]}+a^{\[l]}$$（维度相同所以能够相加）。如果是不同类型层之间的连接，例如CONV layer与POOL layer之间，如果维度不同，则引入矩阵$$W\_s$$

## 2.4 网络中的网络以及 1×1 卷积（Network in Network and 1×1 convolutions）

如果是一张6×6×32的图片，使用1×1过滤器进行卷积效果更好。1×1卷积所实现的功能是遍历这36个单元格，计算左图中32个数字和过滤器中32个数字的元素积之和，然后应用**ReLU**非线性函数

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/7522d4cbc42b7db1c5a05bc461106590.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/7522d4cbc42b7db1c5a05bc461106590.png)

1×1×32过滤器中的32个数字可以理解为一个神经元的输入是32个数字，这32个数字具有不同通道，乘以32个权重（将过滤器中的32个数理解为权重），然后应用**ReLU**非线性函数，输出相应的结果

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/f97e6c31c2b27a2d4ef9610b8f32b335.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/f97e6c31c2b27a2d4ef9610b8f32b335.png)

如果过滤器是多个，就好像有多个输入单元，其输入内容为一个切片上所有数字，输出结果是6×6×#filters

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/70eba35d0705dc681c40f09a0926061a.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/70eba35d0705dc681c40f09a0926061a.png)

1×1卷积可以从根本上理解为对这32个不同的位置都应用一个全连接层，全连接层的作用是输入32个数字（过滤器数量标记为$$n\_{C}^{\left\lbrack l + 1\right\rbrack}$$，在这36个单元上重复此过程）,输出结果是6×6×#filters（过滤器数量），以便在输入层上实施一个非平凡（**non-trivial**）计算

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/46698c486da9ae184532d773716c77e9.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/46698c486da9ae184532d773716c77e9.png)

这种方法通常称为1×1卷积，也被称为**Network in Network**

假设一个28×28×192的输入层，如果通道数量很大，可以用32个大小为1×1×192的过滤器，使输出层为28×28×32，这就是压缩通道数（$$n\_{C}$$）的方法

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/49a16fdc10769a86355911f9e324c728.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/49a16fdc10769a86355911f9e324c728.png)

如果想保持通道数192不变，也是可行的，1×1卷积只是添加了非线性函数，也可以让网络学习更复杂的函数

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/70f3b26fe86c3ec2507b8bb85be8d30c.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/70f3b26fe86c3ec2507b8bb85be8d30c.png)

1×1卷积层给神经网络添加了一个非线性函数，从而减少或保持输入层中的通道数量不变，也可以增加通道数量

## 2.5 谷歌 Inception 网络简介（Inception network motivation）

**Inception**网络或**Inception**层的作用是代替人工来确定卷积层中的过滤器类型，或者确定是否需要创建卷积层或池化层

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/99f8fc7dbe7cd0726f5271aae11b9872.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/99f8fc7dbe7cd0726f5271aae11b9872.png)

基本思想是**Inception**网络在单层网络上可以使用多个不同尺寸的filters，进行same convolutions，把各filter下得到的输出拼接起来。还可以将CONV layer与POOL layer混合，同时实现各种效果，但是要注意使用same pool。Inception Network不需要人为决定使用哪个过滤器或者是否需要池化，它使用不同尺寸的filters并将CONV和POOL混合起来，将所有功能输出组合拼接，再由神经网络本身去学习参数并选择最好的模块

Inception Network在提升性能的同时，会带来计算量大的问题：

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/27894eae037f4fd859d33ebdda1cac9a.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/27894eae037f4fd859d33ebdda1cac9a.png)

乘法运算的总次数为每个输出值所需要执行的乘法运算次数（5×5×192）乘以输出值个数（28×28×32），结果等于1.2亿。

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/5b3df2904b9d8dc51bd99ccb45ac9f5b.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/5b3df2904b9d8dc51bd99ccb45ac9f5b.png)

为此，引入1x1 Convolutions来减少计算量，对于输入层，使用1×1卷积把输入值从192个通道减少到16个通道。然后对这个较小层运行5×5卷积，得到最终输出

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/1fec66d984a3c8c47ff459775d411e71.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/1fec66d984a3c8c47ff459775d411e71.png)

把该1x1 Convolution称为“瓶颈层”（bottleneck layer），瓶颈层是网络中最小的部分，即先缩小网络，然后再扩大

引入bottleneck layer之后，第一个卷积层计算成本：1×1×192×输出28×28×16，相乘结果约等于240万，第二个卷积层的计算成本是：28×28×32×5×5×16，计算结果为1000万，总次数是1204万，计算成本从1.2亿下降到了原来的十分之一

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/7d160f6eab22e4b9544b28b44da686a6.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/7d160f6eab22e4b9544b28b44da686a6.png)

总结：

* 如果在构建神经网络层的时候，不想决定池化层是使用1×1，3×3还是5×5的过滤器，**Inception**模块是最好的选择。可以应用各种类型的过滤器，只需要把输出连接起来
* 计算成本问题，通过使用1×1卷积来构建瓶颈层，大大降低计算成本

只要合理构建瓶颈层，既可以显著缩小表示层规模，又不会降低网络性能，从而节省了计算

## 2.6 Inception 网络（Inception network）

引入1x1 Convolution后的Inception module如下图所示：

![](https://baozou.gitbooks.io/neural-networks-and-deep-learning/content/assets/490import.png)

**Inception**模块会将之前层的激活或者输出作为它的输入，为了能在最后将这些输出都连接起来，会使用**same**类型的**padding**来池化，使得输出的高和宽依然是28×28，这样才能将它与其他输出连接起来。如果进行了最大池化，即便用了**same padding**，3×3的过滤器，**stride**为1，其输出将会是28×28×192，其通道数与输入（通道数）相同。要做的是再加上一个1×1的卷积层，将通道的数量缩小到28×28×32，避免了最后输出时，池化层占据所有的通道

最后把得到的各个层的通道都加起来，得到一个28×28×256的输出。这就是一个**Inception**模块

**Inception**网络只是很多在不同的位置重复组成的网络：

![](https://baozou.gitbooks.io/neural-networks-and-deep-learning/content/assets/492import.png)

中间隐藏层也可以作为输出层Softmax，确保了即便是隐藏单元和中间层也参与了特征计算，也能预测图片的分类，起到一种调整的效果，有利于防止发生过拟合

## 2.7 迁移学习（Transfer Learning）

训练集很小的情况：

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/8f0e69f085991cfc74726983418f6569.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/8f0e69f085991cfc74726983418f6569.png)

建议：从网上下载一些神经网络开源的实现，不仅把代码下载下来，也把权重下载下来。然后去掉**Softmax**层，创建自己的**Softmax**单元，用来输出**Tigger**、**Misty**和**neither**三个类别。把所有的层看作是冻结的，冻结网络中所有层的参数，只需要训练和**Softmax**层有关的参数。这个**Softmax**层有三种可能的输出，**Tigger**、**Misty**或者**Neither**。

通过使用其他人预训练的权重，很可能得到很好的性能，即使只有一个小的数据集。大多数深度学习框架会有`trainableParameter=0`的参数，对于前面的层，可以设置这个参数。为了不训练这些权重，会有`freeze=1`的参数。只需要训练**softmax**层的权重，把前面这些层的权重都冻结

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/ac520bf9e9facfc026db46b187b513bd.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/ac520bf9e9facfc026db46b187b513bd.png)

由于前面的层都冻结了，相当于一个固定的函数，因此不需要改变和训练它，取输入图像$$X$$，然后把它映射到**softmax**前一层的激活函数。能加速训练的技巧是如果先计算这一层（紫色箭头标记），计算特征或者激活值，然后把它们存到硬盘里。所做的就是用这个固定的函数，在这个神经网络的前半部分（**softmax**层之前的所有层视为一个固定映射），取任意输入图像$$X$$，然后计算它的某个特征向量，这样训练的就是一个很浅的**softmax**模型，用这个特征向量来做预测。对计算有用的一步就是对训练集中所有样本的这一层的激活值进行预计算，然后存储到硬盘里，在此之上训练**softmax**分类器。存储到硬盘或者说预计算方法的优点是不需要每次遍历训练集再重新计算这个激活值

更大的训练集：应该冻结更少的层，然后训练后面的层。如果输出层的类别不同，那么需要构建自己的输出单元，**Tigger**、**Misty**或者**Neither**三个类别。可以取后面几层的权重，用作初始化，然后从这里开始梯度下降

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/e7079af956d884d6184c4bde62271175.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/e7079af956d884d6184c4bde62271175.png)

也可以直接去掉这几层，换成自己的隐藏单元和**softmax**输出层，如果有越来越多的数据，那么需要冻结的层数就越少，能够训练的层数就越多。如果有一个更大的数据集，那么不要单单训练一个**softmax**单元，而是考虑训练中等大小的网络，包含最终要用的网络的后面几层

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/7cf0e18b739684106548cbbf0c1dd500.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/7cf0e18b739684106548cbbf0c1dd500.png)

如果有大量数据：应该做的就是用开源的网络和它的权重，把所有的权重当作初始化，然后训练整个网络

如果有越多的标定的数据，可以训练越多的层。极端情况下，可以用下载的权重只作为初始化，用它们来代替随机初始化，接着用梯度下降训练，更新网络所有层的所有权重

## 2.8 数据扩充（Data augmentation）

当下计算机视觉的主要问题是没有办法得到充足的数据

最简单的数据扩充方法就是垂直镜像对称

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/f92337ae2e50a0896d42d45cc7951e43.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/f92337ae2e50a0896d42d45cc7951e43.png)

另一个经常使用的技巧是随机裁剪，给定一个数据集，然后开始随机裁剪，得到不同的图片放在数据集中，随机裁剪并不是一个完美的数据扩充的方法，如果随机裁剪的那一部分（红色方框标记部分，编号4）看起来不像猫。但在实践中，这个方法还是很实用的，随机裁剪构成了很大一部分的真实图片

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/709aa552b6a5f4715620047bacf64753.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/709aa552b6a5f4715620047bacf64753.png)

也可以使用旋转，剪切（仅水平或垂直坐标发生变化）图像，扭曲变形，引入很多形式的局部弯曲等等，但在实践中太复杂所以使用的很少

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/e7e2d497b751f798e77e1b040ebbf358.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/e7e2d497b751f798e77e1b040ebbf358.png)

彩色转换：给**R**、**G**和**B**三个通道上加上不同的失真值

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/a5bcde6f0d2c2326be700c0ca441c934.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/a5bcde6f0d2c2326be700c0ca441c934.png)

实践中对**R**、**G**和**B**的变化是基于某些分布，改变可能很小，**R**、**G**和**B**的值是根据某种概率分布来决定，这样会使得学习算法对照片的颜色更改更具鲁棒性

对**R、G和B**有不同的采样方式，其中一种影响颜色失真的算法是**PCA**，即主成分分析，**PCA**颜色增强的大概含义是，如果图片呈现紫色，即主要含有红色和蓝色，绿色很少，然后**PCA**颜色增强算法就会对红色和蓝色增减很多，绿色变化相对少一点，所以使总体的颜色保持一致

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/d69cfc9648f3a37eede074bd28c74c0d.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/d69cfc9648f3a37eede074bd28c74c0d.png)

如果有特别大的训练数据，可以使用**CPU**线程，不停的从硬盘中读取数据，用**CPU**线程来实现失真变形，可以是随机裁剪、颜色变化，或者是镜像

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/2d9b9ca15ce25598d229470494d796ee.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/2d9b9ca15ce25598d229470494d796ee.png)

同时**CPU**线程持续加载数据，然后实现任意失真变形，从而构成批数据或者最小批数据，这些数据持续的传输给其他线程或者其他的进程，然后开始训练，可以在**CPU**或者**GPU**上实现一个大型网络的训练

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/5ee17d350497cb8cf52881f14cb0d9e8.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/5ee17d350497cb8cf52881f14cb0d9e8.png)

常用的实现数据扩充的方法是使用一个线程或者是多线程来加载数据，实现变形失真，然后传给其他的线程或者其他进程，来训练编号2和这个编号1，可以并行实现

在数据扩充过程中也有一些超参数，比如说颜色变化了多少，以及随机裁剪的时候使用的参数

## 2.9 计算机视觉现状（The state of computer vision）

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/7e51335f705120b35fa4ed5444ec5cda.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/7e51335f705120b35fa4ed5444ec5cda.png)

大部分机器学习问题是介于少量数据和大量数据范围之间的。

* 语音识别有很大数量的数据
* 虽然现在图像识别或图像分类方面有相当大的数据集，但因为图像识别是一个复杂的问题，通过分析像素并识别出它是什么，即使在线数据集非常大，如超过一百万张图片，仍然希望能有更多的数据
* 物体检测拥有的数据更少
* 图像识别是如何看图片的问题，并且告诉你这张图是不是猫，而对象检测则是看一幅图，画一个框，告诉你图片里的物体，比如汽车等等。因为获取边框的成本比标记对象的成本更高，所以进行对象检测的数据往往比图像识别数据要少

当有很多数据时，倾向于使用更简单的算法和更少的手工工程，只要有一个大型的神经网络，甚至一个更简单的架构，就可以去学习它想学习的东西

当没有那么多的数据时，更多的是手工工程

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/e6701cf4129576648941bfd593a13c77.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/e6701cf4129576648941bfd593a13c77.png)

对机器学习应用时，通常学习算法有两种知识来源：

* 一个来源是被标记的数据，像$$(x,y)$$应用在监督学习
* 第二个来源是手工工程，有很多方法去建立一个手工工程系统，它可以是源于精心设计的特征，手工精心设计的网络体系结构或者是系统的其他组件。当没有太多标签数据时，只需要更多地考虑手工工程

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/c87f6cc9ec9c45ad57a049b6baf0b86d.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/c87f6cc9ec9c45ad57a049b6baf0b86d.png)

在基准研究和比赛中，下面的tips可能会有较好的表现：

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/0d0a3e182ddb9e995af3c6a68c7a72eb.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/0d0a3e182ddb9e995af3c6a68c7a72eb.png)

* 集成，意味着想好了要的神经网络之后，可以独立训练几个神经网络，并平均它们的输出。比如说随机初始化三个、五个或者七个神经网络，然后训练所有这些网络，对输出$$\hat y$$进行平均计算，而不要平均权重，可能会在基准上提高1%，2%或者更好。但因为集成意味着要对每张图片进行测试，可能需要在从3到15个不同的网络中运行一个图像，会让运行时间变慢
* **Multi-crop at test time**，**Multi-crop**是一种将数据扩充应用到测试图像中的一种形式，在测试图片的多种版本上运行分类器，输出平均结果

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/6027faa79b81f9940281ea36ca901504.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/6027faa79b81f9940281ea36ca901504.png)

如把猫的图片复制四遍，包括两个镜像版本。如取中心的**crop**，然后取四个角落的**crop，**&#x901A;过分类器来运行它

[![](https://github.com/fengdu78/deeplearning_ai_books/raw/master/images/fbb8d5acae8a02c366cea92000577d62.png)](https://github.com/fengdu78/deeplearning_ai_books/blob/master/images/fbb8d5acae8a02c366cea92000577d62.png)

编号1和编号3是中心**crop**，编号2和编号4是四个角落的**crop**。把这些加起来会有10种不同的图像的**crop**，命名为**10-crop**。通过分类器来运行这十张图片，然后对结果进行平均

集成的一个大问题是需要保持所有这些不同的神经网络，占用了更多的计算机内存。**multi-crop**，只保留一个网络，不会占用太多的内存，但仍然会让运行时间变慢
