卷積神經(jīng)網(wǎng)絡(luò)VGG 論文細(xì)讀 + Tensorflow實(shí)現(xiàn)

一. 背景介紹

VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION

是牛津大學(xué)計(jì)算機(jī)視覺實(shí)驗(yàn)室參加2014年ILSVRC(ImageNet Large Scale Visual Recognition Challenge)比賽的網(wǎng)絡(luò)結(jié)構(gòu)。解決ImageNet中的1000類圖像分類和localization。

分類稀颁、定位响鹃、檢測蜕提、分割

實(shí)驗(yàn)結(jié)果是VGGNet斬獲了2014年ILSVRC分類第二宴抚,定位第一梢什。(當(dāng)年分類第一是GoogleNet布轿,后續(xù)會(huì)介紹)

Oxford Visual Geometry Group

Robotics Research Group

Paper link

二. Abstract

Abstract
1.VGGNet 探索的是神經(jīng)網(wǎng)絡(luò)的深度(depth)與其性能之間的關(guān)系哮笆。

VGG通過反復(fù)堆疊3×3的小型卷積核和2×2的最大池化層,VGG成功構(gòu)建了16-19層的卷積神經(jīng)網(wǎng)絡(luò)汰扭。是當(dāng)時(shí)在論文發(fā)表前最深的深度網(wǎng)絡(luò)稠肘。實(shí)際上,VGG在探索深度對神經(jīng)網(wǎng)絡(luò)影響的同時(shí)萝毛,其實(shí)本身廣度也是很深的项阴。那么:

神經(jīng)網(wǎng)絡(luò)的深度和廣度對其本身的影響是什么呢?

  • 卷積核的種類對應(yīng)了網(wǎng)絡(luò)的廣度笆包,卷積層數(shù)對應(yīng)了網(wǎng)絡(luò)的深度环揽。這兩者對網(wǎng)絡(luò)的擬合都有影響。但是在現(xiàn)代深度學(xué)習(xí)中庵佣,大家普遍認(rèn)為深度比廣度的影響更加高歉胶。
  • 寬度即卷積核的種類個(gè)數(shù),在LeNet那篇文章里我們說了巴粪,權(quán)值共享(每個(gè)神經(jīng)元對應(yīng)一塊局部區(qū)域通今,如果局部區(qū)域是10*10,那么就有100的權(quán)重參數(shù)验毡,但如果我們把每個(gè)神經(jīng)元的權(quán)重參數(shù)設(shè)置為一樣衡创,相當(dāng)于每個(gè)神經(jīng)元用的是同一個(gè)卷積核去卷積圖像,最終兩層間的連接只有 100 個(gè)參數(shù) 晶通!)可以大大減少我們的訓(xùn)練參數(shù),但是由于使用了同一個(gè)卷積核哟玷,最終特征個(gè)數(shù)太少狮辽,效果也不會(huì)好一也,所以一般神經(jīng)網(wǎng)絡(luò)都會(huì)有多個(gè)卷積核,這里說明寬度的增加在一開始對網(wǎng)絡(luò)的性能提升是有效的喉脖。但是椰苟,隨著廣度的增加,對網(wǎng)絡(luò)整體的性能其實(shí)是開始趨于飽和树叽,并且有下降趨勢舆蝴,因?yàn)檫^多的特征(一個(gè)卷積核對應(yīng)發(fā)現(xiàn)一種特征)可能對帶來噪聲的影響。
  • 深度即卷積層的個(gè)數(shù)题诵,對網(wǎng)絡(luò)的性能是極其重要的洁仗,ResNet已經(jīng)表明越深的深度網(wǎng)絡(luò)性能也就越好。深度網(wǎng)絡(luò)自然集成了低性锭、中赠潦、高層特征。多層特征可以通過網(wǎng)絡(luò)的堆疊的數(shù)量(深度)來豐富其表達(dá)草冈。挑戰(zhàn)imagenet數(shù)據(jù)集的優(yōu)秀網(wǎng)絡(luò)都是采用較深的模型她奥。網(wǎng)絡(luò)的深度很重要,但是否能夠簡單的通過增加更多的網(wǎng)絡(luò)層次學(xué)習(xí)更好的網(wǎng)絡(luò)怎棱?這個(gè)問題的障礙就是臭名昭著的梯度消失(爆炸)問題哩俭,這從根本上阻礙了深度模型的收斂。
  • 增加更多的卷積核可以發(fā)現(xiàn)更多的特征拳恋,但是特征是需要進(jìn)行組合的携茂,只有知道了特征之間的關(guān)系才能夠更好的表達(dá)圖片內(nèi)容,而增加深度就是組合特征的過程诅岩。
