天天看點

VGGNet-16(D級)實作--TensorFlowVGGNet

VGGNet

優勢: 探索卷積神經網絡的深度與其性能之間的關系—>反複堆疊3 * 3 kernel 和 2 * 2 最大池化層—>成功建構了16~19層深度卷積神經網絡—>遷移和泛化能力強,網絡結構簡單

[外鍊圖檔轉存失敗(img-JWb9qJR3-1567153752204)(attachment:image.png)]

  1. A —> E 六個級别網絡結構

    [外鍊圖檔轉存失敗(img-gmPBgLMv-1567153752204)(attachment:%E6%8D%95%E8%8E%B72.PNG)]

#建構VGGNet-16(D級)
import tensorflow as tf
import time 
from datetime import datetime
import math
           
# 定義卷積層函數----->相比于AlexNet網絡有了進一步的簡化
def conv_op(input_op,name,kh,kw,n_out,dh,dw,parameters):
    '''
    input_op:輸入的tensor
    name:tensor名稱
    kh:kernel的高
    kw:kernel的寬
    n_out:tensor輸出通道數
    dh:步長的高
    dw:步長的寬
    parameters:參數清單
    '''
    n_in = input_op.get_shape()[-1].value#擷取tensor的通道數
    
    with tf.name_scope(name) as scope:
        #kernel進行初始化---->tf.contrib.layers.xavier_initializer_conv2d()
        kernel = tf.get_variable(scope+'w',
                                 shape=[kh,kw,n_in,n_out],dtype=tf.float32,
                                 initializer=tf.contrib.layers.xavier_initializer_conv2d())
        #biases初始化
        biases = tf.Variable(tf.constant(0.0,shape=[n_out],dtype=tf.float32),
                             trainable=True,name='bias')
        
        #計算卷積并激活relu
        conv = tf.nn.relu(
            tf.nn.bias_add(tf.nn.conv2d(input_op,kernel,[1,dh,dw,1],padding='SAME'),
                           biases),name=scope)
        parameters += [kernel,biases]
        
        return conv
           
# 定義全連接配接層函數
def fc_op(input_op,name,n_out,parameters):
    n_in = input_op.get_shape()[-1].value
    
    with tf.name_scope(name) as scope:
        kerenl = 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='bias')
        activation = tf.nn.relu_layer(input_op,kerenl,biases,name=scope)
        parameters += [kerenl,biases]
        
        return activation
           
# 定義最大池化層函數
def m_max_pool(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)
           
# 定義VGGNet的inference
def inference(input_op,keep_prop):
    '''
    keep_prop: dropout 政策的保留率
    '''
    parameters = []
    
    conv1_1 = conv_op(input_op,name='conv1_1',kh=3,kw=3,n_out=64,dh=1,dw=1,parameters=parameters)
    
    conv1_2 = conv_op(conv1_1,name='conv1_2',kh=3,kw=3,n_out=64,dh=1,dw=1,parameters=parameters)
    
    pool1 = m_max_pool(conv1_2,name='pool1',kh=2,kw=2,dh=2,dw=2)
    
    conv2_1 = conv_op(pool1,name='conv2_1',kh=3,kw=3,n_out=128,dh=1,dw=1,parameters=parameters)
    
    conv2_2 = conv_op(conv2_1,name='conv2_2',kh=3,kw=3,n_out=128,dh=1,dw=1,parameters=parameters)
    
    pool2 = m_max_pool(conv2_2,name='pool2',kh=2,kw=2,dh=2,dw=2)
    
    conv3_1 = conv_op(pool2,name='conv3_1',kh=3,kw=3,n_out=256,dh=1,dw=1,parameters=parameters)
    
    conv3_2 = conv_op(conv3_1,name='conv3_2',kh=3,kw=3,n_out=256,dh=1,dw=1,parameters=parameters)
    
    conv3_3 = conv_op(conv3_2,name='conv3_3',kh=3,kw=3,n_out=256,dh=1,dw=1,parameters=parameters)
    
    pool3 = m_max_pool(conv3_3,name='pool3',kh=2,kw=2,dh=2,dw=2)    
    
    conv4_1 = conv_op(pool3,name='conv4_1',kh=3,kw=3,n_out=512,dh=1,dw=1,parameters=parameters)
    
    conv4_2 = conv_op(conv4_1,name='conv4_2',kh=3,kw=3,n_out=512,dh=1,dw=1,parameters=parameters)
    
    conv4_3 = conv_op(conv4_2,name='conv4_3',kh=3,kw=3,n_out=512,dh=1,dw=1,parameters=parameters)
    
    pool4 = m_max_pool(conv4_3,name='pool4',kh=2,kw=2,dh=2,dw=2)      
    
    conv5_1 = conv_op(pool4,name='conv5_1',kh=3,kw=3,n_out=512,dh=1,dw=1,parameters=parameters)
    
    conv5_2 = conv_op(conv5_1,name='conv5_2',kh=3,kw=3,n_out=512,dh=1,dw=1,parameters=parameters)
    
    conv5_3 = conv_op(conv5_2,name='conv5_3',kh=3,kw=3,n_out=512,dh=1,dw=1,parameters=parameters)
    
    pool5 = m_max_pool(conv5_3,name='pool5',kh=2,kw=2,dh=2,dw=2)

    conv_shape = pool5.get_shape()
    
    flatten_shape = conv_shape[1].value * conv_shape[2].value * conv_shape[3].value
    
    resh1 = tf.reshape(pool5,[-1,flatten_shape],name='resh1')

    fc_6 = fc_op(resh1,name='fc_6',n_out=4096,parameters=parameters)

    fc_6drop = tf.nn.dropout(fc_6,rate=1-keep_prop,name='fc_6drop')
    
    fc_7 = fc_op(fc_6drop,name='fc_7',n_out=4096,parameters=parameters)

    fc_7drop = tf.nn.dropout(fc_7,rate=1-keep_prop,name='fc_7drop')
    
    fc_8 = fc_op(fc_7drop,name='fc_8',n_out=1000,parameters=parameters)

    softmax = tf.nn.softmax(fc_8)
    
    predictions = tf.argmax(softmax,1)
    
    return predictions,softmax,fc_8,parameters
    
    
           
