神經(jīng)網(wǎng)絡(luò)正則化技術(shù)防過擬合和R語言CNN卷積神經(jīng)網(wǎng)絡(luò)手寫數(shù)字圖像數(shù)據(jù)MNIST分類
全文鏈接:http://tecdat.cn/?p=23184?
原文出處:拓端數(shù)據(jù)部落公眾號
在訓(xùn)練深度神經(jīng)網(wǎng)絡(luò)時,在訓(xùn)練集和驗證集上實現(xiàn)相同的性能通常很麻煩。驗證集上相當(dāng)高的誤差是過度擬合的明顯標(biāo)志:神經(jīng)網(wǎng)絡(luò)在訓(xùn)練數(shù)據(jù)方面變得過于專業(yè)。
視頻:神經(jīng)網(wǎng)絡(luò)正則化技術(shù)防過擬合和R語言CNN卷積神經(jīng)網(wǎng)絡(luò)手寫數(shù)字圖像數(shù)據(jù)MNIST分類
神經(jīng)網(wǎng)絡(luò)正則化技術(shù)減少過擬合和R語言CNN卷積神經(jīng)網(wǎng)絡(luò)手寫數(shù)字圖像數(shù)據(jù)MNIST分類
在本文中,我們提供了有關(guān)如何繞過此問題的綜合指南。


神經(jīng)網(wǎng)絡(luò)中的過擬合
在處理任何機器學(xué)習(xí)應(yīng)用程序時,重要的是要清楚地了解模型的偏差和方差。在傳統(tǒng)的機器學(xué)習(xí)算法中,我們討論了偏差與方差的權(quán)衡,它包括試圖最小化模型的方差和偏差時的斗爭。為了減少模型的偏差,即減少錯誤假設(shè)造成的誤差,我們需要一個更復(fù)雜的模型。相反,減少模型的方差,即模型在捕捉訓(xùn)練數(shù)據(jù)變化方面的敏感度,意味著一個更簡單的模型。很簡單,在傳統(tǒng)機器學(xué)習(xí)中,偏差與方差的權(quán)衡源于同時需要更復(fù)雜和更簡單模型的沖突。

在深度學(xué)習(xí)時代,有一些工具可以在不損害模型偏差的情況下僅減少模型的方差,或者相反,在不增加方差的情況下減少偏差。在探索用于防止神經(jīng)網(wǎng)絡(luò)過度擬合的不同技術(shù)之前,重要的是要弄清楚高方差或高偏差的含義。

考慮一個常見的神經(jīng)網(wǎng)絡(luò)任務(wù),例如圖像識別,并考慮一個識別圖片中是否存在熊貓的神經(jīng)網(wǎng)絡(luò)。我們可以自信地評估人類可以以接近 0% 的錯誤率執(zhí)行這項任務(wù)。因此,這是圖像識別網(wǎng)絡(luò)準(zhǔn)確性的合理基準(zhǔn)。在訓(xùn)練集上訓(xùn)練神經(jīng)網(wǎng)絡(luò)并評估其在訓(xùn)練集和驗證集上的性能后,我們可能會得出以下不同的結(jié)果:
訓(xùn)練錯誤 = 20% 和驗證錯誤 = 22%
訓(xùn)練錯誤 = 1% 和驗證錯誤 = 15%
訓(xùn)練誤差 = 0.5% 和驗證誤差 = 1%
訓(xùn)練錯誤 = 20% 和驗證錯誤 = 30%

第一個例子是高偏差的典型例子:訓(xùn)練集和驗證集的誤差都很大。相反,第二個示例存在高方差,在處理模型未從中學(xué)習(xí)的數(shù)據(jù)時準(zhǔn)確度要低得多。第三個結(jié)果代表低方差和偏差,該模型可以被認為是有效的。最后,第四個例子展示了高偏差和高方差的情況:與基準(zhǔn)相比,不僅訓(xùn)練誤差很大,而且驗證誤差也更高。
從現(xiàn)在開始,我將介紹幾種正則化技術(shù),用于減少模型對訓(xùn)練數(shù)據(jù)的過度擬合。它們對前面示例的情況 2. 和 4. 是有益的。
神經(jīng)網(wǎng)絡(luò)的 L1 和 L2 正則化
與經(jīng)典回歸算法(線性、邏輯、多項式等)類似,L1 和 L2 正則化也可用于防止高方差神經(jīng)網(wǎng)絡(luò)中的過度擬合。
L1 和 L2 正則化技術(shù)背后的想法是將模型的權(quán)重限制為更小或?qū)⑵渲幸恍?quán)重縮小到 0。
考慮經(jīng)典深度神經(jīng)網(wǎng)絡(luò)的成本函數(shù) J:

