深度學(xué)習(xí)開發(fā)篇(四):圖像分類任務(wù)

本篇主要內(nèi)容:
1、在PaddlePaddle中訓(xùn)練瞻鹏、預(yù)測自定義單字驗證碼數(shù)據(jù)集

一鹿寨、準(zhǔn)備工作

如果對PaddlePaddle不熟悉,在實踐本篇時遇到了問題释移,不妨查看一下本專題下的內(nèi)容。
點擊查看本專題所有文章

驗證碼數(shù)據(jù)集下載:https://github.com/GT-ZhangAcer/DLExample/tree/master/easy02_Reader

二涩蜘、導(dǎo)入關(guān)鍵模塊

import paddle.fluid as fluid
import numpy as np
import PIL.Image as Image

三熏纯、構(gòu)建Reader

在深度學(xué)習(xí)中,訓(xùn)練并不是越多越好误窖,因為訓(xùn)練只是對當(dāng)前送給神經(jīng)網(wǎng)絡(luò)的那一部分負(fù)責(zé)。

舉個考試的例子霹俺,平常老師給我們發(fā)測試題,我們做一遍可能還有不會的愈魏,再做一遍可能會好一些想际,當(dāng)做到第N遍的時候...

你看到題了,就能回想起答案胡本。如果這種情況持續(xù)了10年,你可能會漸漸記下這個答案侧甫,而不是這種題型的做題技巧!

當(dāng)遇到了同一類型的新題時彩扔,還記得當(dāng)年那個聰明的你嗎僻爽?

所以贾惦,我們需要找到一個平衡點,當(dāng)模型對新的數(shù)據(jù)表現(xiàn)不好時立刻停止訓(xùn)練碰镜,保證學(xué)到的是“做題技巧”而不是答案。這樣的新數(shù)據(jù)绪颖,可以是測試集或交叉驗證集(兩者實際還是有一定差別甜奄,本專題深度學(xué)習(xí)開發(fā)篇(二)有簡略介紹)

Reader部分
為了劃分一部分?jǐn)?shù)據(jù)作為交叉驗證集,在這個reader中牍氛,我們在reader函數(shù)外面再套上一個函數(shù)switch_reader烟阐,方便選擇reader返回的是哪一部分的數(shù)據(jù)紊扬,同時設(shè)置一個布爾類型的參數(shù)作為開關(guān)唉擂。

def switch_reader(is_val: bool = False):
    def reader():
        # 讀取標(biāo)簽數(shù)據(jù)
        with open(data_path + "/OCR_100P.txt", 'r') as f:
            labels = f.read()
        # 判斷是否是驗證集
        if is_val:
            index_range = range(1501, 2000)
        else:
            index_range = range(1, 1500)
        # 抽取數(shù)據(jù)使用迭代器返回
        for index in index_range:
            im = Image.open(data_path + "/" + str(index) + ".jpg").convert('L')  # 使用Pillow讀取圖片
            im = np.array(im).reshape(1, 1, 30, 15).astype(np.float32)  # NCHW格式
            im /= 255  # 歸一化以提升訓(xùn)練效果
            lab = labels[index - 1]  # 因為循環(huán)中i是從1開始迭代的楔敌,所有這里需要減去1
            yield im, int(lab)

    return reader   # 注意!此處不需要帶括號

這里需要注意的是卵凑,return reader后不能加括號,因為我們要返回的是reader這個函數(shù)對象伙判,而不是調(diào)用這個函數(shù)黑忱,等劃分mini batch時再進(jìn)行調(diào)用它更為合適。

開始制作mini_batch

# 劃分mini_batch
batch_size = 128
train_reader = fluid.io.batch(reader=switch_reader(), batch_size=batch_size)
val_reader = fluid.io.batch(reader=switch_reader(is_val=True), batch_size=batch_size)

定義輸入層
該怎樣塞進(jìn)神經(jīng)網(wǎng)絡(luò)呢菇曲?我們需要給它制定一個規(guī)范對不對抚吠?

# 定義網(wǎng)絡(luò)輸入格式
img = fluid.data(name="img", shape=[-1, 1, 30, 15], dtype="float32")
# 把標(biāo)簽也順便定義了吧
label = fluid.data(name='label', shape=[-1, 1], dtype='int64')

這里的-1, 1, 30, 15分別代表Batch_size、C喊式、H、W岔留。

為什么Batch_size指定為-1呢检柬?
因為我們無法保證xxx_reader每次返回的就是我們設(shè)置的128組數(shù)據(jù),也就是說當(dāng)我們只有200條數(shù)據(jù)時里逆,第一組有128條头朱,剩下的72條單獨一組。

所以我們在這里把Batch_size位置設(shè)置為-1班眯,這樣就可以自適應(yīng)Batch_size的大小了。

四署隘、使用PaddlePaddle搭建網(wǎng)絡(luò)層

因為數(shù)據(jù)集特別簡單,所以用簡單的全連接層組成的網(wǎng)絡(luò)就足以滿足要求违崇。

這里我們使用3層全連接層作為主要網(wǎng)絡(luò),因為剛剛我們已經(jīng)定義好了輸入層羞延,所有現(xiàn)在可以直接定義隱藏層了~

# 定義第一個隱藏層脾还,激活函數(shù)為ReLU
hidden = fluid.layers.fc(input=img, size=200, act='relu')
# 第二個,激活函數(shù)仍為ReLU
hidden = fluid.layers.fc(input=hidden, size=200, act='relu')
# 以softmax為激活函數(shù)的全連接層為輸出層鄙漏,輸出層的大小必須為Label的總數(shù)10
net_out = fluid.layers.fc(input=hidden, size=10, act='softmax')