2. VGG結(jié)構(gòu)全部都采用較小的卷積核(3×3讳苦,部分1×1)

在VGG出現(xiàn)之前的深度網(wǎng)絡(luò),比如ZFNet或Overfeat普遍都采用了7×7和11×11的卷積核吩谦。VGG通篇全部采用很小的卷積核鸳谜。我們再回顧一下在深度學(xué)習(xí)中卷積核的感受野的作用。


卷積核的感受野
如何選擇卷積核的大惺酵ⅰ咐扭?越大越好還是越小越好?

答案是小而深滑废,單獨(dú)較小的卷積核也是不好的蝗肪,只有堆疊很多小的卷積核,模型的性能才會(huì)提升蠕趁。

  • 如上圖所示薛闪,CNN的卷積核對應(yīng)一個(gè)感受野,這使得每一個(gè)神經(jīng)元不需要對全局圖像做感受俺陋,每個(gè)神經(jīng)元只感受局部的圖像區(qū)域豁延,然后在更高層昙篙,將這些感受不同局部的神經(jīng)元綜合起來就可以得到全局信息。這樣做的一個(gè)好處就是可以減少大量訓(xùn)練的參數(shù)诱咏。
  • VGG經(jīng)常出現(xiàn)多個(gè)完全一樣的3×3的卷積核堆疊在一起的情況苔可,這些多個(gè)小型卷積核堆疊的設(shè)計(jì)其實(shí)是非常有效的。如下圖所示袋狞,兩個(gè)3×3的卷積層串聯(lián)相當(dāng)于1個(gè)5×5的卷積層焚辅,即一個(gè)像素會(huì)和周圍5×5的像素產(chǎn)生關(guān)聯(lián),可以說感受野是5×5苟鸯。同時(shí)同蜻,3個(gè)串聯(lián)的3×3卷積層串聯(lián)的效果相當(dāng)于一個(gè)7×7的卷積層。除此之外倔毙,3個(gè)串聯(lián)的3×3的卷積層擁有比一個(gè)7×7更少的參數(shù)量埃仪,只有后者的 (3×3×3) / (7×7) = 55%。最重要的是3個(gè)3×3的卷積層擁有比一個(gè)7×7的卷積層更多的非線性變換(前者可以使用三次ReLu激活陕赃,而后者只有一次)卵蛉。


3.VGG獲得了2014年ILSVRC分類第二,定位第一么库。(當(dāng)年分類第一是GoogleNet傻丝,后續(xù)會(huì)介紹)

三. Architecture

architecture

1. vgg模型的輸入是固定的224×224的彩色RGB通道圖像。
2. 輸入做的唯一一個(gè)數(shù)據(jù)預(yù)處理就是各自減去 RGB 3個(gè)通道的均值
3. 使用的是非常小的3×3的卷積核诉儒。
4. 其中一個(gè)結(jié)構(gòu)采用了一些1×1的卷積核葡缰。