# 測評
def time_tensorflow_run(session,target,feed,info_string):
    '''
    session:視窗
    target:評測對象
    feed:輸入的資料
    info_string:對象名稱
    '''
    num_steps_burn_in = 10#程式熱身
    #用于計算方差的兩個參數
    total_duration = 0.0
    total_duration_squared = 0.0
    
    for i in range(num_batches + num_steps_burn_in):
        start_time = time.time()
        _ = session.run(target,feed_dict=feed)
        duration = time.time() - start_time
        if i >= num_steps_burn_in:
            if not i % 10:
                print('%s:step %d,duration = %.3f'%(
                    datetime.now(),i - num_steps_burn_in,duration))
            total_duration += duration
            total_duration_squared += duration * duration
            
    #計算平均耗時和标準差
    mean_time = total_duration / num_batches
    sd = math.sqrt(total_duration_squared / num_batches - mean_time * mean_time)
    print('%s: %s across %d steps,%.3f +/- %.3f sec / batch'%(
        datetime.now(),info_string,num_batches,mean_time,sd))
           
# 建構一個自己的資料集(使用ImageNet資料集訓練過程十分耗時)
def run_benchmark():
    #定義一個新的圖進行計算
    with tf.Graph().as_default():
        image_size = 224
        #構造随機tensor
        images = tf.Variable(tf.random_normal([batch_size,
                                               image_size,
                                               image_size,3],
                                               dtype=tf.float32,stddev=0.1))
        keep_prop = tf.placeholder(tf.float32)
        predictions,softmax,fc_8,parameters = inference(images,keep_prop)
        
        init = tf.global_variables_initializer()
        sess = tf.Session()
        sess.run(init)
     
        time_tensorflow_run(sess,predictions,{keep_prop:1.0},'Forward')
        
        objetive = tf.nn.l2_loss(fc_8)#計算fc_8正則化損失
  
        grad = tf.gradients(objetive,parameters)
        time_tensorflow_run(sess,grad,{keep_prop:0.5},'Forward-Backward')
           
batch_size = 8
num_batches = 10
run_benchmark()
           
Tensor("pool5:0", shape=(8, 7, 7, 512), dtype=float32)
Tensor("resh1:0", shape=(8, 25088), dtype=float32)
Tensor("fc_6:0", shape=(8, 4096), dtype=float32)
Tensor("fc_7:0", shape=(8, 4096), dtype=float32)
Tensor("fc_8:0", shape=(8, 1000), dtype=float32)
Tensor("fc_8:0", shape=(8, 1000), dtype=float32)
2019-08-22 16:47:58.296828:step 0,duration = 1.367
2019-08-22 16:48:08.086028: Forward across 10 steps,1.115 +/- 0.227 sec / batch
Tensor("L2Loss:0", shape=(), dtype=float32)
2019-08-22 16:48:58.554828:step 0,duration = 4.645
2019-08-22 16:49:39.599828: Forward-Backward across 10 steps,4.569 +/- 0.126 sec / batch
           

繼續閱讀