week19 卷積神經(jīng)網(wǎng)絡(luò) lenet5 MNIST字符識(shí)別

紀(jì)念碑旁有一家破舊的電影院秦士,往北走五百米就是南京火車西站
每天都有外地人在直線和曲線之間迷路,氣喘吁吁眼淚模糊奔跑 跌倒 奔跑
秋林龍蝦換了新的地方永高,三十二路還是穿過(guò)挹江門
高架橋修了新的隧道隧土,走來(lái)走去走不出 我的鹽倉(cāng)橋
來(lái)到城市已經(jīng)八百九十六天提针,熱河路一直是相同的容顏
偶爾有干凈的潘西路過(guò),他不會(huì)說(shuō)你好 再見

tensorflow游樂(lè)場(chǎng)

TensorFlow游樂(lè)場(chǎng)是一個(gè)通過(guò)網(wǎng)頁(yè)瀏覽器就可以訓(xùn)練簡(jiǎn)單神經(jīng)網(wǎng)絡(luò)
并實(shí)現(xiàn)了可視化訓(xùn)練過(guò)程的工具次洼。

經(jīng)網(wǎng)絡(luò)解決一個(gè)分類問(wèn)題大致可以分為:
1.提取特征向量作為輸入关贵,比如說(shuō)本例子中零件的長(zhǎng)度和質(zhì)量。
2.定義神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)卖毁。包括隱藏層數(shù),激活函數(shù)等等落萎。
3.通過(guò)訓(xùn)練利用反響傳播算法不斷優(yōu)化權(quán)重的值亥啦,使之達(dá)到最合理水平。
4.使用訓(xùn)練好的神經(jīng)網(wǎng)絡(luò)來(lái)預(yù)測(cè)未知數(shù)據(jù)练链,這里訓(xùn)練好的網(wǎng)絡(luò)就是指權(quán)重達(dá)到最優(yōu)的情況翔脱。


好玩

我玩了一會(huì)發(fā)現(xiàn):這不就是我們做的實(shí)驗(yàn)一嗎!C焦摹届吁!怎么會(huì)有這么好用的工具!绿鸣!可以選擇分類和回歸疚沐,可以選擇輸入數(shù)據(jù)的類型,我的天哪簡(jiǎn)直太好玩了俺蹦!A粱住!

numpy.random.random(20,1)隨機(jī)產(chǎn)生20個(gè)浮點(diǎn)數(shù)擎厢,每個(gè)在(0,1)取值
numpy.zeros(5) (5,dtype = np.int) (2,1) (2,2)
numpy.zeros((2,1)) 2*1矩陣
numpy.dot(A,B)
線性代數(shù)上的矩陣相乘究流,生成矩陣(1,1)為A第一行乘B第一列
A * B or numpy.multiply(A,B)
編程上的矩陣相乘,AB兩矩陣對(duì)應(yīng)位置元素相乘动遭,生成矩陣(1,1)為A(1,1)乘B(1,1)

上周用到的反向傳播算法芬探,一共分為三個(gè)步驟:

  1. 前向計(jì)算每個(gè)神經(jīng)元的輸出值aj

  2. 反向計(jì)算每個(gè)神經(jīng)元的誤差項(xiàng)deltaj,為損失函數(shù)Loss對(duì)該神經(jīng)元輸入的偏導(dǎo)數(shù)

  3. 計(jì)算每個(gè)神經(jīng)元連接權(quán)重wji(from i to j)的梯度厘惦,等于ai * deltaj

梯度下降法更新權(quán)重


推導(dǎo)過(guò)程

對(duì)于卷積神經(jīng)網(wǎng)絡(luò)偷仿,由于涉及到局部連接、下采樣的等操作绵估,影響到了第二步誤差項(xiàng)delta的具體計(jì)算方法炎疆,而權(quán)值共享影響了第三步權(quán)重w的梯度的計(jì)算方法。

numpy實(shí)現(xiàn)lenet5實(shí)現(xiàn)MNIST手寫字符識(shí)別

背景知識(shí)

LeNet-5是一種典型的非常高效的用來(lái)識(shí)別手寫體數(shù)字的卷積神經(jīng)網(wǎng)絡(luò)国裳。LeNet-5出自論文Gradient-Based Learning Applied to Document Recognition形入,是由Yann LeCun提出的,對(duì)MNIST數(shù)據(jù)集的識(shí)別準(zhǔn)確度可達(dá)99.2%缝左。