1×1的卷積核到底有什么作用呢?

  • 1×1的卷積核和正常的濾波器完全是一樣的忱反,只不過它不再感受一個(gè)局部區(qū)域泛释,不考慮像素與像素之間的關(guān)系。1×1的卷積本身就是不同feature channel的線性疊加温算。1×1的卷積最早出現(xiàn)在Network in Network這篇文章中怜校,在Google的inception結(jié)構(gòu)中也采用了大量1×1的卷積。
  • NIN論文中解釋1×1的卷積實(shí)現(xiàn)了多個(gè)feature map的結(jié)合注竿,從而整合了不同通道間的信息茄茁。(個(gè)人認(rèn)為這個(gè)作用并不是特點(diǎn),因?yàn)槠渌笮〉木矸e核也可以實(shí)現(xiàn))
  • 1×1的卷積可以實(shí)現(xiàn)通道數(shù)量的升維和降維巩割。并且是低成本的特征變換(計(jì)算量比3×3小很多)裙顽。是一個(gè)性價(jià)比很高的聚合操作。怎么理解1×1是性價(jià)比很高的升降通道數(shù)的操作呢宣谈?
    (以google inception為例)


    原始

原始結(jié)構(gòu):
參數(shù):(1×1×192×64) + (3×3×192×128) + (5×5×192×32) = 153600
最終輸出的feature map:64+128+32+192 = 416

加入不同channel的1×1卷積后:
參數(shù):1×1×192×64+(1×1×192×96+3×3×96×128)+(1×1×192×16+5×5×16×32)=15872
最終輸出的feature map: 64+128+32+32=256

所以加入1×1的卷積后愈犹,在降低大量運(yùn)算的前提下,降低了維度蒲祈。

5. 卷積步長是一個(gè)像素
6.采用最大池化層
7. 不是所有卷積層后面都接一個(gè)池化層甘萧。(和之前的網(wǎng)絡(luò)有區(qū)別萝嘁,是反復(fù)堆疊幾個(gè)3×3的卷積)
8. 最大池化是2×2梆掸,步長為2.
9. 最后接了3個(gè)全連接層
10. 前兩個(gè)全連接都是4096扬卷,最后一個(gè)根據(jù)imagenet1000類定為1000個(gè)輸出
11. 分類層是softmax
12. 所有隱層都進(jìn)行了ReLU激活。
13. 只有一個(gè)地方使用了LRN酸钦,并且實(shí)驗(yàn)表明LRN沒有任何用處怪得。

四. ConvNet Configurations

ConvNet Configurations

參數(shù)數(shù)量
  • VGG全部使用了3×3的卷積核和2×2的池化核,通過不斷加深網(wǎng)絡(luò)結(jié)構(gòu)來提升性能卑硫。上圖為VGG各個(gè)級(jí)別的網(wǎng)絡(luò)結(jié)構(gòu)圖徒恋。
  • VGG各種級(jí)別的結(jié)構(gòu)都采用了5段卷積,每一段有一個(gè)或多個(gè)卷積層欢伏。同時(shí)每一段的尾部都接著一個(gè)最大池化層來縮小圖片尺寸入挣。每一段內(nèi)的卷積核數(shù)量一致,越靠后的卷積核數(shù)量越多 64-128-256-512-512硝拧。經(jīng)常出現(xiàn)多個(gè)完全一樣的卷積層堆疊在一起的情況径筏。
  • A-LRN結(jié)構(gòu)使用了LRN,結(jié)果表明并沒有什么用處障陶。
  • C 結(jié)構(gòu)比B多了幾個(gè)1×1的卷積滋恬。在VGG里,1×1的卷積意義主要是線性變換抱究,輸入輸出通道數(shù)量并沒有變化恢氯。沒有發(fā)生降維。所以作者認(rèn)為1×1沒有3×3好鼓寺,大一些的卷積核可以學(xué)到更大的空間特征勋拟。
  • A-E 每一級(jí)網(wǎng)絡(luò)逐漸變深,但是參數(shù)并沒有變多很多妈候。這是因?yàn)閰?shù)量主要消耗在最后3個(gè)全連接層敢靡,卷積雖然深但是參數(shù)消耗并不多。但是訓(xùn)練耗時(shí)的仍然是卷積州丹,因其計(jì)算量大醋安。
  • D E就是我們經(jīng)常說的VGG-16和VGG-19

