一個小目標:構建一個classfier超越 lenet5!(model_1)

閒來無事(好像也不閒啊)想從零開始構建一個model在mnist 上超過lenet5而且只訓練1000steps,利用這兩年看的論文,還是有信心的,畢竟lenet5 是20年前的模型啊!

 

首先看下baseline: 

 

emmmm,還是很高的。

 

先說說想法: 我想搞個 inception 那樣的block 爲啥呢因爲我覺着 1.一個block裏花樣多一些有利於提取不同尺度下的特徵,而且某種角度上看 inception就是resnet的跨層連接的變種。

首先構建block:

 

 

def block1(x,block_name):

    mw1=get_weight_variable([3,3,1,32],block_name+"_mW1weights")

    mw21=get_weight_variable([1,5,1,32],block_name+"_mW2weights1")
    mw22=get_weight_variable([5,1,32,32],block_name+"_mW2weights2")
    mb2=get_bias_variable([32],block_name+"_mb2")
    mwn=get_weight_variable([3,3,33,32],block_name+"_mWnweights")

    module1_out=conv2d(x,mw1)
    module2_out=conv2d(x,mw21)
    module2_out=conv2d(module2_out,mw22)
    module2_out+=mb2
    module3_out=pooling2d(x,[1,5,5,1],[1,1,1,1])
    module_out=module1_out+module2_out
    module_out=tf.concat([module_out,module3_out],3)
    return conv2d(module_out,mwn)

def block2(x,block_name):
    mw1=get_weight_variable([3,3,32,64],block_name+"_mW1weights")

    mw21=get_weight_variable([1,5,32,64],block_name+"_mW2weights1")
    mw22=get_weight_variable([5,1,64,64],block_name+"_mW2weights2")
    mb2=get_bias_variable([64],block_name+"_mb2")
    mwn=get_weight_variable([3,3,96,64],block_name+"_mWnweights")

    module1_out=conv2d(x,mw1,strides=[1,2,2,1])
    module2_out=conv2d(x,mw21)
    module2_out=conv2d(module2_out,mw22,strides=[1,2,2,1])
    module2_out+=mb2
    module3_out=pooling2d(x,[1,5,5,1],[1,2,2,1])
    module_out=module1_out+module2_out
    module_out=tf.concat([module_out,module3_out],3)
    return conv2d(module_out,mwn)

#這裏所有的 conv 均 padding SAME

block 1 和block 2 區別在於 1:filter(卷積核)個數 一個32 一個64,block2 卷積和 pooling 均 用了stride 2來縮小 feature map(一下簡稱 fm)的 W 和H

block結構如下:

爲什麼 branch1 與branch2 用add? 爲了減少參數量....

爲什麼,branch2 加了bias branch1 沒有? 因爲我branch1 忘加了...

有了block 就可以搭模型了!

模型結構如下:

x=tf.placeholder(shape=[None,784],dtype=tf.float32)
y=tf.placeholder(shape=[None,10],dtype=tf.float32)
x_image=tf.reshape(x,[-1,28,28,1])
keep=tf.placeholder(tf.float32)
block1_out=block1(x_image,"block1")
block1_out=tf.nn.swish(block1_out,name="block_1_act")
block1_out=tf.nn.dropout(block1_out,keep)

block2_out=block2(block1_out,"block2")
block2_out=pooling2d(block2_out,[1,3,3,1],[1,2,2,1])
block2_out=tf.nn.swish(block2_out,name="block_2_act")
block2_out=tf.nn.dropout(block2_out,keep)

gcw=get_weight_variable([7,7,64,1024],name="globalconv")
block_out=tf.nn.conv2d(block2_out,gcw,padding="VALID",strides=[1,1,1,1])
block_out=tf.reshape(block_out,[-1,1024])

#softmax
softmax_w=get_weight_variable([1024,10],"softmax_w")
softmax_b=get_bias_variable([10],"softmax_b")
y_out=tf.nn.softmax(tf.matmul(block_out,softmax_w)+softmax_b)

 使用交叉熵作爲 loss

使用 adam lr=1e-4

模型結構大概長這樣:

 

測試集上平均結果在98.5左右

 

改進1. 在輸入時增加 規範化層即 (x-mean)/variance,同時再增加一個3*3的conv增大一些 chennels 再進block

在最後一個7*7的conv後增加activation function

規範化層:

#change 1:normalize input
mean,var=tf.nn.moments(x_image,[1,2],keep_dims=True)
x_image=tf.subtract(x_image,mean)
x_image=tf.divide(x_image,var)

最終 acc 98.91左右,已經非常接近了!

改進2:把最後的conv7*7 和FC用 global average pool +conv1*1 替換

#change3 add glob avg pool  -- bad
# block_out=tf.nn.avg_pool(block2_out,[1,7,7,1],[1,1,1,1],padding="VALID")
# gcw=get_weight_variable([1,1,64,10],name="globalconv")
# block_out=tf.nn.conv2d(block_out,gcw,padding="VALID",strides=[1,1,1,1])

很差,acc 只有0.8幾,應該是fm chennel太少導致特徵不夠

所以我改成了:

gcw1=get_weight_variable([7,7,64,1024],name="globalconv1")
block_out=tf.nn.conv2d(block2_out,gcw1,padding="VALID",strides=[1,1,1,1])
#activate function nuibi
block_out=tf.nn.swish(block_out)
gcw2=get_weight_variable([1,1,1024,10],name="globalconv2")
block_out=tf.nn.conv2d(block_out,gcw2,padding="VALID",strides=[1,1,1,1])

conv7*7 加conv1*1 

用 conv 1*1 替換 之前的FC

感覺提升不明顯(但是換種角度想,參數量比fc下降了呀)

最差結果在98.6 最好的結果99.2 已經超越kaggle了!

 

之後在訓練策略上改變了下,前800 step batchsize=128 後 200 step batchsize 喪心病狂到512

前900 step 還用 adam 後100步用 sgd lr=1e-14 微調

最終結果....

訓練了幾次結果比較穩定在 99.05左右,emmmm 勉強算是超越了,之後準備在模型結構上改下試試。

代碼在:

https://github.com/lordrebel/beatLenet5/tree/master model1.py

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章