MNIST數(shù)據(jù)集

局部感受野:卷積神經(jīng)網(wǎng)絡(luò)把每一個(gè)隱藏節(jié)點(diǎn)只連接到圖像的某個(gè)局部區(qū)域亿遂,從而減少參數(shù)訓(xùn)練的數(shù)量

共享權(quán)值:在卷積神經(jīng)網(wǎng)絡(luò)的卷積層中浓若,神經(jīng)元對(duì)應(yīng)的權(quán)值是相同的,由于權(quán)值相同蛇数,因此可以減少訓(xùn)練的參數(shù)量挪钓。共享的權(quán)值和偏置也被稱作卷積核或?yàn)V波器

池化:對(duì)圖像進(jìn)行卷積之后,通過(guò)一個(gè)下采樣過(guò)程耳舅,來(lái)調(diào)整圖像的大小

lenet5

INPUT:輸入圖像的尺寸統(tǒng)一歸一化為32 * 32
C1卷積層:對(duì)輸入圖像進(jìn)行第一次卷積運(yùn)算碌上,使用 6 個(gè)大小為 5 * 5 的卷積核,得到6個(gè)28 * 28的特征圖feature map
S2池化層:使用 2 * 2核進(jìn)行池化浦徊,得到了S2馏予,6個(gè)14 * 14的特征圖(28/2=14)
C3卷積層:第二次卷積,第二次卷積的輸出是C3盔性,16個(gè)10x10的特征圖霞丧,卷積核大小是 5 * 5
S4池化層:窗口大小仍然是2*2,共計(jì)16個(gè)feature map冕香,S4中每個(gè)特征圖的大小是C3中特征圖大小的1/4
C5卷積層:由于S4層的16個(gè)圖的大小為5x5蛹尝,與卷積核的大小相同,所以卷積后形成的圖的大小為1x1
F6全連接:有84個(gè)節(jié)點(diǎn)悉尾,對(duì)應(yīng)于一個(gè)7x12的比特圖突那,-1表示白色,1表示黑色焕襟,這樣每個(gè)符號(hào)的比特圖的黑白色就對(duì)應(yīng)于一個(gè)編碼(ASCII編碼圖)
output全連接:有10個(gè)節(jié)點(diǎn)陨收,分別代表數(shù)字0到9,且如果節(jié)點(diǎn)i的值為0鸵赖,則網(wǎng)絡(luò)識(shí)別的結(jié)果是數(shù)字i

lenet5可以分為三個(gè)部分:
1.網(wǎng)絡(luò)定義 2.訓(xùn)練部分 3.驗(yàn)證部分
將訓(xùn)練部分與驗(yàn)證部分分開的好處在于务漩,訓(xùn)練部分可以持續(xù)輸出訓(xùn)練好的模型,驗(yàn)證部分可以每隔一段時(shí)間驗(yàn)證模型的準(zhǔn)確率它褪;如果模型不好饵骨,則需要及時(shí)調(diào)整網(wǎng)絡(luò)結(jié)構(gòu)的參數(shù)。

LeNet-5 的一些性質(zhì):

  1. 如果輸入層不算神經(jīng)網(wǎng)絡(luò)的層數(shù)茫打,那么 LeNet-5 是一個(gè) 7 層的網(wǎng)絡(luò)居触。LeNet-5 大約有 60,000 個(gè)參數(shù)
  2. 隨著網(wǎng)絡(luò)越來(lái)越深,圖像的高度和寬度在縮小老赤,與此同時(shí)轮洋,圖像的 channel 數(shù)量一直在增加
  3. 現(xiàn)在常用的 LeNet-5 結(jié)構(gòu)和 Yann LeCun論文中提出的結(jié)構(gòu)在某些地方有區(qū)別,比如激活函數(shù)的使用抬旺,以及輸出層一般選擇 softmax

MNIST
MNIST是一個(gè)非常有名的手寫數(shù)字識(shí)別數(shù)據(jù)集弊予,是NIST數(shù)據(jù)集的一個(gè)子集,包含了60000張圖片作為訓(xùn)練數(shù)據(jù)开财,10000張圖片作為測(cè)試數(shù)據(jù)汉柒。在MNIST數(shù)據(jù)集中的每一張圖片都代表0~9中的一個(gè)數(shù)字

初始思路

