深度學(xué)習(xí)(八):卷積神經(jīng)網(wǎng)絡(luò)

1 在多個(gè)位置復(fù)用權(quán)重

1、神經(jīng)網(wǎng)絡(luò)最大的挑戰(zhàn)是過擬合。過擬合指的是神經(jīng)網(wǎng)絡(luò)試圖記憶一個(gè)數(shù)據(jù)集,而不是從中學(xué)習(xí)可以泛化到還沒見過的數(shù)據(jù)的有用抽象姻乓。換句話說,神經(jīng)網(wǎng)絡(luò)學(xué)會的是基于數(shù)據(jù)集中的噪聲進(jìn)行預(yù)測眯牧,而不是依賴于基本信號

2蹋岩、過擬合的產(chǎn)生通常是由于當(dāng)前網(wǎng)絡(luò)參數(shù)的數(shù)量多于學(xué)習(xí)特定數(shù)據(jù)集所需要的參數(shù)數(shù)量。這種情況下学少,網(wǎng)絡(luò)有足夠多的參數(shù)剪个,以至于它可以記住訓(xùn)練集中的每一個(gè)細(xì)節(jié),而不是高層次的抽象進(jìn)行學(xué)習(xí)

3版确、網(wǎng)絡(luò)結(jié)構(gòu)是一種很好的防止過擬合的方法扣囊。網(wǎng)絡(luò)結(jié)構(gòu)指的是,在神經(jīng)網(wǎng)絡(luò)中绒疗,因?yàn)槲覀兿嘈拍軌蛟诙鄠€(gè)位置檢測到相同的模式侵歇,所以可以有選擇地重復(fù)用針對多個(gè)目標(biāo)的權(quán)重。正如所見吓蘑,這可以顯著地減少過擬合惕虑,并導(dǎo)致模型的精度更高,因?yàn)樗档土藱?quán)重?cái)?shù)量與數(shù)據(jù)量的比例

4磨镶、在神經(jīng)網(wǎng)絡(luò)中溃蔫,最著名且最廣泛使用的網(wǎng)絡(luò)結(jié)構(gòu)叫作卷積,當(dāng)作為一層使用時(shí)叫作卷積層

2 卷積層(Convolutional Layer)

1琳猫、化整為零伟叛,將許多小線性神經(jīng)元層在各處重用。卷積層背后的思想是脐嫂,它不是一個(gè)大的统刮、稠密的線性神經(jīng)元層紊遵,在其中從每個(gè)輸入到每個(gè)輸出都有連接,而是由很多非常小的線性層構(gòu)成侥蒙,每個(gè)線性層通常擁有少于25個(gè)輸入和一個(gè)輸出暗膜,我們可以在任意輸入位置使用它。每個(gè)小神經(jīng)元層都被稱為卷積核辉哥,但它實(shí)際上只是一個(gè)很小的線性層桦山,含有weights和激活函數(shù)功能攒射,接受少量的輸入并作為單一輸出

2醋旦、圖片底部是4個(gè)不同的卷積核,它們處理相同的8×8的數(shù)字2的圖像会放。每個(gè)卷積核的結(jié)果是是一個(gè)6×6(8-3卷積核長度+1)的預(yù)測矩陣饲齐。你可以對這些矩陣求和(求和池化),取它們的均值(平均池化)咧最,或者按元素計(jì)算最大值(最大池化)

3捂人、最大池化方式是使用最多的:對于每個(gè)位置,查看4個(gè)卷積核各自的輸出矢沿,找到最大值滥搭,并將它復(fù)制到一個(gè)6×6的最終矩陣中,如圖2右下角所示捣鲸。當(dāng)所有運(yùn)算完成后瑟匆,這個(gè)最終矩陣(且僅有這個(gè)最終矩陣)將信號向前傳播到下一層。需要注意的是這4個(gè)卷積核的學(xué)習(xí)模式不同栽惶,右下角的卷積核沒有識別出被訓(xùn)練來預(yù)測的任何模式

4愁溜、網(wǎng)絡(luò)的訓(xùn)練過程允許每個(gè)卷積核學(xué)習(xí)特定的模式,然后在圖像的某個(gè)地方尋找該模式的存在外厂。每個(gè)小巧的卷積核都在多數(shù)數(shù)據(jù)上進(jìn)行了多次向前傳播冕象,從而改變了權(quán)重?cái)?shù)量與訓(xùn)練這些權(quán)重的數(shù)量比例。這對網(wǎng)絡(luò)產(chǎn)生了顯著影響汁蝶,極大地降低了過擬合現(xiàn)象渐扮,提高了網(wǎng)絡(luò)的泛化能力

3 代碼實(shí)現(xiàn)