五. Training


這個(gè)部分是VGG當(dāng)時(shí)是怎么訓(xùn)練的具體過程,有很多值得借鑒的地方墓毒。
1. 使用mini-batch的梯度下降法吓揪,并且是帶動(dòng)量的。batch_size設(shè)置為256所计,動(dòng)量是0.9柠辞。
2. 前兩個(gè)全連接使用了dropout,值是0.5, 用來緩解過擬合主胧。
3. 學(xué)習(xí)率初始設(shè)置為0.01叭首,衰減系數(shù)為10习勤,每當(dāng)驗(yàn)證集上準(zhǔn)確率不再變好時(shí),會(huì)降低學(xué)習(xí)率焙格。學(xué)習(xí)率一共被衰減3次图毕。總共訓(xùn)練了74個(gè)epoch眷唉,370k個(gè)iteration予颤。

VGG的參數(shù)初始化方式是怎么樣的?

  • 上圖中間紅框部分作者介紹了VGG訓(xùn)練時(shí)參數(shù)的初始化方式冬阳,這個(gè)部分比較有意思蛤虐。作者認(rèn)為這么深的網(wǎng)絡(luò)(論文發(fā)表前最深)訓(xùn)練收斂是很困難的,必須借助有效的參數(shù)初始化方式肝陪。
  • 作者先訓(xùn)練上面網(wǎng)絡(luò)結(jié)構(gòu)中的A結(jié)構(gòu)驳庭,A收斂之后呢,將A的網(wǎng)絡(luò)權(quán)重保存下來氯窍,再復(fù)用A網(wǎng)絡(luò)的權(quán)重來初始化后面幾個(gè)簡單模型饲常。
  • 復(fù)用A的網(wǎng)絡(luò)權(quán)重,只是前四個(gè)卷積層荞驴,以及后三層全連接層不皆,其它的都是隨機(jī)初始化。
  • 隨機(jī)初始化熊楼,均值是0霹娄,方差是0.01。bias是0.

六. Image Size

在訓(xùn)練和測試階段鲫骗,VGG都采用了Multi-scale的方式犬耻。


training

testing

VGG的Multi-Scale方法

  • VGG在訓(xùn)練階段使用了Multi-Scale的方法做數(shù)據(jù)增強(qiáng),將原始圖片縮放到不同的尺寸S执泰,然后再隨機(jī)裁剪224×224的圖片枕磁,這樣能增加很多數(shù)據(jù)量,對于防止模型過擬合有很不錯(cuò)的效果术吝。
  • 實(shí)驗(yàn)中计济,作者令S在[256, 512]這個(gè)區(qū)間,使用Multi-Scale獲得了多個(gè)版本的數(shù)據(jù)排苍,并將多個(gè)版本的數(shù)據(jù)合在一起訓(xùn)練沦寂。
  • 在測試時(shí),也采用了Multi-Scale的方法淘衙,將圖像scale到一個(gè)尺寸Q传藏,并將圖片輸入卷積網(wǎng)絡(luò)計(jì)算,然后再最后一個(gè)卷積層使用滑窗的方式進(jìn)行分類預(yù)測,將不同窗口的分類結(jié)果平均毯侦,再將不同尺寸Q的結(jié)果平均哭靖,得到最后的結(jié)果。這樣可以提高數(shù)據(jù)的利用率和預(yù)測準(zhǔn)確率侈离。
  • 下圖是VGG各種不同scale的訓(xùn)練結(jié)果试幽,融合了Multi-Scale的D和E是最好的。


七. Tensorflow實(shí)現(xiàn)簡單的VGG-16的結(jié)構(gòu)

本部分整理自《Tensorflow實(shí)戰(zhàn)》

1. 實(shí)現(xiàn)卷積操作函數(shù)