當(dāng)然,成本函數(shù) J 是每個層 1、...、L 的權(quán)重和偏差的函數(shù)。m 是訓(xùn)練樣本的數(shù)量,? 是損失函數(shù)。
L1 正則化
在 L1 正則化中,我們將以下項添加到成本函數(shù) J:

其中矩陣范數(shù)是網(wǎng)絡(luò)的每一層 1, ..., L 的權(quán)重絕對值之和:

λ 是正則化項。這是一個必須仔細調(diào)整的超參數(shù)。λ 直接控制正則化的影響:隨著 λ 的增加,對權(quán)重收縮的影響更加嚴重。
L1 正則化下的完整成本函數(shù)變?yōu)椋?/p>
對于 λ=0,L1 正則化的效果為空。相反,選擇太大的 λ 值會過度簡化模型,可能會導(dǎo)致網(wǎng)絡(luò)擬合不足。
L1 正則化可以被認為是一種神經(jīng)元選擇過程,因為它會使一些隱藏神經(jīng)元的權(quán)重為零。
L2 正則化
在 L2 正則化中,我們添加到成本函數(shù)中的項如下:

在這種情況下,正則化項是每個網(wǎng)絡(luò)層權(quán)重的平方范數(shù)。該矩陣范數(shù)稱為 Frobenius 范數(shù),并且明確地計算如下:

請注意,相對于第 l 層的權(quán)重矩陣有 n^{[l]} 行和 n^{[l-1]} 列。
最后,L2 正則化下的完整代價函數(shù)變?yōu)椋?/p>
同樣,λ 是正則化項,對于 λ=0,L2 正則化的效果為空。
L2 正則化使權(quán)重值趨近于零,從而產(chǎn)生更簡單的模型。
L1 和 L2 正則化如何減少過擬合?
L1 和 L2 正則化技術(shù)對過度擬合訓(xùn)練數(shù)據(jù)有積極影響,原因有兩個:
一些隱藏單元的權(quán)重變得更接近(或等于)0。因此,它們的影響被削弱了,并且生成的網(wǎng)絡(luò)更簡單,因為它更接近更小的網(wǎng)絡(luò)。如介紹中所述,更簡單的網(wǎng)絡(luò)不太容易過度擬合。
對于較小的權(quán)重,隱藏神經(jīng)元的激活函數(shù)的輸入 z 也會變小。對于接近 0 的值,許多激活函數(shù)的行為是線性的。
第二個原因并非微不足道,值得擴展??紤]一個雙曲正切 (tanh) 激活函數(shù),其圖形如下:

雙曲正切 (tanh)
從函數(shù)圖中我們可以看到,如果輸入值 x 很小,函數(shù) tanh(x) 的行為幾乎是線性的。當(dāng) tanh 用作神經(jīng)網(wǎng)絡(luò)隱藏層的激活函數(shù)時,輸入值為:

對于小權(quán)重 w 也接近于零。
如果神經(jīng)網(wǎng)絡(luò)的每一層都是線性的,我們可以證明整個網(wǎng)絡(luò)的行為是線性的。因此,約束一些隱藏單元來模擬線性函數(shù),會導(dǎo)致網(wǎng)絡(luò)更簡單,因此有助于防止過度擬合。
更簡單的模型通??梢员苊庥?xùn)練數(shù)據(jù)中的噪聲,因此過擬合的頻率較低。
dropout
dropout 正則化的思想是隨機刪除網(wǎng)絡(luò)中的一些節(jié)點。在訓(xùn)練過程之前,我們?yōu)榫W(wǎng)絡(luò)的每個節(jié)點設(shè)置一個概率(假設(shè) p = 50%)。在訓(xùn)練階段,每個節(jié)點都有 p 概率被關(guān)閉。dropout 過程是隨機的,它是針對每個訓(xùn)練示例單獨執(zhí)行的。因此,每個訓(xùn)練示例都可能在不同的網(wǎng)絡(luò)上進行訓(xùn)練。
至于 L2 正則化,dropout 正則化的結(jié)果是一個更簡單的網(wǎng)絡(luò),一個更簡單的網(wǎng)絡(luò)導(dǎo)致一個不太復(fù)雜的模型,也不太容易過擬合。

dropout 對簡單網(wǎng)絡(luò)的影響。
R語言KERAS深度學(xué)習(xí)CNN卷積神經(jīng)網(wǎng)絡(luò)分類識別手寫數(shù)字圖像數(shù)據(jù)(MNIST)
?在本文中,我們將學(xué)習(xí)如何使用keras,用手寫數(shù)字圖像數(shù)據(jù)集(即MNIST)進行深度學(xué)習(xí)。本文的目的是為了讓大家親身體驗并熟悉培訓(xùn)課程中的神經(jīng)網(wǎng)絡(luò)部分。
1 軟件包的下載和安裝
在這個例子的筆記本中,需要keras R包。由于它有許多需要下載和安裝的依賴包,因此需要幾分鐘的時間才能完成。請耐心等待!?
1.1 下載 keras
我們可以通過CRAN調(diào)用install.packages("keras")來獲得。

1.2 加載keras包和所需的tensorflow后端
由于keras只是流行的深度學(xué)習(xí)框架的一個接口,我們必須安裝一個特殊的深度學(xué)習(xí)后端。默認和推薦的后端是TensorFlow。通過調(diào)用install_keras(),它將為TensorFlow安裝所有需要的依賴項。下面的單元格需要一分鐘左右的時間來運行。

??

現(xiàn)在,我們準(zhǔn)備好探索深度學(xué)習(xí)了。
2 MNIST數(shù)據(jù)集的概述
在深度學(xué)習(xí)中,比傳統(tǒng)的機器學(xué)習(xí)領(lǐng)域更成功的應(yīng)用之一是圖像識別。我們將在本教程中使用廣泛使用的MNIST手寫數(shù)字圖像數(shù)據(jù)集。關(guān)于該數(shù)據(jù)集的更多信息可以在以下網(wǎng)站找到:https://en.wikipedia.org/wiki/MNIST_database。
2.1 加載MNIST數(shù)據(jù)集
這個數(shù)據(jù)集已經(jīng)包含在keras/tensorflow的安裝中,我們可以簡單地加載數(shù)據(jù)集。加載數(shù)據(jù)集只需要不到一分鐘的時間。
dataset_mnist()
2.2 訓(xùn)練和測試數(shù)據(jù)集
MNIST數(shù)據(jù)集的數(shù)據(jù)結(jié)構(gòu)簡單明了,有兩塊。(1) 訓(xùn)練集:x(即特征):60000x28x28張量,對應(yīng)于60000張28x28像素的圖像,采用灰度表示(即每個28x28矩陣中所有的值都是0到255之間的整數(shù)),y(即因變量):一個長度為60000的向量,包含相應(yīng)的數(shù)字,整數(shù)值在0到9之間。(2) 測試集:與訓(xùn)練集相同,但只有10000個圖像和因變量。數(shù)據(jù)集的詳細結(jié)構(gòu)可以通過下面的str(mnist)看到。
str(mnist)

現(xiàn)在我們準(zhǔn)備好訓(xùn)練和測試數(shù)據(jù)集的特征(x)和因變量(y),可以用str()函數(shù)檢查x_train和y_train的結(jié)構(gòu)。?
str(x_train)
str(y_train)