1、layer_0是一批大小為28×28的圖像掖棉,現(xiàn)在將每個(gè)圖像切成3×3的小圖像席爽,一張圖像可以分割成幾百個(gè)子區(qū)域。通過線性層的一個(gè)輸出神經(jīng)元對它們進(jìn)行正向傳播這一過程啊片,與每批圖像在各個(gè)子區(qū)域上基于線性層進(jìn)行預(yù)測是一樣的
2只锻、具有 n 個(gè)輸出神經(jīng)元的線性層,與n個(gè)卷積核(線性層)在每個(gè)輸入位置進(jìn)行預(yù)測的輸出是一樣的紫谷。這樣做可以使代碼更簡單齐饮,也會更快

import sys,numpy as np
np.random.seed(1)

from keras.datasets import mnist

(x_train,y_train),(x_test,y_test) = mnist.load_data()
#維度分別為(60000,28,28),((60000,)
x_train.shape,y_train.shape

#維度分別為(1000,28*28),((1000,)
#功能:降維捐寥,進(jìn)行標(biāo)準(zhǔn)化
images,labels = (x_train[0:1000].reshape(1000,28*28)/255,y_train[0:1000])

#維度是(1000,10),將一個(gè)最終的數(shù)字祖驱,擴(kuò)充到0-9上的比例
one_hot_labels = np.zeros((len(labels),10))

#這個(gè)是結(jié)果的維度(1000,10),在0-9的的對應(yīng)位置上標(biāo)記為1握恳,其余位置標(biāo)記為0
for i,l in enumerate(labels):
    one_hot_labels[i][l] = 1

labels = one_hot_labels

#將像素值降到0-1之間
test_images = x_test.reshape(len(x_test),28*28)/255
test_labels = np.zeros((len(y_test),10))

for i,l in enumerate(y_test):
    test_labels[i][l] = 1

#relu = lambda x:(x>0) * x
#relu2deriv = lambda x:x>0

#激活函數(shù),將數(shù)值變換到(-1,1)之間
#隱藏層激活函數(shù)
def tanh(x):
    return np.tanh(x)


#反向傳播捺僻,tanh再求導(dǎo)
def tanh2deriv(output):
    return 1-(output**2)

#沿著第一維進(jìn)行求和乡洼,保留數(shù)組的維度
#輸出層激活函數(shù)
def softmax(x):
    temp = np.exp(x)
    return temp/np.sum(temp,axis=1,keepdims=True)


alpha,interations = (2,10)
pixels_per_image,num_labels = (784,10)
#進(jìn)行批訓(xùn)練的時(shí)候,batch_size 為 128
batch_size = 128

#圖片的行匕坯、列個(gè)數(shù)
input_rows = 28
input_cols = 28

#卷積核的行束昵、列數(shù)
kernel_rows = 3
kernel_cols = 3

#使用的卷積核的個(gè)數(shù)
num_kernels = 16

#10000
#隱藏層的size
hidden_size = ((input_rows - kernel_rows)*(input_cols - kernel_cols)) * num_kernels

#維度(9,16), 初始的kernels 權(quán)重,相當(dāng)于weights_0_1
kernels = 0.02*np.random.random((kernel_rows*kernel_cols,num_kernels)) - 0.01

#維度(1000,10),輸出層的維度
weights_1_2 = 0.2*np.random.random((hidden_size,num_labels)) - 0.1

#在一批圖像中選擇子區(qū)域葛峻,選擇了一批輸入圖像的一小部分
def get_image_section(layer,row_from,row_to,col_from,col_to):
    #對layer數(shù)據(jù)進(jìn)行切片
    section = layer[:,row_from:row_to,col_from:col_to]
    #重塑切片后的shape
    #reshape 用于修改數(shù)組的形狀锹雏,不會改變數(shù)組的數(shù)據(jù)和數(shù)量,只會改變其維度
    #-1 表示讓Numpy自動(dòng)計(jì)算這一維度的大小.是reshape之后的行數(shù)
    return section.reshape(-1,1,row_to-row_from,col_to-col_from)

