- CNN的應用
- 計算機是如何解析圖片
- 圖片分類MLP
- 分类交叉熵
- Keras 中的模型验证
- MLP與CNN的差異
- 局部连接性
- 卷積層
- stride和填充
- keras中的卷積層
- 维度
- 池化層
- keras中的池化層
- 圖片分類CNN
- AWS GPU實例
- Keras 中的 CNN:實例
- Keras 中的图片增强功能
- 突破性的 CNN 架构
- 可视化 CNN
- 遷移學習
- Keras 中遷移學習
-
- 如果你能训练人工智能机器人唱歌,干嘛还训练它聊天?在 2017 年 4 月,研究人员使用 WaveNet 模型的变体生成了歌曲。原始论文和演示可以在此处找到。
-
了解 Facebook 的创新 CNN 方法(Facebook),该方法专门用于解决语言翻译任务,准确率达到了前沿性水平,并且速度是 RNN 模型的 9 倍。
- 首先,電腦看到的不是圖片,而是一堆數字。
- 再來,神經網路處理的是vector不是matrix,所以要先將matrix轉化成vector。
- 將4x4的matrix,轉成1x16的vector。
- MLP: Multilayer Perceptron。
- 先設計一個神經網路。
- input: MNIST數據庫的圖片(28x28)
- output: 辨識0~9
- Flatten: 將matrix轉成vector。
- 加入relu當作activation。
- relu的好處可以降低梯度消失的現象。
- 详细了解激活函数
- 加入droupout,避免模型overfitting。
- 将 dropout 用作避免过拟合技巧的研究论文。
- 目前設計完成的神經網路,總共有669706的權重需要進行訓練。
- 定義loss function,來區別模型現在預測效果的優劣。
- Keras 中有很多不同的损失函数。对于这节课来说,我们将仅使用 categorical_crossentropy。
- categorical_crossentropy的基本概念,就是如下圖。
- 利用梯度下降,來訓練這些權重。可以利用不同梯度下降的方式來加速訓練的目標。
- 参阅 Keras 中可用的优化程序列表。
- sgd, rmsprop, adam .....。
- 進行compile
- 那還沒訓練的模型直接進預測數字的結果會是如何?
- 跟用猜的差不多,約10%上下的命中率。
- 數據的分配,Training, Validation, Test。
- Validation: 用來驗證我們的model是否有overfitting的現象。
- Test: 用來避免模型選擇流程都偏向Validation。
- 開始訓練模型。
- ModelCheckpoint
- 允許在每次epoch之後保存模型權重。
- save_best_only: 只有當模型讓驗證集達到最佳準確率時,才紀錄權重。
- verbose: 訓練過程,會輸出權重文件何時被更新。
- ModelCheckpoint
-
MLP並未考慮每個像素位置的相對關係。
- MLP的輸入是個vector,已經把原本的matrix間像素的相對關係給打散了。
- 但CNN卻將每個像素位置的相對關係給考慮進去。
-
CNN的主架構跟MLP還是相同。
- 都是一樣的input, hiddien, output。
- 可以共用相同的loss function。
- 但CNN在hidden layer,不在只是單純的Fully Connected layer,而是多了其他特殊作用的layer來幫忙加速訓練。
- 再次檢驗整理MLP跟CNN的差異
- 其中MLP中Fully Connected layer在處理大圖片會導致計算量暴增。
- 這個是重要的觀念,讓CNN的計算量可以大讓降低。
- 每個hidden layer的節點僅需要看到原始圖片的1/4,並找出這1/4圖片中的規律。
- 這樣的設計讓參數量大量減少,也更不容易overfitting。
- 這樣的設計也可以在變化,在hidden layer中多幾組這樣的node,讓神經網路可以發現更複雜的規律。
- 每一個隱層節點都具有共享權重,因為圖片中的不同位置,可能會出現具有相同種類的訊息。
- 每個有助於理解圖片的規律都有可能圖片中的某個位置。
- 例如: 判別是否有貓的照片,貓可能出現在照片中的任何位置。
- window: 卷積窗
- 水平和垂直方向慢慢移動此window,並將原圖圖片切割劃分成不同的小區域。
- Convolutional layer: 卷積層
- 透過卷積窗切割而形成的。
- Filter: 過濾器
- 可以過濾出某個特定訊息(pattern)。
- 例如:下方的過濾器可以篩選出"右上到左下的白色線條" - 第一個卷積窗切割的區域: 沒有含有此pattern。 - 第二個卷積窗切割的區域: 含有此pattern。 - 第三個卷積窗切割的區域: 含有此pattern。
- 多個filters
- 例如 小狗圖片中的這個區域,可能就要一個鬍子filter,牙齒filter,嘴巴filter...。
- 利用4種不同filter來找出圖片中4種不同規律。
- 如何處理彩色圖片
- input: 圖片從2D變成3D
- filter: 從2D變成3D
- Convolutional: 從2D變成3D
- CNN流程
- 一開始檢測的規律是隨機的。
- 定義CNN的損失函數,定義方式跟MLP相同 cross entropy
- 每次epoch都會根據反向傳播來更新過濾器的值,以便最小化損失函數。
- CNN根據損失函數來確認他需要檢查什麼要的規律。
CNN的filtwe是從數據中學習而來的
- stride和padding是CNN的hyper parameter。
- 每次window移動的步伐大小
- stride = 1,convolution layer的大小跟輸入的差不多。
- stride = 2,convolution layer的大小跟輸入的一半。
- stride對圖片邊緣的影響
- 以這個例子當stride=2, 發現window會超出圖片邊緣。
- 兩種處理方式:
- 仍要保留這些?資訊
- 不要保留這些?資訊
- 仍要保留這些?資訊 padding = same
- padding = same,就是在圖片外圍再填充一層0,讓window有更多的移動空間。
- 不要保留這些?資訊 padding = valid
- 會遺失掉邊緣的資訊
-
必须传递以下参数:
- filters - 过滤器数量。
- kernel_size - 指定(方形)卷积窗口的高和宽的数字。
-
你可能还需要调整其他可选参数:
- strides - 卷积 stride。如果不指定任何值,则 strides 设为 1。
- padding - 选项包括 'valid' 和 'same'。如果不指定任何值,则 padding 设为 'valid'。
- activation - 通常为 'relu'。如果未指定任何值,则不应用任何激活函数。强烈建议你向网络中的每个卷积层添加一个 ReLU 激活函数。
-
注意:可以将 kernel_size 和 strides 表示为数字或元组。
在模型中将卷积层当做第一层级(出现在输入层之后)时,必须提供另一个 input_shape 参数:
-
input_shape - 指定输入的高度、宽度和深度(按此顺序)的元组。
-
注意:如果卷积层不是网络的第一个层级,请勿包含 input_shape 参数。
# 导入必要的模块
from keras.layers import Conv2D
# 创建卷积层
Conv2D(filters, kernel_size, strides, padding, activation='relu', input_shape)
- 範例1: 构建一个 CNN,输入层接受的是 200 x 200 像素(对应于高 200、宽 100、深 1 的三维数组)的灰度图片。然后,假设我希望下一层级是卷积层,具有 16 个过滤器,每个宽和高分别为 2。在进行卷积操作时,我希望过滤器每次跳转 2 个像素。并且,我不希望过滤器超出图片界限之外;也就是说,我不想用 0 填充图片。要构建该卷积层,我将使用下面的代码:
Conv2D(filters=16, kernel_size=2, strides=2, activation='relu', input_shape=(200, 200, 1))
- 範例2: 假设我希望 CNN 的下一层级是卷积层,并将示例 1 中构建的层级作为输入。假设新层级是 32 个过滤器,每个的宽和高都是 3。在进行卷积操作时,我希望过滤器每次移动 1 个像素。我希望卷积层查看上一层级的所有区域,因此不介意过滤器在进行卷积操作时是否超过上一层级的边缘。然后,要构建此层级,我将使用以下代码:
Conv2D(filters=32, kernel_size=3, padding='same', activation='relu')
- 範例3: 在这种情况下,有 64 个过滤器,每个的大小是 2x2,层级具有 ReLU 激活函数。层级中的其他参数使用默认值,因此卷积的 stride 为 1,填充设为 'valid'。
Conv2D(64, (2,2), activation='relu')
from keras.models import Sequential
from keras.layers import Conv2D
model = Sequential()
model.add(Conv2D(filters=16, kernel_size=2, strides=2, padding='valid',
activation='relu', input_shape=(200, 200, 1)))
model.summary()
- None 对应的是批次大小,卷积层的高度为 100,宽度为 100,深度为 16。
-
目的: 越複雜的圖就需要越多的過濾器來找出越多的特徵,越多的過濾器就會導致產生越多的參數,越多的參數就會導致訓練量增加,overfitting機會也變大。池化層的目的就是要降低卷积层的餐數量。
-
兩種常看到的池化層
- Max Pooling Layer
- Global Average Pooling layer
-
Max Pooling Layer
- Global Average Pooling layer
from keras.layers import MaxPooling2D
MaxPooling2D(pool_size, strides, padding)
-
参数
- pool_size - 指定池化窗口高度和宽度的数字。
- 你可能还需要调整其他可选参数:
- strides - 垂直和水平 stride。如果不指定任何值,则 strides 默认为 pool_size。
- padding - 选项包括 'valid' 和 'same'。如果不指定任何值,则 padding 设为 'valid'。
- 注意:可以将 pool_size 和 strides 表示为数字或元组。
-
示例 假设我要构建一个 CNN,并且我想通过在卷积层后面添加最大池化层,降低卷积层的维度。假设卷积层的大小是 (100, 100, 15),我希望最大池化层的大小为 (50, 50, 15)。要实现这一点,我可以在最大池化层中使用 2x2 窗口,stride 设为 2,代码如下:
MaxPooling2D(pool_size=2, strides=2)
- 检查最大池化层的维度
from keras.models import Sequential
from keras.layers import MaxPooling2D
model = Sequential()
model.add(MaxPooling2D(pool_size=2, strides=2, input_shape=(100, 100, 15)))
model.summary()
- 首先,CNN的輸入圖片大小必須固定。
- 通常都是固定成2次方的整數 ex. 32x32
- 增加深度,減少寬高。
- 卷積層: 增加深度
- 池化層: 減少寬高
- 架構卷積層
- 先建立3層的卷積層
- 架構池化層
- 緊接在卷積層
- 減少寬高,就是移除了不必要的空間資訊
- 增加深度,把不同的特徵獨立出來
- 架構全聯接層
- 將所有特徵轉化成是哪個類別的機率
# 创建一个序列模型来创建一个 CNN
from keras.models import Sequential
# 导入几个层,包括熟悉的神经网络层
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
model = Sequential()
# 该网络以三个卷积层(后面跟着最大池化层)序列开始。前 6 个层级旨在将图片像素数组输入转换为所有空间信息都丢失、仅保留图片内容信息的数组 。
model.add(Conv2D(filters=16, kernel_size=2, padding='same', activation='relu', input_shape=(32, 32, 3)))
model.add(MaxPooling2D(pool_size=2))
model.add(Conv2D(filters=32, kernel_size=2, padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Conv2D(filters=64, kernel_size=2, padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=2))
# CNN 的第七个层级将该数组扁平化为向量。
model.add(Flatten())
# 两个密集层,旨在进一步说明图片中的内容。最后一层针对数据集中的每个对象类别都有一个条目,并具有一个 softmax 激活函数,使其返回概率。
model.add(Dense(500, activation='relu'))
# 在构建分类网络时,网络中的最后层级应该是具有 softmax 激活函数的 密集层。最后层级的节点数量应该等于数据集中的类别总数。
model.add(Dense(10, activation='softmax'))
-
验证集注意事项
- 在这节课的早些时候,我们通过验证方式训练了一个神经网络,方法是将 model.fit 中的 validation_split 参数设为 0.2。这样会将训练数据的最后 20% 数据变成验证数据。在此视频的 notebook 中,我们自己硬编码了拆分比例,而不是让 Keras 为我们拆分验证集。
-
这是用于在 Keras 中指定神经网络(包括 CNN)的备忘单
-
参阅 CIFAR-10 竞赛的获胜架构
-
當在設計圖片分類的CNN架構時,需要處理大量的irrelevnet information(不相關的資訊)
- 例如:所需辨識物件的角度,位置這些資訊都不該影響辨識的結果。
-
Data Augmentation(數據增強): 透過這個方式,讓model學習如何處理這些不相關的資訊,也可以避免過度的overfitting。
-
ImageNet是一個超過1000萬張的手動標記圖片的資料庫。
- 超過1000個不同圖片分類
- 每年ImageNet都會舉辦ImageNet large scale visual recognition competition。
- 2015 ResNet
- 152層深度神經網路
- 增加shortcut path使得梯度訊號的傳播路徑更短,避免梯度消失的現象。
- 我们将看到该网络中的每个层级会检测到什么,并查看每个层级如何检测到越来越复杂的规律。
- 参阅这个关于很酷的 OpenFrameworks 应用的演示,该应用可以根据用户提供的视频实时可视化 CNN!
- 这是另一个 CNN 可视化工具的演示。如果你想详细了解这些可视化图表是如何制作的,请观看此视频。
- 这是另一个可与 Keras 和 Tensorflow 中的 CNN 无缝合作的可视化工具。
-
迁移学习是指对提前训练过的神经网络进行调整,以用于新的不同数据集。
-
取决于以下两个条件:
- 新数据集的大小,以及
- 新数据集与原始数据集的相似程度
-
使用迁移学习的方法将各不相同。有以下四大主要情形:
- 新数据集很小,新数据与原始数据相似
- 新数据集很小,新数据不同于原始训练数据
- 新数据集很大,新数据与原始训练数据相似
- 新数据集很大,新数据不同于原始训练数据
- 大型数据集可能具有 100 万张图片。小型数据集可能有 2000 张图片。大型数据集与小型数据集之间的界限比较主观。对小型数据集使用迁移学习需要考虑过拟合现象。
- 我们将以一个普通的预先训练过的卷积神经网络开始,并解释如何针对每种情形调整该网络。我们的示例网络包含三个卷积层和三个完全连接层
- 删除神经网络的最后层级
- 添加一个新的完全连接层,与新数据集中的类别数量相匹配
- 随机化设置新的完全连接层的权重;冻结预先训练过的网络中的所有权重
- 训练该网络以更新新连接层的权重
- 为了避免小数据集出现过拟合现象,原始网络的权重将保持不变,而不是重新训练这些权重。
- 将靠近网络开头的大部分预先训练过的层级删掉
- 向剩下的预先训练过的层级添加新的完全连接层,并与新数据集的类别数量相匹配
- 随机化设置新的完全连接层的权重;冻结预先训练过的网络中的所有权重
- 训练该网络以更新新连接层的权重
- 因为数据集很小,因此依然需要注意过拟合问题。要解决过拟合问题,原始神经网络的权重应该保持不变,就像第一种情况那样。
- 删掉最后的完全连接层,并替换成与新数据集中的类别数量相匹配的层级
- 随机地初始化新的完全连接层的权重
- 使用预先训练过的权重初始化剩下的权重
- 重新训练整个神经网络
- 训练大型数据集时,过拟合问题不严重;因此,你可以重新训练所有权重。
- 删掉最后的完全连接层,并替换成与新数据集中的类别数量相匹配的层级
- 使用随机初始化的权重重新训练网络
- 或者,你可以采用和“大型相似数据”情形的同一策略
- 虽然数据集与训练数据不同,但是利用预先训练过的网络中的权重进行初始化可能使训练速度更快。因此这种情形与大型相似数据集这一情形完全相同。
- 参阅这篇 研究论文,该论文系统地分析了预先训练过的 CNN 中的特征的可迁移性。
-
先將原本的input的圖片,透過已經訓練好的權重,轉換成output。
- 再把剛剛的output當作我們準備要訓練layer的input,進行訓練。
- 参阅这个使用 CNN 进行对象定位的资源库
- 这是提议将 GAP 层级用于对象定位的首篇研究论文
- 观看这个关于使用 CNN 进行对象定位的视频演示
- 参阅这个使用可视化机器更好地理解瓶颈特征的资源库