2.3 繪制圖像
現(xiàn)在讓我們使用R將一個選定的28x28矩陣繪制成圖像。顯示圖像的方式是從矩陣表示法中旋轉(zhuǎn)了90度。因此,還需要額外的步驟來重新排列矩陣,以便能夠使用image()函數(shù)來顯示它的實際方向。
index_image = 28 ## 改變這個索引以看不同的圖像。
output_matrix <- t(output_matrix)
這里是上述圖像的原始28x28矩陣。
input_matrix
3?卷積神經(jīng)網(wǎng)絡(luò)模型
在本節(jié)中,我們將展示如何使用卷積神經(jīng)網(wǎng)絡(luò)(CNN)對MNIST手寫數(shù)據(jù)集進行分類,將圖像分為數(shù)字。這與之前學(xué)習(xí)的問題完全相同,但CNN是一種比一般的深度神經(jīng)網(wǎng)絡(luò)更好的圖像識別深度學(xué)習(xí)方法。CNN利用了二維圖像中相鄰像素之間的關(guān)系來獲得更好的表現(xiàn)。它還避免了為全彩的高分辨率圖像生成數(shù)千或數(shù)百萬的特征。
3.1 數(shù)據(jù)集導(dǎo)入和參數(shù)設(shè)置
現(xiàn)在讓我們再次從頭開始導(dǎo)入MNIST數(shù)據(jù)集,因為已經(jīng)專門為深度神經(jīng)網(wǎng)絡(luò)模型做了一些預(yù)處理。對于CNN,有不同的預(yù)處理步驟。我們還定義了一些以后要使用的參數(shù)。
#加載mnist數(shù)據(jù)的訓(xùn)練和測試數(shù)據(jù)集
x_train <- train$x
y_train <- train$y
x_test <- test$x
y_test <- test$y
# 定義一些用于CNN模型的參數(shù)
epochs <- 10
# 輸入圖像維度
img_rows <- 28
3.2 數(shù)據(jù)預(yù)處理
對于一般的CNN方法,MxN圖像的輸入是一個具有K個特定通道的MxNxK三維數(shù)組。例如,一個灰度MxN圖像只有一個通道,其輸入是MxNx1張量。一個MXN每通道8位的RGB圖像有三個通道,有3個MxN數(shù)組,數(shù)值在0和255之間,所以輸入是MxNx3張量。對于現(xiàn)在的問題,圖像是灰度的,但我們需要通過使用array_reshape()將二維數(shù)組重塑為三維張量來特別定義有一個通道。input_shape變量將在后面的CNN模型中使用。對于RGB顏色的圖像,通道的數(shù)量是3,如果輸入的圖像是RGB格式,我們需要在下面的代碼單元中用 "3 "代替 "1"。
3.2.1 在維度中添加通道
x_train <- array_reshape(x_train, c(nrow(x_train), img_rows, img_cols, 1))
x_test <- array_reshape(x_test, c(nrow(x_test), img_rows, img_cols, 1))
input_shape <- c(img_rows, img_cols, 1)
這里是重塑圖像的結(jié)構(gòu),第一維是圖像索引,第2-4維是一個三維張量,盡管只有一個通道。
str(x_train)
3.2.2 標(biāo)準(zhǔn)化
與DNN模型一樣,為了在優(yōu)化過程中同樣考慮數(shù)值的穩(wěn)定性,我們將輸入值標(biāo)準(zhǔn)化為0和1之間。
x_train <- x_train / 255
x_test <- x_test / 255
3.2.3 將因變量轉(zhuǎn)換為分類變量
與DNN模型一樣,因變量被轉(zhuǎn)換為分類變量。
#將類向量轉(zhuǎn)換為二進制類矩陣
to_categorical(train, numclass)
3.3 構(gòu)建一個CNN模型
正如我們所討論的,CNN模型包含一系列二維卷積層,其中有幾個參數(shù)。(1)kernal_size,通常是3x3或5x5;(2)過濾器的數(shù)量,對應(yīng)于輸出張量中的通道數(shù)量(即第三維);(3)激活函數(shù)。對于第一層,還有一個input_shape參數(shù),即輸入圖像的尺寸和通道。為了防止過度擬合和加快計算速度,通常在一個或幾個二維卷積層之后應(yīng)用一個池化層。一個典型的池化層將2x2池大小的最大值作為輸出的新值,這基本上是將大小減少到一半。除了池化鄰居值之外,也可以使用Dropout。在幾個二維卷積層之后,我們還需要將三維張量輸出 "扁平化 "為一維張量,然后添加一個或幾個密集層,將二維卷積層的輸出連接到目標(biāo)因變量類別。
3.3.1 定義一個CNN模型結(jié)構(gòu)
現(xiàn)在我們定義一個CNN模型,其中有兩個帶有最大池的二維卷積層,第2層帶有附加濾波以防止過擬合。然后將輸出扁平化,并使用兩個密集層連接到圖像的類別。
#定義模型結(jié)構(gòu)
conv_2d(filters = 32,size = c(3,3)) %>%
max_pooling_2d(size = c(2, 2)) %>%
conv_2d(filters = 64, size = c(3,3), ?'relu') %>%
max_pooling(size = c(2, 2)) %>%
dropout(rate = 0.25) %>%
layer_flatten() %>%
summary(model)
3.3.2 ?編譯模型
與DNN模型類似,我們需要編譯所定義的CNN模型。
# 編譯模型
loss_categorical_crossentropy,
optimizer_adadelta(),
c('accuracy')
訓(xùn)練模型并保存每個訓(xùn)練迭代(epochs)的歷史。請注意,由于我們沒有使用GPU,它需要幾分鐘的時間來完成。如果在GPU上運行,訓(xùn)練時間可以大大減少。
3.3.3 訓(xùn)練模型
現(xiàn)在,我們可以用我們處理過的數(shù)據(jù)來訓(xùn)練模型。每個epochs的歷史記錄都可以被保存下來以追蹤進度。請注意,由于我們沒有使用GPU,它需要幾分鐘的時間來完成。在等待結(jié)果時,請耐心等待。如果在GPU上運行,訓(xùn)練時間可以大大減少。
# 訓(xùn)練模型
fit(
x_train, y_train,
validation_split = 0.2
)
plot(cnn)
可以在測試數(shù)據(jù)集上評估訓(xùn)練后的模型準(zhǔn)確性,這是很好的。
evaluate(x_test, y_test)
3.4 模型預(yù)測
對于任何新的圖像,在經(jīng)過同樣的預(yù)處理后,我們可以用訓(xùn)練好的模型來預(yù)測該圖像屬于哪一個數(shù)字。
#
# 模型預(yù)測
predict_classes(x_test)
3.5 檢查誤判的圖像
現(xiàn)在讓我們檢查幾張被誤判的圖像,看看是否人眼識別能比這個簡單的CNN模型做得更好。
## 錯分類圖像的數(shù)量
sum(cnn_pred != testy)
x[cnn_pred != test$y,]
y[cnn_pred !=test$y]
cnn_pred[cnn_pred !=test$y]
index_image = 6 ## 改變這個索引以看到不同的圖像。
image(1:28, ?output_matrix
數(shù)字9被誤預(yù)測為數(shù)字8?

?

最受歡迎的見解
1.r語言用神經(jīng)網(wǎng)絡(luò)改進nelson-siegel模型擬合收益率曲線分析
2.r語言實現(xiàn)擬合神經(jīng)網(wǎng)絡(luò)預(yù)測和結(jié)果可視化
3.python用遺傳算法-神經(jīng)網(wǎng)絡(luò)-模糊邏輯控制算法對樂透分析
4.用于nlp的python:使用keras的多標(biāo)簽文本lstm神經(jīng)網(wǎng)絡(luò)分類
5.用r語言實現(xiàn)神經(jīng)網(wǎng)絡(luò)預(yù)測股票實例
6.R語言基于Keras的小數(shù)據(jù)集深度學(xué)習(xí)圖像分類
7.用于NLP的seq2seq模型實例用Keras實現(xiàn)神經(jīng)機器翻譯
8.python中基于網(wǎng)格搜索算法優(yōu)化的深度學(xué)習(xí)模型分析糖
9.matlab使用貝葉斯優(yōu)化的深度學(xué)習(xí)