for j in range(interations):
    correct_cnt = 0
    #按照 batch_size 分批進(jìn)行訓(xùn)練
    for i in range(int(len(images)/batch_size)):
        batch_start,batch_end = ((i * batch_size),((i+1)*batch_size))
        #在圖像的每個(gè)位置對它進(jìn)行多次調(diào)用
        #維度(128,784)
        layer_0 = images[batch_start:batch_end]
        #維度(128,28,28)术奖,這里是將其升維到 28*28 行列的矩陣
        layer_0 = layer_0.reshape(layer_0.shape[0],28,28)
        sects = list()
        #0-24
        for row_start in range(layer_0.shape[1]-kernel_rows):
            #0-24
            for col_start in range(layer_0.shape[2]-kernel_cols):
                #依次選取128個(gè)images的卷積kernels礁遵,維度應(yīng)該是(128,1,3,3)
                sect = get_image_section(layer_0,row_start,row_start+kernel_rows,col_start,col_start+kernel_cols)
                sects.append(sect)
        #將眾多小的卷積數(shù)據(jù)進(jìn)行匯總
        expanded_input = np.concatenate(sects,axis=1)
        es = expanded_input.shape
        #降維
        flattened_input = expanded_input.reshape(es[0]*es[1],-1)
        #是在layer0之間加了許多線性卷積核,乘以kernels權(quán)重
        kernel_output = flattened_input.dot(kernels)
        layer_1 = tanh(kernel_output.reshape(es[0],-1))
        dropout_mask = np.random.randint(2,size=layer_1.shape)
        layer_1 *= dropout_mask*2
        #最終的預(yù)測結(jié)果
        layer_2 = softmax(np.dot(layer_1,weights_1_2))

        for k in range(batch_size):
            labelset = labels[batch_start+k:batch_start+k+1]
            _inc = int(np.argmax(layer_2[k:k+1])==np.argmax(labelset))
            correct_cnt += _inc
            #反向傳播步驟
            layer_2_delta = (labels[batch_start:batch_end]-layer_2)/(batch_size*layer_2.shape[0])
            layer_1_delta = layer_2_delta.dot(weights_1_2.T)*tanh2deriv(layer_1)

            layer_1_delta *= dropout_mask
            weights_1_2 += alpha*layer_1.T.dot(layer_2_delta)

            #對kernel進(jìn)行更新采记,相當(dāng)于更新的 weights_0_1
            l1d_reshape = layer_1_delta.reshape(kernel_output.shape)
            k_update = flattened_input.T.dot(l1d_reshape)
            kernels -= alpha*k_update

        test_correct_cnt = 0
        for i in range(len(test_images)):
            layer_0 = test_images[i:i+1]
            layer_0 = layer_0.reshape(layer_0.shape[0],28,28)
            layer_0.shape

            sects = list()
            for row_start in range(layer_0.shape[1] - kernel_rows):
                for col_start in range(layer_0.shape[2]-kernel_cols):
                    sect = get_image_section(layer_0,row_start,row_start+kernel_rows,col_start,col_start+kernel_cols)
                    sects.append(sect)
        expanded_input = np.concatenate(sects,axis=1)
        es = expanded_input.shape
        flattened_input = expanded_input.reshape(es[0]*es[1],-1)

        kernel_output = flattened_input.dot(kernels)
        layer_1 = tanh(kernel_output.reshape(es[0],-1))
        layer_2 = np.dot(layer_1,weights_1_2)
        test_correct_cnt += int(np.argmax(layer_2)==np.argmax(test_labels[i:i+1]))
    
    if(j %1 ==0):
        sys.stdout.write("\n" + "I:" + str(j) + " Test-Acc:" +str(test_correct_cnt/float(len(test_images))) + \
                    " Train-Acc:" +str(correct_cnt/float(len(images))))

4 總結(jié)

1佣耐、卷積層的大多數(shù)用法是多層疊加在一起,這樣每個(gè)卷積都將前一層的輸出作為輸入
2唧龄、層疊卷積層是促成非常深的神經(jīng)網(wǎng)絡(luò)以及深度學(xué)習(xí)流行的主要進(jìn)展之一
3兼砖、復(fù)用權(quán)重是深度學(xué)習(xí)中最重要的創(chuàng)新之一
4、當(dāng)神經(jīng)網(wǎng)絡(luò)需要在多處使用相同想法時(shí)选侨,應(yīng)試著在這些地方使用相同的權(quán)重掖鱼,這樣做會使那些權(quán)重有更多的樣本可以學(xué)習(xí)并提高泛化能力,從而讓權(quán)重更智能

5 參考資料

《深度學(xué)習(xí)圖解》

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末援制,一起剝皮案震驚了整個(gè)濱河市戏挡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌晨仑,老刑警劉巖褐墅,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異洪己,居然都是意外死亡妥凳,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門答捕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來逝钥,“玉大人,你說我怎么就攤上這事拱镐∷铱睿” “怎么了持际?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長哗咆。 經(jīng)常有香客問我蜘欲,道長,這世上最難降的妖魔是什么晌柬? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任姥份,我火速辦了婚禮,結(jié)果婚禮上年碘,老公的妹妹穿的比我還像新娘澈歉。我一直安慰自己,他們只是感情好盛泡,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布闷祥。 她就那樣靜靜地躺著娱颊,像睡著了一般傲诵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上箱硕,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天拴竹,我揣著相機(jī)與錄音,去河邊找鬼剧罩。 笑死栓拜,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的惠昔。 我是一名探鬼主播幕与,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼镇防!你這毒婦竟也來了啦鸣?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤来氧,失蹤者是張志新(化名)和其女友劉穎诫给,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啦扬,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡中狂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了扑毡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胃榕。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖瞄摊,靈堂內(nèi)的尸體忽然破棺而出勋又,到底是詐尸還是另有隱情枉层,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布赐写,位于F島的核電站鸟蜡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏挺邀。R本人自食惡果不足惜揉忘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望端铛。 院中可真熱鬧泣矛,春花似錦、人聲如沸禾蚕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽换淆。三九已至哗总,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間倍试,已是汗流浹背讯屈。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留县习,地道東北人涮母。 一個(gè)月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像躁愿,于是被迫代替她去往敵國和親叛本。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

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