VGG包含很多卷積霍狰,函數(shù)conv_op創(chuàng)建卷積層抡草,并把本層參數(shù)存入?yún)?shù)列表饰及。這樣可以方便后面VGG結(jié)構(gòu)中多次使用卷積操作蔗坯。

輸入?yún)?shù)

  • input_op: 輸入tensor,是一個(gè)4D的tensor燎含,可以理解為image batch宾濒。shape=[batch, in_height, in_width, in_channels],即:[訓(xùn)練時(shí)一個(gè)batch的圖片數(shù)量, 圖片高度, 圖片寬度, 圖像通道數(shù)]
  • kh:卷積核的高
  • kw:卷積核的寬
  • n_out:輸出通道數(shù)屏箍;這三個(gè)參數(shù)恰好定義了一個(gè)卷積核的參數(shù)绘梦,卷積核kernel的參數(shù)即為: shape=[filter_height, filter_width, in_channels, out_channels],即:[卷積核的高度赴魁,卷積核的寬度卸奉,圖像通道數(shù),卷積核個(gè)數(shù)]
  • dh:卷積的步長高
  • dw:卷積的步長寬颖御。 進(jìn)行卷積操作時(shí)榄棵,我們除了需要輸入的tensor和卷積核參數(shù)外,還需要定義卷積的步長strides潘拱,strides卷積時(shí)在每一維上的步長疹鳄,strides[0]=strides[3]=1。
  • p:參數(shù)列表芦岂。將卷積核和bias的參數(shù)寫入p瘪弓,以便后面使用

輸出:
經(jīng)過卷積,和激活函數(shù)的tensor禽最。[batch_size, new_h, new_w, n_out]

def conv_op(input_op, name, kh, kw, n_out, dh, dw, p):
    n_in = input_op.get_shape()[-1].value
    with tf.name_scope(name) as scope:
        kernel = tf.get_variable(scope+'w', shape=[kh, kw, n_in, n_out], dtype = tf.float32,
                                initializer = tf.contrib.layers.xavier_initializer_conv2d())
        conv = tf.nn.conv2d(input_op, kernel, (1, dh, dw, 1), padding = 'SAME')
        bias_init_val = tf.constant(0.0, shape = [n_out], dtype = tf.float32)
        biases = tf.variable(bias_init_val, trainable = True, name = 'b')
        z = tf.nn.bias_add(conv, biases)
        activation = tf.nn.relu(z, name = scope)
        p += [kernel, biases]
        return activation
  • 整體過程非常簡單腺怯,建議熟背這一段代碼。首先獲得輸入的tensor川无,即image batch呛占,并且定義name,卷積核的大小舀透,卷積的步長(輸入?yún)?shù))栓票。
  • 使用get_shape()獲得輸入tensor的輸入通道數(shù)。
  • name_scope將scope內(nèi)生成的variable自動(dòng)命名為name/xxx,用于區(qū)分不同卷積層的組件
  • get_variable()定義卷積核的參數(shù)走贪,注意shape和初始化方式
  • conv2d對輸入tensor佛猛,使用剛剛的卷積核進(jìn)行卷積操作,注意此處定義strides和padding
  • constant定義bias坠狡,注意shape等于輸出通道數(shù)继找。一個(gè)卷積核對應(yīng)一個(gè)輸出通道,對應(yīng)一個(gè)bias逃沿。tf.variable再將其轉(zhuǎn)換成可訓(xùn)練的參數(shù)婴渡。
  • 進(jìn)行relu激活

2. 實(shí)現(xiàn)池化操作函數(shù)

輸入?yún)?shù)

  • input_op: 輸入tensor
  • kh:池化的高
  • kw:池化的寬
  • dh:池化的步長高
  • dw:池化的步長寬。
def maxpool_op(input_op, name, kh, kw, dh, dw):
    return tf.nn.max_pool(input_op,
                          ksize=[1, kh, kw, 1],
                          strides=[1, dh, dw, 1],
                          padding='SAME',
                          name=name)

