深度學習之卷積神經網路(Convolutional Neural Networks, CNN)(二)
前面我們說了CNN的一般層次結構, 每個層的作用及其引數的優缺點等內容. 這一節將在前一節的內容的基礎上, 討論CNN中的引數初始化, CNN過擬合的處理方法, 引數學習的方法, CNN的優缺點等內容.
一 CNN引數初始化及引數學習方法
和機器學習很多演算法一樣, CNN在進行訓練之前也要進行引數的初始化操作. 我們知道, 在機器學習中的引數值一般都是隨機給定的. 但是, 這CNN的引數初始化又和機器學習中有所不同.
1.1 W的初始化
由於CNN 中的引數更新的過程一般是通過BP演算法實現的,再由前面我們在深度學習之BP演算法一文中得到的BP演算法引數更新公式可以發現, 引數更新過程中卷積核(權重值W)參與了連乘運算,因此一定不能初始化W = 0, 否則引數W無法更新. 另外考慮到太大(小)的W值可能導致梯度下降太快(慢), 一般選擇很小的隨機數, 且要求w為服從均值為0, 方差未知(建議選擇2/n, n為權重的個數)的正態分佈的隨機序列.
1.2 b的初始化
一般直接設定為0,在存在ReLU啟用函式的網路中,也可以考慮設定為一個很小的數字.
1.3 CNN模型引數學習方法
CNN中的引數學習方法主要是BP演算法.
前面我們知道, BP演算法的關鍵在於反向傳播時的鏈式求導求得誤差值 . 然後使用梯度下降的方法進行引數W和b的更新.
二 CNN過擬合
CNN是通過卷積核對樣本進行特徵提取的, 當特徵提取過多(即學習到了不重要的特徵)就回造成過擬合現象的發生, 這裡主要介紹兩種解決過擬合的方法, 分別為正則化和Dropout.
2.1 正則化
和機器學習一樣, 通過在損失函式加上L1,L2正則項可以有效地防止過擬合的問題.
2.2 Dropout
一般情況下,對於同一組訓練資料,利用不同的神經網路訓練之後,求其輸出的平均值可以減少overfitting。Dropout就是利用這個原理,每次丟掉一半左右的隱藏層神經元,相當於在不同的神經網路上進行訓練,這樣就減少了神經元之間的依賴性,即每個神經元不能依賴於某幾個其它的神經元(指層與層之間相連線的神經元),使神經網路更加能學習到與其它神經元之間的更加健壯robust(魯棒性)的特徵。另外Dropout不僅減少overfitting,還能提高準確率。
Dropout通過隨機刪除神經網路中的神經元來解決overfitting問題,在每次迭代的時候,只使用部分神經元訓練模型獲取W和d的值. 具體的可以參見PDF文件.
2.3 方案選擇一般選擇L2 或者Dropout 防止過擬合.
三 經典的CNN模型簡述
1) LeNet(經典的CNN,最早用於數字識別的CNN演算法)---具體的網路結構如圖所示
2) AlexNet(2012年ILSVRC比賽冠軍,遠超第二名的CNN,比LeNet更深,用多層小卷積疊加來替換單個的大卷積 )
3) ZFNet(2013年ILSVRC比賽冠軍)
4) GoogleNet(2014年比賽冠軍,層數較深, 執行時間較長)
5) VGGNet(2014年比賽模型, 效果比GooleNet略差, 但是實際運用較多)
6) ResNet(2015ILSVRC冠軍,結構修正以適應更深層次的CNN訓練)
四 資料增強
一 資料增強的方法介紹
增加訓練資料, 則能夠提升演算法的準確率, 因為這樣可以避免過擬合, 而避免了過擬合你就可以增大你的網路結構了。 當訓練資料有限的時候, 可以通過一些變換來從已有的訓練資料集中生成一些新的資料, 來擴大訓練資料。
資料增強的方法有很多,這裡主要介紹幾種常見的資料增強的方法.
1) 圖片的水平翻轉(主要包括對稱處理, 度數旋轉等)
2) 隨機裁剪(可以裁剪成不同大小的資料)
3) fancy PCA (就是從畫素的角度變化, 形成新的圖片)
4) 樣本不均衡( 解決方案: 增加小眾類別的影像資料)
樣本資料的不均衡的問題是日常中較多遇到的問題, 在機器學習中我們對於資料不平衡有上取樣和下采樣等處理方法, 在這裡我們一般使用的是小眾類別增強的方法處理.
一般根據資料集中的影像最多的種類的數量進行隨機取樣, 使得每個樣本的數量均相等.然後將這些樣本圖片混合打亂形成新的資料集.
5)其它方法(如平移變換;旋轉/仿射變換;高斯噪聲、 模糊處理、 對顏色的資料增強: 影像亮度、 飽和度、 對比度變化.)
二 資料增強的TensorFlow實現
這裡就直接看程式碼(基於python,TensorFlow).
# _*_coding:utf-8_*_
'''
影像處理的Python庫:OpenCV, PIL, matplotlib, tensorflow
'''
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
def show_image_tensor(image_tensor):
image = image_tensor.eval()
print('影像的大小為:{}'.format(image.shape))
if len(image.shape) == 3 and image.shape[2] == 1:
# 黑白圖片
plt.imshow(image[:, :, 0], cmap='Greys_r')
plt.show()
elif len(image.shape) == 3:
# 彩色圖片
plt.imshow(image)
plt.show()
# 1 互動式會話啟動
sess = tf.InteractiveSession()
# 圖片路徑
image_path0 = './datas/black_white.jpg'
image_path1 = './datas/gray.png'
image_path2 = './datas/xiaoren.png'
# 2 影像的預處理
# 一. 影像格式的轉換
file_content = tf.read_file(image_path2)
# 圖片解碼,輸出tensor物件
# 一般影像輸出為[height, width, num_channels],
# gif格式(動態影像)輸出為[num_frames, height, width, 3], num_frames表示動態影像中有幾個靜態影像
# 引數channel可取值0,1,3,4
# 其中0表示自動選擇,1表示gray圖片通道數,3表示RGB(紅.綠,藍)彩色圖片,4表示RGBA四個通道(A表示透明度alpha)
image_tensor = tf.image.decode_png(file_content, channels=3)
# 呼叫show_image_tensor 函式,顯示圖片
# show_image_tensor(image_tensor)
# 二. 影像的大小重置
resize_image = tf.image.resize_images(images=image_tensor, size=[1200, 1200],
method=tf.image.ResizeMethod.NEAREST_NEIGHBOR)
# show_image_tensor(resize_image)
# 三. 影像的剪下或者填充
# 中間剪下或者填充
crop_or_pad_image_tensor = tf.image.resize_image_with_crop_or_pad(image=image_tensor, target_height=1200,
target_width=500)
# show_image_tensor(crop_or_pad_image_tensor)
# 中間等比例剪下
center_image_tensor = tf.image.central_crop(image=image_tensor, central_fraction=0.8)
# show_image_tensor(center_image_tensor)
# 填充資料(給定位置填充)
pad_image_tensor = tf.image.pad_to_bounding_box(image_tensor, offset_height=400, offset_width=490, target_width=1000,
target_height=1000)
# show_image_tensor(pad_image_tensor)
# 剪下資料(給定位置剪下)
crop_image_tensor = tf.image.crop_to_bounding_box(image_tensor, offset_width=20, offset_height=26, target_height=70,
target_width=225)
# show_image_tensor(crop_image_tensor)
# 四.圖片旋轉
# 上下旋轉
flip_up_down_image_tensor = tf.image.flip_up_down(image_tensor)
# show_image_tensor(flip_up_down_image_tensor)
# 左右旋轉
flip_left_right_image_tensor = tf.image.flip_left_right(image_tensor)
# show_image_tensor(flip_left_right_image_tensor)
# 轉置
transpose_image_tensor = tf.image.transpose_image(image_tensor)
# show_image_tensor(transpose_image_tensor)
# 旋轉90,180,270(逆時針旋轉)
rot90_image_tensor = tf.image.rot90(image_tensor, k=2)
# show_image_tensor(rot90_image_tensor)
# 五 顏色空間的轉換(必須將型別轉換為float32型別)
convert_type_image_tensor = tf.image.convert_image_dtype(image_tensor, dtype=tf.float32)
# show_image_tensor(convert_type_image_tensor)
# 1 RGB 轉換為 HSV 格式(hsv表示影像的色度,飽和度,亮度)
rgb_to_hsv_image_tensor = tf.image.rgb_to_hsv(convert_type_image_tensor)
# show_image_tensor(rgb_to_hsv_image_tensor)
# 2 hsv 轉換為 rgb
hsv_to_rgb_image_tensor = tf.image.hsv_to_rgb(rgb_to_hsv_image_tensor)
# show_image_tensor(hsv_to_rgb_image_tensor)
# 3 rgb_to_gray
gray_image_tensor = tf.image.rgb_to_grayscale(hsv_to_rgb_image_tensor)
# show_image_tensor(gray_image_tensor)
# 4 gray to rgb
rgb_image_tensor = tf.image.grayscale_to_rgb(gray_image_tensor)
# show_image_tensor(rgb_image_tensor)
# show_image_tensor(convert_type_image_tensor)
# 從顏色空間中提取影像輪廓資訊(非常有用!!!)
# 0是黑, 1是白
a = gray_image_tensor
b = tf.less_equal(a, 0.8)
c = tf.where(b, x=a, y=a - a)
# show_image_tensor(c)
# 六 影像的調整
# 亮度調整
# delta取值(-1,1),底層是將rgb==>hsv ==> v*delta ==> rgb
adjust_brightness_image_tensor = tf.image.adjust_brightness(image_tensor, delta=0.5)
# show_image_tensor(adjust_brightness_image_tensor)
# 色調調整
adjust_hue_image_tensor = tf.image.adjust_hue(image_tensor, delta=0.5)
# show_image_tensor(adjust_hue_image_tensor)
# 飽和度調整
adjust_saturation_image_tensor = tf.image.adjust_saturation(image_tensor, saturation_factor=10)
# show_image_tensor(adjust_saturation_image_tensor)
# 對比度調整
# 公式: (x-mean)*contrast_factor + mean
adjust_contrast_image_tensor = tf.image.adjust_contrast(image_tensor, contrast_factor=5)
# show_image_tensor(adjust_contrast_image_tensor)
# 影像的gamma校正
# 注意: 輸入必須為float型別的資料 input* gamma
gamma_image_tensor = tf.image.adjust_gamma(convert_type_image_tensor, gamma=2)
# show_image_tensor(gamma_image_tensor)
# 影像的歸一化(防止梯度消失)
image_standardize_image_tensor = tf.image.per_image_standardization(image_tensor)
# show_image_tensor(image_standardize_image_tensor)
# 六 噪音資料的加入
noisy_image_tensor = image_tensor + tf.cast(8 * tf.random_normal(shape=(600, 510, 3), mean=0, stddev=0.2),
dtype=tf.uint8)
show_image_tensor(noisy_image_tensor)
相關文章
- 卷積神經網路:Convolutional Neural Networks(CNN)卷積神經網路CNN
- 卷積神經網路(Convolutional Neural Network,CNN)卷積神經網路CNN
- “卷積神經網路(Convolutional Neural Network,CNN)”之問卷積神經網路CNN
- 卷積神經網路CNN-學習1卷積神經網路CNN
- 論文筆記:Diffusion-Convolutional Neural Networks (傳播-卷積神經網路)筆記卷積神經網路
- CNN神經網路之卷積操作CNN神經網路卷積
- 卷積神經網路CNN卷積神經網路CNN
- 深度學習三:卷積神經網路深度學習卷積神經網路
- 【深度學習原理第4篇】卷積神經網路詳解(CNN)深度學習卷積神經網路CNN
- 深度學習經典卷積神經網路之AlexNet深度學習卷積神經網路
- 看懂卷積神經網路(CNN)卷積神經網路CNN
- 【深度學習篇】--神經網路中的卷積神經網路深度學習神經網路卷積
- 深度學習筆記------卷積神經網路深度學習筆記卷積神經網路
- 深度學習卷積神經網路筆記深度學習卷積神經網路筆記
- 卷積神經網路學習筆記——Siamese networks(孿生神經網路)卷積神經網路筆記
- Convolutional Neural Networks(CNN)CNN
- 卷積神經網路(CNN)詳解卷積神經網路CNN
- 深度學習——LeNet卷積神經網路初探深度學習卷積神經網路
- 深度學習基礎-基於Numpy的卷積神經網路(CNN)實現深度學習卷積神經網路CNN
- Neural Networks and Deep Learning(神經網路與深度學習) - 學習筆記神經網路深度學習筆記
- 神經網路(neural networks)神經網路
- 吳恩達深度學習筆記(deeplearning.ai)之卷積神經網路(CNN)(上)吳恩達深度學習筆記AI卷積神經網路CNN
- CNN (Convolutional Neural Networks) AbstractCNN
- 深度學習革命的開端:卷積神經網路深度學習卷積神經網路
- Tensorflow-卷積神經網路CNN卷積神經網路CNN
- 卷積神經網路(CNN)模型結構卷積神經網路CNN模型
- 直白介紹卷積神經網路(CNN)卷積神經網路CNN
- 深度剖析卷積神經網路卷積神經網路
- 神經網路之卷積篇:詳解經典網路(Classic networks)神經網路卷積
- 深度學習-卷積神經網路-演算法比較深度學習卷積神經網路演算法
- [譯] 淺析深度學習神經網路的卷積層深度學習神經網路卷積
- Keras上實現卷積神經網路CNNKeras卷積神經網路CNN
- CNN筆記:通俗理解卷積神經網路CNN筆記卷積神經網路
- 【卷積神經網路學習】(4)機器學習卷積神經網路機器學習
- 卷積神經網路學習資料卷積神經網路
- 神經網路之卷積篇:詳解單層卷積網路(One layer of a convolutional network)神經網路卷積
- 深度學習與圖神經網路學習分享:CNN 經典網路之-ResNet深度學習神經網路CNN
- 機器學習從入門到放棄:卷積神經網路CNN(二)機器學習卷積神經網路CNN