最初我的實(shí)現(xiàn)思路是和之前的全連接神經(jīng)網(wǎng)絡(luò)擬合y=sinx一樣误褪,將所有的層c1、s2碾褂、c3 等等等等封裝在一個(gè)類里兽间,每一層作為一個(gè)方法,里面包含前向與反向傳播正塌。
后來(lái)發(fā)現(xiàn)嘀略,層與層之間重復(fù)的部分太多,代碼復(fù)用率太高传货,例如c1和c3基本是一樣的屎鳍,都是實(shí)現(xiàn)了卷積操作。于是果斷棄用问裕,換為將卷積層、池化層孵坚、全連接層粮宛、非線性層每個(gè)都單獨(dú)封裝為一個(gè)類。這樣構(gòu)建每一層的時(shí)候只要初始化類對(duì)象就可以卖宠。

數(shù)據(jù)讀取
讀取

通過(guò)glob和struct模塊來(lái)實(shí)現(xiàn)訓(xùn)練集和測(cè)試集的讀取

glob:kind表示前綴巍杈,'t10k' 為測(cè)試集,'train'為訓(xùn)練集扛伍, .表示當(dāng)前目錄筷畦,%s為path和kind代表的字符串,*匹配任意字符刺洒,3-ubyte為圖片數(shù)據(jù)集的后綴鳖宾,返回的為list,[0]表示我們要的是這個(gè)list中的第一個(gè)文件
struct:pack與unpack 實(shí)現(xiàn)python中字節(jié)流與其他格式的轉(zhuǎn)換逆航,>II表示解壓至少需要8個(gè)字節(jié)的緩沖區(qū)鼎文,將bytes文件轉(zhuǎn)換為python數(shù)據(jù)文件,返回為元組
np.fromfile:按照指定的格式讀取數(shù)據(jù)因俐,對(duì)數(shù)組的形狀做簡(jiǎn)單的修改

卷積層

初始化:

def __init__(self, shape, output_channels, kernel_size=3, stride=1, method='VALID'):

shape為四維數(shù)組拇惋,如[64, 28, 28, 1],代表[batchsize, width, height, channels]
output_channels為輸出的層數(shù)
kernel_size為卷積核的大小抹剩,如3 * 3的卷積核的大小就為3
stride為卷積的步長(zhǎng)
method為是否做zero padding 撑帖,VALID代表不做,SAME代表做
前向傳播:利用im2col方法來(lái)做卷積澳眷,同時(shí)得到self.col_image
求梯度:

def gradient(self, last_delta):

輸入為下一層的誤差項(xiàng)last_delta胡嘿,將其reshape

col_delta = np.reshape(last_delta, [self.batchsize, -1, self.output_channels])

將前向傳播得到的self.col_image轉(zhuǎn)置后與誤差項(xiàng)col_delta相乘,得到self.w的梯度境蔼,將col_delta求和灶平,得到self.b的梯度
將col_delta矩陣與翻轉(zhuǎn)180度后的權(quán)重矩陣self.weight矩陣相乘伺通,reshape后得到上一層的誤差項(xiàng)next_delta
反向傳播:

def backward(self, learning_rate = 1e-4, weight_decay = 0.0004):

根據(jù)學(xué)習(xí)率和self.w、self.b的梯度進(jìn)行梯度下降來(lái)更新

全連接層

思路和week18做的全連接層一樣逢享,只不過(guò)這次要把層抽象出來(lái)罐监,方法分為前向傳播forward、求梯度gradient和反向傳播backward
初始化:

def __init__(self, shape, output_amount = 2):

shape為四維數(shù)組同上瞒爬,output_amount代表輸出層神經(jīng)元的數(shù)目
前向傳播:矩陣相乘弓柱,求卷積
求梯度:

def gradient(self, last_delta):

根據(jù)后一層的誤差項(xiàng)來(lái)求出前一層的誤差項(xiàng),并求出self.w和self.b的梯度
反向傳播:

def backward(self, learning_rate = 1e-4, weight_decay = 0.0004):

根據(jù)學(xué)習(xí)率和梯度來(lái)進(jìn)行梯度下降來(lái)更新

非線性層

采用relu激活函數(shù)侧但,前向傳播為

return np.maximum(self.x, 0)

反向傳播為

self.delta[self.x < 0] = 0
最大池化層

前向傳播為(2,2)區(qū)域內(nèi)做池化矢空,取最大值,值得注意的是要記錄每一區(qū)域內(nèi)最大值對(duì)應(yīng)的索引

