0
本文作者: AI研習(xí)社 | 2017-05-08 16:56 |
雷鋒網(wǎng)按:本文作者宋傳標(biāo),原文載于作者個(gè)人博客,雷鋒網(wǎng)已獲授權(quán)。
在人工的全連接神經(jīng)網(wǎng)絡(luò)中,每相鄰兩層之間的每個(gè)神經(jīng)元之間都是有邊相連的。當(dāng)輸入層的特征維度變得很高時(shí),這時(shí)全連接網(wǎng)絡(luò)需要訓(xùn)練的參數(shù)就會增大很多,計(jì)算速度就會變得很慢,例如一張黑白的 28×28 的手寫數(shù)字圖片,輸入層的神經(jīng)元就有784個(gè),如下圖所示:
若在中間只使用一層隱藏層,參數(shù) w 就有 784×15=11760 多個(gè);若輸入的是28×28 帶有顏色的RGB格式的手寫數(shù)字圖片,輸入神經(jīng)元就有28×28×3=2352 個(gè)…… 。這很容易看出使用全連接神經(jīng)網(wǎng)絡(luò)處理圖像中的需要訓(xùn)練參數(shù)過多的問題。
而在卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Network,CNN)中,卷積層的神經(jīng)元只與前一層的部分神經(jīng)元節(jié)點(diǎn)相連,即它的神經(jīng)元間的連接是非全連接的,且同一層中某些神經(jīng)元之間的連接的權(quán)重 w 和偏移 b 是共享的(即相同的),這樣大量地減少了需要訓(xùn)練參數(shù)的數(shù)量。
卷積神經(jīng)網(wǎng)絡(luò)CNN的結(jié)構(gòu)一般包含這幾個(gè)層:
● 輸入層:用于數(shù)據(jù)的輸入
● 卷積層:使用卷積核進(jìn)行特征提取和特征映射
● 激勵(lì)層:由于卷積也是一種線性運(yùn)算,因此需要增加非線性映射
● 池化層:進(jìn)行下采樣,對特征圖稀疏處理,減少數(shù)據(jù)運(yùn)算量。
● 全連接層:通常在CNN的尾部進(jìn)行重新擬合,減少特征信息的損失
● 輸出層:用于輸出結(jié)果
當(dāng)然中間還可以使用一些其他的功能層:
● 歸一化層(Batch Normalization):在CNN中對特征的歸一化
● 切分層:對某些(圖片)數(shù)據(jù)的進(jìn)行分區(qū)域的單獨(dú)學(xué)習(xí)
● 融合層:對獨(dú)立進(jìn)行特征學(xué)習(xí)的分支進(jìn)行融合
輸入層:
在CNN的輸入層中,(圖片)數(shù)據(jù)輸入的格式 與 全連接神經(jīng)網(wǎng)絡(luò)的輸入格式(一維向量)不太一樣。CNN的輸入層的輸入格式保留了圖片本身的結(jié)構(gòu)。
對于黑白的 28×28 的圖片,CNN的輸入是一個(gè) 28×28 的的二維神經(jīng)元,如下圖所示:
而對于RGB格式的28×28圖片,CNN的輸入則是一個(gè) 3×28×28 的三維神經(jīng)元(RGB中的每一個(gè)顏色通道都有一個(gè) 28×28 的矩陣),如下圖所示:
卷積層:
在卷積層中有幾個(gè)重要的概念:
local receptive fields(感受視野)
shared weights(共享權(quán)值)
假設(shè)輸入的是一個(gè) 28×28 的的二維神經(jīng)元,我們定義5×5 的 一個(gè) local receptive fields(感受視野),即 隱藏層的神經(jīng)元與輸入層的5×5個(gè)神經(jīng)元相連,這個(gè)5*5的區(qū)域就稱之為Local Receptive Fields,如下圖所示:
可類似看作:隱藏層中的神經(jīng)元 具有一個(gè)固定大小的感受視野去感受上一層的部分特征。在全連接神經(jīng)網(wǎng)絡(luò)中,隱藏層中的神經(jīng)元的感受視野足夠大乃至可以看到上一層的所有特征。
而在卷積神經(jīng)網(wǎng)絡(luò)中,隱藏層中的神經(jīng)元的感受視野比較小,只能看到上一次的部分特征,上一層的其他特征可以通過平移感受視野來得到同一層的其他神經(jīng)元,由同一層其他神經(jīng)元來看:
設(shè)移動的步長為1:從左到右掃描,每次移動 1 格,掃描完之后,再向下移動一格,再次從左到右掃描。
具體過程如動圖所示:
可看出 卷積層的神經(jīng)元是只與前一層的部分神經(jīng)元節(jié)點(diǎn)相連,每一條相連的線對應(yīng)一個(gè)權(quán)重 w 。
一個(gè)感受視野帶有一個(gè)卷積核,我們將 感受視野 中的權(quán)重 w 矩陣稱為 卷積核 ;將感受視野對輸入的掃描間隔稱為步長(stride);當(dāng)步長比較大時(shí)(stride>1),為了掃描到邊緣的一些特征,感受視野可能會“出界”,這時(shí)需要對邊界擴(kuò)充(pad),邊界擴(kuò)充可以設(shè)為 0 或 其他值。步長 和 邊界擴(kuò)充值的大小由用戶來定義。
卷積核的大小由用戶來定義,即定義的感受視野的大??;卷積核的權(quán)重矩陣的值,便是卷積神經(jīng)網(wǎng)絡(luò)的參數(shù),為了有一個(gè)偏移項(xiàng) ,卷積核可附帶一個(gè)偏移項(xiàng) b ,它們的初值可以隨機(jī)來生成,可通過訓(xùn)練進(jìn)行變化。
因此 感受視野 掃描時(shí)可以計(jì)算出下一層神經(jīng)元的值為:
對下一層的所有神經(jīng)元來說,它們從不同的位置去探測了上一層神經(jīng)元的特征。
我們將通過 一個(gè)帶有卷積核的感受視野 掃描生成的下一層神經(jīng)元矩陣 稱為 一個(gè)feature map (特征映射圖),如下圖的右邊便是一個(gè) feature map:
因此在同一個(gè) feature map 上的神經(jīng)元使用的卷積核是相同的,因此這些神經(jīng)元 shared weights,共享卷積核中的權(quán)值和附帶的偏移。一個(gè) feature map 對應(yīng) 一個(gè)卷積核,若我們使用 3 個(gè)不同的卷積核,可以輸出3個(gè)feature map:(感受視野:5×5,布長stride:1)
因此在CNN的卷積層,我們需要訓(xùn)練的參數(shù)大大地減少到了 (5×5+1)×3=78個(gè)。
假設(shè)輸入的是 28×28 的RGB圖片,即輸入的是一個(gè) 3×28×28 的的二維神經(jīng)元,這時(shí)卷積核的大小不只用長和寬來表示,還有深度,感受視野也對應(yīng)的有了深度,如下圖所示:
由圖可知:感受視野: 3×2×2 ; 卷積核: 3×2×2 ,深度為3;下一層的神經(jīng)元的值為:b+∑2d=0∑1i=0∑1j=0wdijxdij . 卷積核的深度和感受視野的深度相同,都由輸入數(shù)據(jù)來決定,長寬可由自己來設(shè)定,數(shù)目也可以由自己來設(shè)定,一個(gè)卷積核依然對應(yīng)一個(gè) feature map 。
注:“stride=1”表示在長和寬上的移動間隔都為1,即 stridewidth=1 且 strideheight=1
激勵(lì)層:
激勵(lì)層主要對卷積層的輸出進(jìn)行一個(gè)非線性映射,因?yàn)榫矸e層的計(jì)算還是一種線性計(jì)算。使用的激勵(lì)函數(shù)一般為ReLu函數(shù):
f(x)=max(x,0)
卷積層和激勵(lì)層通常合并在一起稱為“卷積層”。
池化層:
當(dāng)輸入經(jīng)過卷積層時(shí),若感受視野比較小,布長stride比較小,得到的feature map (特征圖)還是比較大,可以通過池化層來對每一個(gè) feature map 進(jìn)行降維操作,輸出的深度還是不變的,依然為 feature map 的個(gè)數(shù)。
池化層也有一個(gè)“池化視野(filter)”來對feature map矩陣進(jìn)行掃描,對“池化視野”中的矩陣值進(jìn)行計(jì)算,一般有兩種計(jì)算方式:
Max pooling:取“池化視野”矩陣中的最大值
Average pooling:取“池化視野”矩陣中的平均值
掃描的過程中同樣地會涉及的掃描布長stride,掃描方式同卷積層一樣,先從左到右掃描,結(jié)束則向下移動布長大小,再從左到右。如下圖示例所示:
其中“池化視野”filter: 2×2;布長stride:2。(注:“ 池化視野”為個(gè)人叫法)
最后可將 3 個(gè) 24×24 的 feature map 下采樣得到 3 個(gè) 24×24 的特征矩陣:
歸一化層:
1. Batch Normalization
Batch Normalization(批量歸一化)實(shí)現(xiàn)了在神經(jīng)網(wǎng)絡(luò)層的中間進(jìn)行預(yù)處理的操作,即在上一層的輸入歸一化處理后再進(jìn)入網(wǎng)絡(luò)的下一層,這樣可有效地防止“梯度彌散”,加速網(wǎng)絡(luò)訓(xùn)練。
Batch Normalization具體的算法如下圖所示:
每次訓(xùn)練時(shí),取 batch_size 大小的樣本進(jìn)行訓(xùn)練,在BN層中,將一個(gè)神經(jīng)元看作一個(gè)特征,batch_size 個(gè)樣本在某個(gè)特征維度會有 batch_size 個(gè)值,然后在每個(gè)神經(jīng)元 xi 維度上的進(jìn)行這些樣本的均值和方差,通過公式得到 xi∧,再通過參數(shù) γ 和 β 進(jìn)行線性映射得到每個(gè)神經(jīng)元對應(yīng)的輸出 yi 。在BN層中,可以看出每一個(gè)神經(jīng)元維度上,都會有一個(gè)參數(shù) γ 和 β ,它們同權(quán)重w一樣可以通過訓(xùn)練進(jìn)行優(yōu)化。
在卷積神經(jīng)網(wǎng)絡(luò)中進(jìn)行批量歸一化時(shí),一般對 未進(jìn)行ReLu激活的 feature map進(jìn)行批量歸一化,輸出后再作為激勵(lì)層的輸入,可達(dá)到調(diào)整激勵(lì)函數(shù)偏導(dǎo)的作用。
一種做法是將 feature map 中的神經(jīng)元作為特征維度,參數(shù) γ 和 β 的數(shù)量和則等于 2×fmapwidth×fmaplength×fmapnum,這樣做的話參數(shù)的數(shù)量會變得很多;
另一種做法是把 一個(gè) feature map 看做一個(gè)特征維度,一個(gè) feature map 上的神經(jīng)元共享這個(gè) feature map的 參數(shù) γ 和 β ,參數(shù) γ 和 β 的數(shù)量和則等于 2×fmapnum,計(jì)算均值和方差則在batch_size個(gè)訓(xùn)練樣本在每一個(gè)feature map維度上的均值和方差。
注:fmapnum指的是一個(gè)樣本的feature map數(shù)量,feature map 跟神經(jīng)元一樣也有一定的排列順序。
Batch Normalization 算法的訓(xùn)練過程和測試過程的區(qū)別:
在訓(xùn)練過程中,我們每次都會將 batch_size 數(shù)目大小的訓(xùn)練樣本 放入到CNN網(wǎng)絡(luò)中進(jìn)行訓(xùn)練,在BN層中自然可以得到計(jì)算輸出所需要的 均值 和 方差 ;
而在測試過程中,我們往往只會向CNN網(wǎng)絡(luò)中輸入一個(gè)測試樣本,這是在BN層計(jì)算的均值和方差會均為 0,因?yàn)橹挥幸粋€(gè)樣本輸入,因此BN層的輸入也會出現(xiàn)很大的問題,從而導(dǎo)致CNN網(wǎng)絡(luò)輸出的錯(cuò)誤。所以在測試過程中,我們需要借助訓(xùn)練集中所有樣本在BN層歸一化時(shí)每個(gè)維度上的均值和方差,當(dāng)然為了計(jì)算方便,我們可以在 batch_num 次訓(xùn)練過程中,將每一次在BN層歸一化時(shí)每個(gè)維度上的均值和方差進(jìn)行相加,最后再進(jìn)行求一次均值即可。
2. Local Response Normalization
近鄰歸一化(Local Response Normalization)的歸一化方法主要發(fā)生在不同的相鄰的卷積核(經(jīng)過ReLu之后)的輸出之間,即輸入是發(fā)生在不同的經(jīng)過ReLu之后的 feature map 中。
LRN的公式如下:
其中:
a(i,x,y) 表示第i個(gè)卷積核的輸出(經(jīng)過ReLu層)的feature map上的 (x,y) 位置上的值。
b(i,x,y) 表示 a(i,x,y) 經(jīng)LRN后的輸出。
N 表示卷積核的數(shù)量,即輸入的 feature map的個(gè)數(shù)。
n 表示近鄰的卷積核(或feature map)個(gè)數(shù),由自己來決定。
k,α,β是超參數(shù),由用戶自己調(diào)整或決定。
與BN的區(qū)別:BN依據(jù)mini batch的數(shù)據(jù),近鄰歸一僅需要自己來決定,BN訓(xùn)練中有學(xué)習(xí)參數(shù);BN歸一化主要發(fā)生在不同的樣本之間,LRN歸一化主要發(fā)生在不同的卷積核的輸出之間。
切分層:
在一些應(yīng)用中,需要對圖片進(jìn)行切割,獨(dú)立地對某一部分區(qū)域進(jìn)行單獨(dú)學(xué)習(xí)。這樣可以對特定部分進(jìn)行通過調(diào)整 感受視野 進(jìn)行力度更大的學(xué)習(xí)。
融合層:
融合層可以對切分層進(jìn)行融合,也可以對不同大小的卷積核學(xué)習(xí)到的特征進(jìn)行融合。
例如在GoogleLeNet 中,使用多種分辨率的卷積核對目標(biāo)特征進(jìn)行學(xué)習(xí),通過 padding 使得每一個(gè) feature map 的長寬都一致,之后再將多個(gè) feature map 在深度上拼接在一起:
融合的方法有幾種,一種是特征矩陣之間的拼接級聯(lián),另一種是在特征矩陣進(jìn)行運(yùn)算 (+,-,x,max,conv)。
全連接層和輸出層
全連接層主要對特征進(jìn)行重新擬合,減少特征信息的丟失;輸出層主要準(zhǔn)備做好最后目標(biāo)結(jié)果的輸出。例如VGG的結(jié)構(gòu)圖,如下圖所示:
LeNet-5模型
第一個(gè)成功應(yīng)用于數(shù)字?jǐn)?shù)字識別的卷積神經(jīng)網(wǎng)絡(luò)模型(卷積層自帶激勵(lì)函數(shù),下同):
卷積層的卷積核邊長都是5,步長都為1;池化層的窗口邊長都為2,步長都為2。
AlexNet 模型
具體結(jié)構(gòu)圖:
從AlexNet的結(jié)構(gòu)可發(fā)現(xiàn):經(jīng)典的卷積神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)通常為:
輸入層 → (卷積層+→池化層?)+→全連接層+→輸出層
AlexNet卷積層的卷積核邊長為5或3,池化層的窗口邊長為3。具體參數(shù)如圖所示:
VGGNet 模型
VGGNet 模型 和 AlexNet模型 在結(jié)構(gòu)上沒多大變化,在卷積層部位增加了多個(gè)卷積層。AlexNet(上) 和 VGGNet (下)的對比如下圖所示:
具體參數(shù)如圖所示:其中CONV3-64:表示卷積核的長和寬為3,個(gè)數(shù)有64個(gè);POOL2:表示池化窗口的長和寬都為2,其他類似。
GoogleNet 模型
使用了多個(gè)不同分辨率的卷積核,最后再對它們得到的feature map 按深度融合在一起,結(jié)構(gòu)如圖:
其中,有一些主要的模塊稱為 Inception module,例如:
在 Inception module 中使用到了很多 1×1 的卷積核,使用 1×1 的卷積核,步長為1時(shí),輸入的feature map和輸出的feature map長寬不會發(fā)生改變,但可以通過改變 1×1 的卷積核的數(shù)目,來達(dá)到減小feature map的厚度的效果,從而做到一些訓(xùn)練參數(shù)的減少。
GoogleNet還有一個(gè)特點(diǎn)就是它是全卷積結(jié)構(gòu)(FCN)的,網(wǎng)絡(luò)的最后沒有使用全連接層,一方面這樣可以減少參數(shù)的數(shù)目,不容易過擬合,一方面也帶來了一些空間信息的丟失。代替全連接層的是全局平均池化(Global Average Pooling,GAP)的方法,思想是:為每一個(gè)類別輸出一個(gè) feature map ,再取每一個(gè) feature map上的平均值,作為最后的softmax層的輸入。
ResNet模型
在前面的CNN模型中,都是將輸入一層一層地傳遞下去(圖左),當(dāng)層次比較深時(shí),模型不是很好訓(xùn)練。在ResNet模型中,它將低層學(xué)習(xí)到的特征和高層的學(xué)習(xí)到的特征進(jìn)行一個(gè)融合(加法運(yùn)算,圖右),這樣反向傳遞時(shí),導(dǎo)數(shù)傳遞得更快,減少梯度彌散的現(xiàn)象。
注意:F(X)的shape需要等于 X 的shape ,這樣才可以進(jìn)行相加。
主要的函數(shù)說明:
卷積層:
tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None)
參數(shù)說明:
● data_format:表示輸入的格式,有兩種分別為:“NHWC”和“NCHW”,默認(rèn)為“NHWC”
● input:輸入是一個(gè)4維格式的(圖像)數(shù)據(jù),數(shù)據(jù)的 shape 由 data_format 決定:當(dāng) data_format 為“NHWC”輸入數(shù)據(jù)的shape表示為[batch, in_height, in_width, in_channels],分別表示訓(xùn)練時(shí)一個(gè)batch的圖片數(shù)量、圖片高度、 圖片寬度、 圖像通道數(shù)。當(dāng) data_format 為“NHWC”輸入數(shù)據(jù)的shape表示為[batch, in_channels, in_height, in_width]
● filter:卷積核是一個(gè)4維格式的數(shù)據(jù):shape表示為:[height,width,in_channels, out_channels],分別表示卷積核的高、寬、深度(與輸入的in_channels應(yīng)相同)、輸出 feature map的個(gè)數(shù)(即卷積核的個(gè)數(shù))。
● strides:表示步長:一個(gè)長度為4的一維列表,每個(gè)元素跟data_format互相對應(yīng),表示在data_format每一維上的移動步長。當(dāng)輸入的默認(rèn)格式為:“NHWC”,則 strides = [batch , in_height , in_width, in_channels]。其中 batch 和 in_channels 要求一定為1,即只能在一個(gè)樣本的一個(gè)通道上的特征圖上進(jìn)行移動,in_height , in_width表示卷積核在特征圖的高度和寬度上移動的布長,即 strideheight 和 stridewidth 。
● padding:表示填充方式:“SAME”表示采用填充的方式,簡單地理解為以0填充邊緣,但還有一個(gè)要求,左邊(上邊)補(bǔ)0的個(gè)數(shù)和右邊(下邊)補(bǔ)0的個(gè)數(shù)一樣或少一個(gè),“VALID”表示采用不填充的方式,多余地進(jìn)行丟棄。具體公式:
“SAME”: output_spatial_shape[i]=(input_spatial_shape[i] / strides[i])
“VALID”: output_spatial_shape[i]=((input_spatial_shape[i]-(spatial_filter_shape[i]-1)/strides[i])
池化層:
tf.nn.max_pool( value, ksize,strides,padding,data_format=’NHWC’,name=None)
或者
tf.nn.avg_pool(…)
參數(shù)說明:
● value:表示池化的輸入:一個(gè)4維格式的數(shù)據(jù),數(shù)據(jù)的 shape 由 data_format 決定,默認(rèn)情況下shape 為[batch, height, width, channels]
● 其他參數(shù)與 tf.nn.cov2d 類型
● ksize:表示池化窗口的大?。阂粋€(gè)長度為4的一維列表,一般為[1, height, width, 1],因不想在batch和channels上做池化,則將其值設(shè)為1。
Batch Nomalization層:
batch_normalization( x,mean,variance,offset,scale, variance_epsilon,name=None)
● mean 和 variance 通過 tf.nn.moments 來進(jìn)行計(jì)算:
batch_mean, batch_var = tf.nn.moments(x, axes = [0, 1, 2], keep_dims=True),注意axes的輸入。對于以feature map 為維度的全局歸一化,若feature map 的shape 為[batch, height, width, depth],則將axes賦值為[0, 1, 2]
● x 為輸入的feature map 四維數(shù)據(jù),offset、scale為一維Tensor數(shù)據(jù),shape 等于 feature map 的深度depth。
代碼示例:
通過搭建卷積神經(jīng)網(wǎng)絡(luò)來實(shí)現(xiàn)sklearn庫中的手寫數(shù)字識別,搭建的卷積神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)如下圖所示:
import tensorflow as tf
from sklearn.datasets import load_digits
import numpy as np
digits = load_digits()
X_data = digits.data.astype(np.float32)
Y_data = digits.target.astype(np.float32).reshape(-1,1)
print X_data.shape
print Y_data.shape
(1797, 64)
(1797, 1)
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X_data = scaler.fit_transform(X_data)
from sklearn.preprocessing import OneHotEncoder
Y = OneHotEncoder().fit_transform(Y_data).todense() #one-hot編碼
Y
matrix([[ 1., 0., 0., ..., 0., 0., 0.],
[ 0., 1., 0., ..., 0., 0., 0.],
[ 0., 0., 1., ..., 0., 0., 0.],
...,
[ 0., 0., 0., ..., 0., 1., 0.],
[ 0., 0., 0., ..., 0., 0., 1.],
[ 0., 0., 0., ..., 0., 1., 0.]])
# 轉(zhuǎn)換為圖片的格式 (batch,height,width,channels)
X = X_data.reshape(-1,8,8,1)
batch_size = 8 # 使用MBGD算法,設(shè)定batch_size為8
def generatebatch(X,Y,n_examples, batch_size):
for batch_i in range(n_examples // batch_size):
start = batch_i*batch_size
end = start + batch_size
batch_xs = X[start:end]
batch_ys = Y[start:end]
yield batch_xs, batch_ys # 生成每一個(gè)batch
tf.reset_default_graph()
# 輸入層
tf_X = tf.placeholder(tf.float32,[None,8,8,1])
tf_Y = tf.placeholder(tf.float32,[None,10])
# 卷積層+激活層
conv_filter_w1 = tf.Variable(tf.random_normal([3, 3, 1, 10]))
conv_filter_b1 = tf.Variable(tf.random_normal([10]))
relu_feature_maps1 = tf.nn.relu(\
tf.nn.conv2d(tf_X, conv_filter_w1,strides=[1, 1, 1, 1], padding='SAME') + conv_filter_b1)
# 池化層
max_pool1 = tf.nn.max_pool(relu_feature_maps1,ksize=[1,3,3,1],strides=[1,2,2,1],padding='SAME')
print max_pool1
Tensor("MaxPool:0", shape=(?, 4, 4, 10), dtype=float32)
# 卷積層
conv_filter_w2 = tf.Variable(tf.random_normal([3, 3, 10, 5]))
conv_filter_b2 = tf.Variable(tf.random_normal([5]))
conv_out2 = tf.nn.conv2d(relu_feature_maps1, conv_filter_w2,strides=[1, 2, 2, 1], padding='SAME') + conv_filter_b2
print conv_out2
Tensor("add_4:0", shape=(?, 4, 4, 5), dtype=float32)
# BN歸一化層+激活層
batch_mean, batch_var = tf.nn.moments(conv_out2, [0, 1, 2], keep_dims=True)
shift = tf.Variable(tf.zeros([5]))
scale = tf.Variable(tf.ones([5]))
epsilon = 1e-3
BN_out = tf.nn.batch_normalization(conv_out2, batch_mean, batch_var, shift, scale, epsilon)
print BN_out
relu_BN_maps2 = tf.nn.relu(BN_out)
Tensor("batchnorm/add_1:0", shape=(?, 4, 4, 5), dtype=float32)
# 池化層
max_pool2 = tf.nn.max_pool(relu_BN_maps2,ksize=[1,3,3,1],strides=[1,2,2,1],padding='SAME')
print max_pool2
Tensor("MaxPool_1:0", shape=(?, 2, 2, 5), dtype=float32)
# 將特征圖進(jìn)行展開
max_pool2_flat = tf.reshape(max_pool2, [-1, 2*2*5])
# 全連接層
fc_w1 = tf.Variable(tf.random_normal([2*2*5,50]))
fc_b1 = tf.Variable(tf.random_normal([50]))
fc_out1 = tf.nn.relu(tf.matmul(max_pool2_flat, fc_w1) + fc_b1)
# 輸出層
out_w1 = tf.Variable(tf.random_normal([50,10]))
out_b1 = tf.Variable(tf.random_normal([10]))
pred = tf.nn.softmax(tf.matmul(fc_out1,out_w1)+out_b1)
loss = -tf.reduce_mean(tf_Y*tf.log(tf.clip_by_value(pred,1e-11,1.0)))
train_step = tf.train.AdamOptimizer(1e-3).minimize(loss)
y_pred = tf.arg_max(pred,1)
bool_pred = tf.equal(tf.arg_max(tf_Y,1),y_pred)
accuracy = tf.reduce_mean(tf.cast(bool_pred,tf.float32)) # 準(zhǔn)確率
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for epoch in range(1000): # 迭代1000個(gè)周期
for batch_xs,batch_ys in generatebatch(X,Y,Y.shape[0],batch_size): # 每個(gè)周期進(jìn)行MBGD算法
sess.run(train_step,feed_dict={tf_X:batch_xs,tf_Y:batch_ys})
if(epoch%100==0):
res = sess.run(accuracy,feed_dict={tf_X:X,tf_Y:Y})
print (epoch,res)
res_ypred = y_pred.eval(feed_dict={tf_X:X,tf_Y:Y}).flatten() # 只能預(yù)測一批樣本,不能預(yù)測一個(gè)樣本
print res_ypred
(0, 0.36338341)
(100, 0.96828049)
(200, 0.99666113)
(300, 0.99554813)
(400, 0.99888706)
(500, 0.99777406)
(600, 0.9961046)
(700, 0.99666113)
(800, 0.99499166)
(900, 0.99888706)
[0 1 2 ..., 8 9 8]
在第100次個(gè)batch size 迭代時(shí),準(zhǔn)確率就快速接近收斂了,這得歸功于Batch Normalization 的作用!需要注意的是,這個(gè)模型還不能用來預(yù)測單個(gè)樣本,因?yàn)樵谶M(jìn)行BN層計(jì)算時(shí),單個(gè)樣本的均值和方差都為0,會得到相反的預(yù)測效果,解決方法詳見歸一化層。
from sklearn.metrics import accuracy_score
print accuracy_score(Y_data,res_ypred.reshape(-1,1))
0.998887033945
從初級到高級,理論 + 實(shí)戰(zhàn),一站式深度了解 TensorFlow!
本課程面向深度學(xué)習(xí)開發(fā)者,講授如何利用 TensorFlow 解決圖像識別、文本分析等具體問題。課程跨度為 10 周,將從 TensorFlow 的原理與基礎(chǔ)實(shí)戰(zhàn)技巧開始,一步步教授學(xué)員如何在 TensorFlow 上搭建 CNN、自編碼、RNN、GAN 等模型,并最終掌握一整套基于 TensorFlow 做深度學(xué)習(xí)開發(fā)的專業(yè)技能。
兩名授課老師佟達(dá)、白發(fā)川身為 ThoughtWorks 的資深技術(shù)專家,具有豐富的大數(shù)據(jù)平臺搭建、深度學(xué)習(xí)系統(tǒng)開發(fā)項(xiàng)目經(jīng)驗(yàn)。
時(shí)間:每周二、四晚 20:00-21:00
開課時(shí)長:總學(xué)時(shí) 20 小時(shí),分 10 周完成,每周 2 次,每次 1 小時(shí)
線上授課地址:http://www.mooc.ai/
雷鋒網(wǎng)(公眾號:雷鋒網(wǎng))相關(guān)閱讀:
CNN 在基于弱監(jiān)督學(xué)習(xí)的圖像分割中的應(yīng)用
三年來,CNN在圖像分割領(lǐng)域經(jīng)歷了怎樣的技術(shù)變革?
雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。