這部分代碼也很容易理解凯亮,nn.max_pool可以直接使用边臼,需要定義池化的大小ksize,步長strides假消,以及邊界填充方式padding柠并。此部分沒有需要訓(xùn)練的參數(shù)。

3. 定義全連接操作函數(shù)

輸入?yún)?shù)

  • input_op: 輸入的tensor
  • n_out: 輸出向量長度富拗。 全連接只需要這兩個(gè)參數(shù)
def fc_op(input_op, name, n_out, p):
    n_in = input_op.get_shape()[-1].value
    with tf.name_scope(name) as scope:
        kernel = tf.get_variable(scope+"w", shape=[n_in, n_out], dtype=tf.float32,
                                 initializer=tf.contrib.layers.xavier_initializer())
        biases = tf.Variable(tf.constant(0.1, shape=[n_out], dtype=tf.float32), name='b')n
        activation = tf.nn.relu_layer(input_op, kernel, biases, name= scope)
        p += [kernel, biases]
        return activation

此部分代碼也很簡單臼予,全連接層需要訓(xùn)練參數(shù),并且比卷積層更多(卷積層是局部連接)啃沪,同樣獲得輸入圖片tensor的通道數(shù)(向量長度)粘拾,同樣獲得輸入圖片tensor的通道數(shù),注意每個(gè)訓(xùn)練參數(shù)都需要給定初始化值或初始化方式创千。bias利用constant函數(shù)初始化為較小的值0.1,而不是0缰雇, 再做relu非線性變。

4. 根據(jù)論文結(jié)構(gòu)創(chuàng)建VGG16網(wǎng)絡(luò)

input_op是輸入的圖像tensor shape=[batch, in_height, in_width, in_channels]
keep_prob是控制dropout比率的一個(gè)placeholder

def inference_op(input_op,keep_prob):
    # 初始化參數(shù)p列表
    p = []

VGG16包含6個(gè)部分签餐,前面5段卷積寓涨,最后一段全連接,
每段卷積包含多個(gè)卷積層和pooling層.

下面是第一段卷積,包含2個(gè)卷積層和一個(gè)pooling層,
利用前面定義好的函數(shù)conv_op,mpool_op 創(chuàng)建這些層

# 第一段卷積的第一個(gè)卷積層 卷積核3*3氯檐,共64個(gè)卷積核(輸出通道數(shù))戒良,步長1*1
# input_op:224*224*3 輸出尺寸224*224*64
conv1_1 = conv_op(input_op, name="conv1_1", kh=3, kw=3, n_out=64, dh=1,
                      dw=1, p=p)

# 第一段卷積的第2個(gè)卷積層 卷積核3*3,共64個(gè)卷積核(輸出通道數(shù))冠摄,步長1*1
# input_op:224*224*64 輸出尺寸224*224*64
conv1_2 = conv_op(conv1_1, name="conv1_2", kh=3, kw=3, n_out=64, dh=1,
                      dw=1, p=p)

# 第一段卷積的pooling層糯崎,核2*2,步長2*2
# input_op:224*224*64 輸出尺寸112*112*64
pool1 = mpool_op(conv1_2, name="pool1", kh=2, kw=2, dh=2, dw=2)

下面是第2段卷積河泳,包含2個(gè)卷積層和一個(gè)pooling層

# 第2段卷積的第一個(gè)卷積層 卷積核3*3沃呢,共128個(gè)卷積核(輸出通道數(shù)),步長1*1
# input_op:112*112*64 輸出尺寸112*112*128
conv2_1 = conv_op(pool1, name="conv2_1", kh=3, kw=3, n_out=128, dh=1,
                      dw=1, p=p)

# input_op:112*112*128 輸出尺寸112*112*128
conv2_2 = conv_op(conv2_1, name="conv2_2", kh=3, kw=3, n_out=128, dh=1,
                      dw=1, p=p)

