最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

CNN識別手寫吉爾吉斯語字母以及相關(guān)

2023-09-13 17:13 作者:潘多拉茶壺  | 我要投稿

0. 前言

本專欄主要介紹了一下我做的一個小的深度學(xué)習(xí)項目,并分享一下我的感受。主要面向有一定深度學(xué)習(xí)經(jīng)驗的人,如果有任何不懂的或者我有什么錯誤的地方歡迎評論區(qū)留言。

這里分成兩部分來介紹,首先是項目具體內(nèi)容,然后是我對這個項目的一些相關(guān)討論。

1. 項目內(nèi)容

1.1 項目介紹

使用CNN(卷積神經(jīng)網(wǎng)絡(luò))實現(xiàn)識別手寫吉爾吉斯字母的分類器,即輸入一個手寫的吉爾吉斯字母的PNG圖片,輸出對應(yīng)的字母。

數(shù)據(jù)集:https://www.kaggle.com/datasets/ilgizzhumaev/database-of-36-handwritten-kyrgyz-letters

具體大概是這個樣子(共36種吉爾吉斯字母):


1.2?注意事項

  1. 數(shù)據(jù)集文件夾直接使用了吉爾吉斯字母作為文件夾名稱,在中文的windows系統(tǒng)下,這些名稱會被識別為中文字符,程序中需要注意進(jìn)行轉(zhuǎn)換。

  2. 數(shù)據(jù)集為134x134的PNG圖片,直接全部讀取會占用大量內(nèi)存,直接作為神經(jīng)網(wǎng)絡(luò)的輸入也過大,這里需要對其作預(yù)處理。

  3. 數(shù)據(jù)集內(nèi)部有做訓(xùn)練集(train)和測試集(test)的劃分,嚴(yán)格來說測試集用作超參數(shù)的確定,會部分參與訓(xùn)練,因此嚴(yán)格來說應(yīng)該要保留一個驗證集(validation),其沒有參與任何訓(xùn)練。這里直接將數(shù)據(jù)集中的測試集作為驗證集,而不再去專門劃分測試集,但是后續(xù)描述依舊稱其為測試集(test)。

  4. 神經(jīng)網(wǎng)絡(luò)的實現(xiàn)這里使用tensorflow的keras包(https://keras.io/getting_started),因此程序使用python實現(xiàn)(即便我很討厭python)。

1.3 數(shù)據(jù)預(yù)處理

這里統(tǒng)一將輸入的數(shù)據(jù)轉(zhuǎn)換成32x32的灰度圖像作為輸入,具體操作為(借助opencv包實現(xiàn)):

  1. 使用opencv讀取圖片

  2. 如果圖像有透明度通道,首先將其置于純白的背景下得到?jīng)]有透明度的BGR圖像

  3. 使用opencv的內(nèi)置函數(shù)將BGR圖像轉(zhuǎn)為單通道的灰度圖像

  4. 將整個灰度圖像做仿射變化,使得最亮顏色為255,而最暗顏色為0(最大化對比度)

  5. 裁剪周圍多余的白色背景(容差為32)

  6. 將裁剪后的圖像使用白色向周圍延申成正方形圖像

  7. 縮放圖像到28x28

  8. 將周圍填充2寬度的白色像素,得到32x32的灰度圖像

預(yù)處理前后對比:

在這里最后再將得到的圖像數(shù)組除以255歸一化并使用浮點數(shù)存儲,并且使用1減去結(jié)果(反色),使得重要的字符部分接近1而不重要的背景接近0。

1.4 CNN的結(jié)構(gòu)

最后確認(rèn)下來的結(jié)構(gòu)如下圖:

keras自動輸出的網(wǎng)絡(luò)結(jié)構(gòu)圖

對應(yīng)代碼(model.py):

其實模型本身沒什么特別的,這里提幾個比較重要的點:

  • 所有卷積核采用3x3的大小。

  • 其中DepthwiseConv2D的使用主要是控制整個模型的參數(shù)數(shù)量。

  • 除了最后分類使用softmax,其余部分統(tǒng)一使用relu作為激活函數(shù)。

  • 圖片展示的為默認(rèn)最簡單的結(jié)構(gòu),實際可以通過dropout和BN參數(shù)來增加這兩個層,以及append_layers來增加額外的中間層。

參數(shù)數(shù)量:

1.5?CNN的訓(xùn)練

使用交叉熵作為損失函數(shù),使用keras默認(rèn)自帶的SGD優(yōu)化器,設(shè)置batch_size=32,epoch=32(or 24),初始學(xué)習(xí)率設(shè)置為0.1,策略為前4個epoch固定為0.1,后續(xù)按照0.4/epoch遞減,如下圖:

學(xué)習(xí)速率調(diào)整策略