如果對激活函數(shù)不熟悉的話,可以先無腦Relu巩步,因為Relu在大部分情況下表現(xiàn)很好桦踊。
用他不能保證一定是最優(yōu)秀的,但至少能保證不會很輕松的掛掉钞钙。

五声离、訓(xùn)練開始前的配置

使用API計算正確率

acc = fluid.layers.accuracy(input=net_out, label=label)

這里的input傳入是輸出層的結(jié)果,label則為剛剛所定義的標(biāo)簽本刽。

克隆一個程序給驗證集使用

eval_prog = fluid.default_main_program().clone(for_test=True)

查看驗證集的結(jié)果也需要將數(shù)據(jù)喂到神經(jīng)網(wǎng)絡(luò)里赠涮。
是不是還需要再把上面給訓(xùn)練集定義的部分,單獨再定義一遍呢斜友?
直接用API克隆出來一個吧垃它,特別方便烹看!

定義損失函數(shù)

loss = fluid.layers.cross_entropy(input=net_out, label=label)
avg_loss = fluid.layers.mean(loss)

如果對損失函數(shù)的作用不了解惯殊,可以參考之前的文章也殖。
這里我們使用交叉熵?fù)p失函數(shù),差不多就是計算網(wǎng)絡(luò)層的輸出與標(biāo)簽直接的差距還有多大忆嗜。

定義優(yōu)化方法

sgd_optimizer = fluid.optimizer.SGD(learning_rate=0.01)
sgd_optimizer.minimize(avg_loss)     # 定義參數(shù)更新(反向傳播也包含在內(nèi))

這里我們使用SGD隨機(jī)梯度下降法作為優(yōu)化方案。
但對于較復(fù)雜的數(shù)據(jù)集還是建議使用Adam來優(yōu)化址愿,效率可能會更高一些冻璃。

之所以把克隆驗證程序放在定義優(yōu)化方法之前,因為我們需要保證在驗證時模型學(xué)到的全部是訓(xùn)練集的參數(shù)娘纷,驗證集不可參與“學(xué)習(xí)”(參數(shù)更新)跋炕,這樣才知道到底學(xué)習(xí)的如何。

定義執(zhí)行器

place = fluid.CPUPlace()    #使用CPU訓(xùn)練辐烂,此處也可以換成GPU
exe = fluid.Executor(place)

數(shù)據(jù)傳入順序設(shè)置

feeder = fluid.DataFeeder(place=place, feed_list=[img, label])

這里的feed_list的順序?qū)τ赗eader里yield返回的順序。

六胳嘲、開始訓(xùn)練

# 對網(wǎng)絡(luò)層進(jìn)行初始化
prog = fluid.default_startup_program()
exe.run(prog)

Epoch = 10    # 訓(xùn)練10輪
for i in range(Epoch):
    batch_loss = None
    batch_acc = None
    # 訓(xùn)練集 只看loss來判斷模型收斂情況
    for batch_id, data in enumerate(train_reader()):
        outs = exe.run(
            feed=feeder.feed(data),
            fetch_list=[loss])
        batch_loss = np.average(outs[0])
    # 驗證集 只看準(zhǔn)確率來判斷收斂情況
    for batch_id, data in enumerate(val_reader()):
        outs = exe.run(program=eval_prog,
                       feed=feeder.feed(data),
                       fetch_list=[acc])
        batch_acc = np.average(outs[0])
    print("Epoch:", i, "\tLoss:{:3f}".format(batch_loss), "\tAcc:{:2f} %".format(batch_acc * 100))

為了輸出看起來好看一些扣草,對于訓(xùn)練集我們只要求返回loss的值,驗證集只返回正確率的值鹰祸。
這些都定義在fetch_list=[xxx]中密浑。

七、訓(xùn)練效果


可以看到驗證集上效果非常棒街图,在第8個Epoch上已經(jīng)達(dá)到了100%!(相信你知道為什么是第8個Epoch)

關(guān)于模型保存台夺,下一節(jié)將對模型保存進(jìn)行詳細(xì)介紹。

示例代碼以及數(shù)據(jù)集

https://github.com/GT-ZhangAcer/DLExample/tree/master/easy03_CV_Classify

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末梳星,一起剝皮案震驚了整個濱河市滚朵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌韵吨,老刑警劉巖移宅,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異糠悼,居然都是意外死亡浅乔,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門席噩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來贤壁,“玉大人,你說我怎么就攤上這事萧芙〖偕ィ” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵包帚,是天一觀的道長运吓。 經(jīng)常有香客問我疯趟,道長谋梭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任盹舞,我火速辦了婚禮隘庄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘丑掺。我一直安慰自己,他們只是感情好街州,可當(dāng)我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布唆缴。 她就那樣靜靜地躺著,像睡著了一般蟆技。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上质礼,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天眶蕉,我揣著相機(jī)與錄音,去河邊找鬼造挽。 笑死,一個胖子當(dāng)著我的面吹牛饭入,可吹牛的內(nèi)容都是我干的肛真。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼乾忱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了衷佃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤纲酗,失蹤者是張志新(化名)和其女友劉穎新蟆,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吮螺,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡帕翻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年嘀掸,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片睬塌。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖勋陪,靈堂內(nèi)的尸體忽然破棺而出硫兰,到底是詐尸還是另有隱情,我是刑警寧澤劫映,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站雌桑,受9級特大地震影響摹蘑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜衅鹿,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一大渤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧泵三,春花似錦、人聲如沸烫幕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽捷犹。三九已至,卻和暖如春萍歉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背憔晒。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工蔑舞, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人澎蛛。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓蜕窿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親桐经。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容