# input_op:112*112*128 輸出尺寸56*56*128
pool2 = mpool_op(conv2_2, name="pool2", kh=2, kw=2, dh=2, dw=2)

下面是第3段卷積拆挥,包含3個(gè)卷積層和一個(gè)pooling層

# 第3段卷積的第一個(gè)卷積層 卷積核3*3薄霜,共256個(gè)卷積核(輸出通道數(shù))某抓,步長1*1
# input_op:56*56*128 輸出尺寸56*56*256
conv3_1 = conv_op(pool2, name="conv3_1", kh=3, kw=3, n_out=256, dh=1,
                      dw=1, p=p)

# input_op:56*56*256 輸出尺寸56*56*256
conv3_2 = conv_op(conv3_1, name="conv3_2", kh=3, kw=3, n_out=256, dh=1,
                      dw=1, p=p)

# input_op:56*56*256 輸出尺寸56*56*256
conv3_3 = conv_op(conv3_2, name="conv3_3", kh=3, kw=3, n_out=256, dh=1,
                      dw=1, p=p)

# input_op:56*56*256 輸出尺寸28*28*256
pool3 = mpool_op(conv3_3, name="pool3", kh=2, kw=2, dh=2, dw=2)

下面是第4段卷積,包含3個(gè)卷積層和一個(gè)pooling層

# 第3段卷積的第一個(gè)卷積層 卷積核3*3惰瓜,共512個(gè)卷積核(輸出通道數(shù))否副,步長1*1
# input_op:28*28*256 輸出尺寸28*28*512
conv4_1 = conv_op(pool3, name="conv4_1", kh=3, kw=3, n_out=512, dh=1,
                      dw=1, p=p)

# input_op:28*28*512 輸出尺寸28*28*512
conv4_2 = conv_op(conv4_1, name="conv4_2", kh=3, kw=3, n_out=512, dh=1,
                      dw=1, p=p)

# input_op:28*28*512 輸出尺寸28*28*512
conv4_3 = conv_op(conv4_2, name="conv4_3", kh=3, kw=3, n_out=512, dh=1,
                      dw=1, p=p)

# input_op:28*28*512 輸出尺寸14*14*512
pool4 = mpool_op(conv4_3, name="pool4", kh=2, kw=2, dh=2, dw=2)

前面4段卷積發(fā)現(xiàn),VGG16每段卷積都是把圖像面積變?yōu)?/4崎坊,但是通道數(shù)翻倍, 因此圖像tensor的總尺寸縮小一半备禀。
下面是第5段卷積,包含3個(gè)卷積層和一個(gè)pooling層

# 第5段卷積的第一個(gè)卷積層 卷積核3*3奈揍,共512個(gè)卷積核(輸出通道數(shù))曲尸,步長1*1
# input_op:14*14*512 輸出尺寸14*14*512
conv5_1 = conv_op(pool4, name="conv5_1", kh=3, kw=3, n_out=512, dh=1,
                      dw=1, p=p)

# input_op:14*14*512 輸出尺寸14*14*512
conv5_2 = conv_op(conv5_1, name="conv5_2", kh=3, kw=3, n_out=512, dh=1,
                      dw=1, p=p)

# input_op:14*14*512 輸出尺寸14*14*512
conv5_3 = conv_op(conv5_2, name="conv5_3", kh=3, kw=3, n_out=512, dh=1,
                      dw=1, p=p)

# input_op:28*28*512 輸出尺寸7*7*512
pool5 = mpool_op(conv5_3, name="pool5", kh=2, kw=2, dh=2, dw=2)

下面要經(jīng)過全連接,需將第五段卷積網(wǎng)絡(luò)的結(jié)果扁平化, reshape將每張圖片變?yōu)?7512=25088的一維向量

shp = pool5.get_shape()
flattened_shape = shp[1].value * shp[2].value * shp[3].value
# tf.reshape(tensor, shape, name=None) 將tensor變換為參數(shù)shape的形式男翰。
resh1 = tf.reshape(pool5, [-1, flattened_shape], name="resh1")