關(guān)于這些選取的解釋為:

  • 損失函數(shù):由于是分類問題,選用交叉熵(回歸問題則選擇均方差,這是極大似然估計的結(jié)論)。

  • 優(yōu)化器,batch_size,epoch:認(rèn)為這只是一個最優(yōu)化問題,因此只需要保證在可以接受的時間內(nèi)達(dá)到(或基本接近)最小值即可,因此(不去考慮早停的情況下)如何選擇沒有本質(zhì)區(qū)別。

  • 學(xué)習(xí)率:同樣認(rèn)為只是一個最優(yōu)化問題,因此學(xué)習(xí)率只要保證迭代收斂即可。

1.6?訓(xùn)練結(jié)果

對于上述最簡單的模型(不增加dropout或BN),有結(jié)果:

訓(xùn)練過程中訓(xùn)練集和測試集的loss變化
訓(xùn)練過程中訓(xùn)練集和測試集的top-1和top-5準(zhǔn)確率變化
最后(epoch=32)時此模型的結(jié)果

其中top-1準(zhǔn)確率表示模型預(yù)測的概率最高的分類就是正確分類的比例,而top-5準(zhǔn)確率表示模型預(yù)測的概率最高5個分類中包含正確分類的比例

很明顯,訓(xùn)練過程出現(xiàn)了過擬合的現(xiàn)象,隨著訓(xùn)練輪次增加,雖然訓(xùn)練集上loss持續(xù)減少,但是測試集上的loss先下降后上升。

許多地方會采用早停的技術(shù)來抑制這種過擬合現(xiàn)象,即對于上述情況,會在epoch=11處停止進(jìn)一步訓(xùn)練,將其直接作為最終模型,此時測試集上的loss最小。

這里我并不推薦這種做法,首先這樣我們的測試集就一定程度參與了訓(xùn)練過程,用來確定“訓(xùn)練輪次”這個超參數(shù)(上面說過,這里還是將測試集作為驗證集來使用,不希望其參與訓(xùn)練過程)。

另一點則是,應(yīng)該認(rèn)為訓(xùn)練過程是一個最優(yōu)化的過程,“早?!睂嶋H上并沒有讓這個模型中的參數(shù)達(dá)到最優(yōu),這樣會有更多的東西影響訓(xùn)練結(jié)果:例如優(yōu)化器的選擇,batch_size,等等。

關(guān)于過擬合,不是只有這種測試集上的loss先下降后上升才可稱為過擬合,其實只要測試集上的loss明顯高于訓(xùn)練集就是過擬合,因此過擬合其實是一個相對概念。

1.7?抑制過擬合

這里通過向模型中增加dropout或BN層的方式來抑制過擬合,并且對比兩者的效果:

關(guān)于dropout和BN具體內(nèi)容請讀者自行查閱相關(guān)資料


訓(xùn)練過程中訓(xùn)練集和測試集的loss變化
訓(xùn)練過程中訓(xùn)練集和測試集的top-1和top-5準(zhǔn)確率變化
最后時四種模型的結(jié)果

數(shù)據(jù)都疊在一起了,將縱坐標(biāo)換成對數(shù)坐標(biāo)可以看得更加清晰一些:

對數(shù)坐標(biāo)下的loss變化
對數(shù)坐標(biāo)下的錯誤率變化

可以看到無論是使用dropout還是BN層,都可以很好的抑制過擬合,并且BN可以增加訓(xùn)練的速度,而dropout則有相對更好的效果。而同時使用兩種則可以兼顧訓(xùn)練速度的提升和更好的效果(雖然一般認(rèn)為只需要選擇一種即可)。

可以看到雖然測試集下,dropout的loss比BN更小,但是top-1準(zhǔn)確率是相反的,盡管如此這里還是以loss為準(zhǔn)。

在使用dropout后,訓(xùn)練集的loss反而大于測試集的loss,并且錯誤率也有類似的結(jié)果,這是由于keras的dropout層只有在訓(xùn)練的時候會開啟(只使用部分參數(shù)),而在測試的時候會關(guān)閉(使用了所有參數(shù)),因此一般測試時得到的結(jié)果會更好。

可以發(fā)現(xiàn)無論使用dropout還是BN層,最終測試集上的效果都要好于不添加的模型,即使使用上“早?!奔夹g(shù),因此我更加推薦使用dropout或者BN層來抑制過擬合而不是"早停"。


2. 相關(guān)討論

2.1 參數(shù)對網(wǎng)絡(luò)性能的影響

這里統(tǒng)一使用效果最好的同時添加dropout和BN層的模型,訓(xùn)練epoch=32保證基本收斂,并調(diào)整每一層的卷積核數(shù)目或者增加中間層的數(shù)目,以此來擴大網(wǎng)絡(luò)的規(guī)模,看看能否進(jìn)一步提高分類的性能。