index = np.argmax(x[b, i:i + self.kernel_size, j:j + self.kernel_size, c])
self.index[b, i+index//self.stride, j + index % self.stride, c] = 1

反向傳播為

def gradient(self, delta):return np.repeat(np.repeat(delta, self.stride, axis=1), self.stride, axis=2) * self.index
Softmax層

初始化

def __init__(self, shape):
    self.delta = np.zeros(shape)
    self.softmax = np.zeros(shape)
    self.batchsize = shape[0]

預(yù)測(cè)
根據(jù)softmax原理進(jìn)行預(yù)測(cè)

def predict(self, prediction):
    exp_prediction = np.zeros(prediction.shape)
    self.softmax = np.zeros(prediction.shape)
    for i in range(self.batchsize):
        prediction[i, :] -= np.max(prediction[i, :])
        exp_prediction[i] = np.exp(prediction[i])
        self.softmax[i] = exp_prediction[i]/np.sum(exp_prediction[i])
    return self.softmax

求梯度

    def gradient(self):
        self.delta = self.softmax.copy()
        for i in range(self.batchsize):
            self.delta[i, self.label[i]] -= 1
        return self.delta

計(jì)算損失

    def cal_loss(self, prediction, label):
        self.label = label
        self.prediction = prediction
        self.predict(prediction)
        self.loss = 0
        for i in range(self.batchsize):
            self.loss += np.log(np.sum(np.exp(prediction[i]))) - prediction[i, 
label[i]]

        return self.loss

運(yùn)行效果


new_lenet

網(wǎng)絡(luò)結(jié)構(gòu)略有不同
早期由于計(jì)算資源有限禀横,S2到C3的連接方式是規(guī)定好的屁药,如圖


S2 to C3

而在算力發(fā)達(dá)的今天,我們便不再規(guī)定二者之間的連接方法
如圖所示初始化類對(duì)象柏锄,設(shè)置epoch酿箭、batchsize,開始訓(xùn)練
構(gòu)建對(duì)象

在訓(xùn)練5個(gè)epoch即5輪后趾娃,訓(xùn)練集上的正確率達(dá)到了98.3%缭嫡,驗(yàn)證集上達(dá)到了97.8%


final

結(jié)語(yǔ)

算上在家里“天倫之樂(lè)”的時(shí)間,這個(gè)Lenet5我足足寫了三個(gè)星期抬闷,我看到有博主理解和復(fù)寫這個(gè)寫了小半年妇蛀。關(guān)于實(shí)驗(yàn)課,老師的要求是每一句代碼都要手寫笤成,完全不要農(nóng)夫三拳评架。這樣的初衷和目的當(dāng)然是好我能理解,但是在要求的一個(gè)星期的時(shí)間內(nèi)真的有新手能完完整整的手寫出來(lái)嗎疹启?同學(xué)們真的不會(huì)為了完成目標(biāo)而采取特殊手段嗎古程?這都是值得思考的問(wèn)題。在實(shí)驗(yàn)上我已經(jīng)鴿了太久了hhhh喊崖,能過(guò)就趕快過(guò)看后面的吧≌跄ィ現(xiàn)在先吃飯去咯

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市荤懂,隨后出現(xiàn)的幾起案子茁裙,更是在濱河造成了極大的恐慌,老刑警劉巖节仿,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晤锥,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)矾瘾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門女轿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人壕翩,你說(shuō)我怎么就攤上這事蛉迹。” “怎么了放妈?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵北救,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我芜抒,道長(zhǎng)珍策,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任宅倒,我火速辦了婚禮攘宙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拐迁。我一直安慰自己模聋,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布唠亚。 她就那樣靜靜地躺著,像睡著了一般持痰。 火紅的嫁衣襯著肌膚如雪灶搜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天工窍,我揣著相機(jī)與錄音割卖,去河邊找鬼。 笑死患雏,一個(gè)胖子當(dāng)著我的面吹牛鹏溯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播淹仑,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼丙挽,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了匀借?” 一聲冷哼從身側(cè)響起颜阐,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吓肋,沒(méi)想到半個(gè)月后凳怨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年肤舞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了紫新。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡李剖,死狀恐怖芒率,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情杖爽,我是刑警寧澤敲董,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站慰安,受9級(jí)特大地震影響腋寨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜化焕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一萄窜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧撒桨,春花似錦查刻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至谜疤,卻和暖如春佃延,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背夷磕。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工履肃, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人坐桩。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓尺棋,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親绵跷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子膘螟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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