第一個(gè)全連接層另患,是一個(gè)隱藏節(jié)點(diǎn)數(shù)為4096的全連接層,后面接一個(gè)dropout層奏篙,訓(xùn)練時(shí)保留率為0.5柴淘,預(yù)測時(shí)為1.0

fc6 = fc_op(resh1, name="fc6", n_out=4096, p=p)
fc6_drop = tf.nn.dropout(fc6, keep_prob, name="fc6_drop")

第2個(gè)全連接層,是一個(gè)隱藏節(jié)點(diǎn)數(shù)為4096的全連接層秘通,后面接一個(gè)dropout層,訓(xùn)練時(shí)保留率為0.5敛熬,預(yù)測時(shí)為1.0

fc7 = fc_op(fc6_drop, name="fc7", n_out=4096, p=p)
fc7_drop = tf.nn.dropout(fc7, keep_prob, name="fc7_drop")

最后是一個(gè)1000個(gè)輸出節(jié)點(diǎn)的全連接層肺稀,利用softmax輸出分類概率,argmax輸出概率最大的類別应民。

fc8 = fc_op(fc7_drop, name="fc8", n_out=1000, p=p)
softmax = tf.nn.softmax(fc8)
predictions = tf.argmax(softmax, 1)
return predictions, softmax, fc8, p

個(gè)人原創(chuàng)作品话原,轉(zhuǎn)載需征求本人同意

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市诲锹,隨后出現(xiàn)的幾起案子繁仁,更是在濱河造成了極大的恐慌,老刑警劉巖归园,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件黄虱,死亡現(xiàn)場離奇詭異,居然都是意外死亡庸诱,警方通過查閱死者的電腦和手機(jī)捻浦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來桥爽,“玉大人朱灿,你說我怎么就攤上這事∧扑模” “怎么了盗扒?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jī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
  • 文/蒼蘭香墨 我猛地睜開眼宠页,長吁一口氣:“原來是場噩夢啊……” “哼左胞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起举户,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤烤宙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后俭嘁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體躺枕,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有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
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽趋惨。三九已至,卻和暖如春惦蚊,著一層夾襖步出監(jiān)牢的瞬間器虾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國打工蹦锋, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留兆沙,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓晕粪,卻偏偏與公主長得像挤悉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子巫湘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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

  • CNN on TensorFlow 本文大部分內(nèi)容均參考于: An Intuitive Explanation o...
    _Randolph_閱讀 7,698評(píng)論 2 31
  • 卷積神經(jīng)網(wǎng)絡(luò)是基于人工神經(jīng)網(wǎng)絡(luò)的深度機(jī)器學(xué)習(xí)方法,成功應(yīng)用于圖像識(shí)別領(lǐng)域昏鹃。CNN采用了局部連接和權(quán)值共享尚氛,保持了網(wǎng)...
    dopami閱讀 1,036評(píng)論 0 0
  • 文章作者:Tyan博客:noahsnail.com | CSDN | 簡書 聲明:作者翻譯論文僅為學(xué)習(xí),如有侵權(quán)請...
    SnailTyan閱讀 9,115評(píng)論 0 16
  • 文章主要分為:一洞渤、深度學(xué)習(xí)概念阅嘶;二、國內(nèi)外研究現(xiàn)狀载迄;三讯柔、深度學(xué)習(xí)模型結(jié)構(gòu);四护昧、深度學(xué)習(xí)訓(xùn)練算法魂迄;五、深度學(xué)習(xí)的優(yōu)點(diǎn)...
    艾剪疏閱讀 21,835評(píng)論 0 58
  • 【超級(jí)貝貝】2017.9.9學(xué)習(xí)力踐行day117 幼兒園回來第三天惋耙,一回來就興奮地和我說捣炬,媽媽我學(xué)了新的手指謠熊昌,...
    huina_fb9e閱讀 182評(píng)論 0 0