首先調(diào)整每層的卷積核數(shù)目,得到top-1和top-5準(zhǔn)確率的趨勢:


網(wǎng)絡(luò)中每層的卷積核數(shù)目和最終top-1準(zhǔn)確率的關(guān)系?
網(wǎng)絡(luò)中每層的卷積核數(shù)目和最終top-5準(zhǔn)確率的關(guān)系

最開始的網(wǎng)絡(luò)選擇的卷積核數(shù)目為32。

然后是設(shè)定卷積核數(shù)目為16,增加神經(jīng)網(wǎng)絡(luò)的層數(shù),得到top-1和top-5準(zhǔn)確率的趨勢:

網(wǎng)絡(luò)中附加的神網(wǎng)絡(luò)層數(shù)和最終top-1準(zhǔn)確率的關(guān)系?
網(wǎng)絡(luò)中附加的神網(wǎng)絡(luò)層數(shù)和最終top-5準(zhǔn)確率的關(guān)系

可以看到兩種方式都可以增加網(wǎng)絡(luò)性能,并且都存在邊際效應(yīng)。

這里統(tǒng)計每個的具體參數(shù)數(shù)目,得到性能隨參數(shù)增加的變化趨勢:

兩種方式修改神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)得到的參數(shù)和準(zhǔn)確率的關(guān)系
兩種方式修改神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)得到的參數(shù)和錯誤的關(guān)系的對數(shù)圖

可以看到,增加網(wǎng)絡(luò)的層數(shù)相比增加每層的寬度,可以使用更少的參數(shù)達(dá)到相同的性能,也就是增加網(wǎng)絡(luò)的層數(shù)比增加每層的寬度“性價比”更高。

當(dāng)然也不能無限的增加網(wǎng)絡(luò)的參數(shù),當(dāng)層數(shù)過多時,會出現(xiàn)梯度消失或者梯度爆炸的問題,導(dǎo)致訓(xùn)練困難;而著名的ResNet就是克服了這個問題,從而可以將網(wǎng)絡(luò)層數(shù)增加到非常高(152層)也可以保證訓(xùn)練能收斂,得到了非常好的效果。

ResNet網(wǎng)絡(luò)示意圖(右一)

由于這個項目問題比較簡單,這里不考慮使用ResNet。

2.2?GUI交互實現(xiàn)

這時會想是否可以直接創(chuàng)建一個繪圖區(qū)域,實時將繪制的圖像使用上述訓(xùn)練的模型來進(jìn)行分類,可以馬上查看模型的效果。

比較可惜的是似乎沒有比較好用的現(xiàn)成的庫實現(xiàn)這個功能,這樣我就只能從tkinter來做一個簡單的gui程序(最討厭寫gui)。

實現(xiàn)過程這里略去,最后得到的界面如下:


gui實時圖像識別

選擇的是每層32個卷積核,不添加額外層的模型,并只使用了BN層而沒有使用dropout。

使用鼠標(biāo)左鍵繪制,右鍵擦除,左上角按鈕清空所有圖像:

實時繪制然后識別的結(jié)果

試了一下才知道,我也不知道手寫吉爾吉斯字母到底是個什么寫法,所以分類到底準(zhǔn)不準(zhǔn)我也不知道,也就圖一樂

3. 源碼提供和說明

源碼已經(jīng)上傳到github,感興趣的可以直接使用:https://github.com/CHanzyLazer/ML-CNN-Kyrgyz

里面包含模型構(gòu)建,圖片預(yù)處理,訓(xùn)練和繪圖,以及gui的實現(xiàn)代碼;并且保留了我運行的結(jié)果。

倉庫中只包含源碼不包含數(shù)據(jù)集,數(shù)據(jù)集需要另外下載:https://www.kaggle.com/datasets/ilgizzhumaev/database-of-36-handwritten-kyrgyz-letters

下載完成后數(shù)據(jù)集置于dataset目錄下,文件結(jié)構(gòu)為:


CNN識別手寫吉爾吉斯語字母以及相關(guān)的評論 (共 條)

分享到微博請遵守國家法律
囊谦县| 尚义县| 佳木斯市| 孟州市| 泰来县| 顺昌县| 武陟县| 沧州市| 绩溪县| 肇源县| 阜城县| 无锡市| 成安县| 叶城县| 兴和县| 南昌市| 龙江县| 永兴县| 淮北市| 固安县| 鄂托克前旗| 宁河县| 万荣县| 怀远县| 西吉县| 普定县| 灵武市| 南开区| 敦煌市| 大邑县| 信阳市| 西贡区| 井研县| 延寿县| 阆中市| 五峰| 行唐县| 于田县| 汨罗市| 拜城县| 萨迦县|