殘差網絡實現

殘差網絡可以解決多層神經網絡問題,這裏使用mnist數據集實現一下殘差網絡。
網絡模型如下:
在這裏插入圖片描述
該代碼可以在普通VGG網絡中隨意添加殘差層(ResNet(x1, x2, layer_name)),方便建立自己的網絡模型。

代碼:

# tensorflow基於mnist數據集上的VGG11網絡,可以直接運行
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
import numpy as np
import os


def maxPoolLayer(x, layer_name, ksize=2, strides=2):
    '''池化層'''
    '''池化窗口大小:ksize=[1,height,width,1]'''
    '''滑動步長大小:strides=[batch滑動步長, height方向滑動步長, width方向滑動步長, channels方向滑動步長]'''
    return tf.nn.max_pool(x, ksize=[1, ksize, ksize, 1], strides=[1, strides, strides, 1], padding='SAME', name=layer_name)


def con2d_layer(x, out_chs, ksize, layer_name, strides=1):
    '''卷積層'''
    d_in = x.get_shape()[-1].value
    with tf.variable_scope(layer_name):
        '''卷積核:shape=[filter_height, filter_width, in_channels, out_channels]'''
        w = tf.get_variable('weights', shape=[ksize, ksize, d_in, out_chs],
                            initializer=tf.truncated_normal_initializer(stddev=0.1))  # 初始化權重值
        # '''shape=[out_channels]'''
        b = tf.get_variable('bias', shape=[out_chs],
                            initializer=tf.truncated_normal_initializer(stddev=0.1))  # 初始化偏執值
        y = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(x, w, strides=[1, strides, strides, 1], padding='SAME'), b))  # 卷積運算
    return y


def fc_layer(x, out_kernels, layer_name):
    '''全連接層'''
    n_in = x.get_shape()[-1].value
    with tf.variable_scope(layer_name):
        w = tf.get_variable('weights', shape=[n_in, out_kernels], dtype=tf.float32,
                            initializer=tf.contrib.layers.xavier_initializer_conv2d())
        b = tf.get_variable('bias', shape=[out_kernels], dtype=tf.float32, trainable=True,
                            initializer=tf.truncated_normal_initializer(stddev=0.1))
        y = tf.nn.relu(tf.nn.bias_add(tf.matmul(x, w), b))
    return y


def ResNet(x1, x2, layer_name):
    '''殘差計算'''
    '''x1爲前卷積層'''
    '''x2爲後卷積層'''
    with tf.variable_scope(layer_name):
        if x1.shape[1] == x2.shape[1] and x1.shape[3] == x2.shape[3]:               # 當兩個卷積結果維度相同時,直接將兩卷積求和
            conv_add = tf.nn.relu(tf.add(x1, x2))
        else:                                                                       # 當兩個卷積結果維度不同時,將想x1進行卷積操作,使x1與x2維度相同
            w = tf.get_variable('weights', shape=[1, 1, x1.shape[3], x2.shape[3]], dtype=tf.float32,
                                initializer=tf.contrib.layers.xavier_initializer_conv2d())
            conv = tf.nn.conv2d(x1, w, strides=[1, x1.shape[1]//x2.shape[1], x1.shape[1]//x2.shape[1], 1], padding='VALID')                 # 通常情況下,卷積後圖像大小不會變大,通過計算可以獲取步長
            conv_add = tf.nn.relu(tf.add(conv, x2))
    return conv_add


def VGG11(x, _dropout, n_cls):
    '''輸入:28*28*1'''
    '''輸出:14*14*64'''
    conv1_1 = con2d_layer(x, 64, 2, 'conv1_1', strides=2)
    pool1 = maxPoolLayer(conv1_1, 'pool1', ksize=3, strides=1)

    '''輸入:14*14*64'''
    '''輸出:14*14*64'''
    conv2_1 = con2d_layer(pool1, 64, 1, 'conv2_1', strides=1)

    '''輸入:14*14*64'''
    '''輸出:14*14*256'''
    conv2_2 = con2d_layer(conv2_1, 64, 3, 'conv2_2', strides=1)
    conv2_3 = con2d_layer(conv2_2, 256, 1, 'conv2_3', strides=1)

    '''輸入:x1=14*14*64, x2=14*14*256'''
    '''輸出:14*14*256'''
    residual2 = ResNet(pool1, conv2_3, 'residual2')

    '''輸入:14*14*256'''
    '''輸出:14*14*64'''
    conv3_1 = con2d_layer(residual2, 64, 1, 'conv3_1', strides=1)

    '''輸入:14*14*64'''
    '''輸出:14*14*64'''
    conv3_2 = con2d_layer(conv3_1, 64, 3, 'conv3_2', strides=1)

    '''輸入:14*14*64'''
    '''輸出:14*14*256'''
    conv3_3 = con2d_layer(conv3_2, 256, 1, 'conv3_3', strides=1)

    '''輸入:x1=14*14*256, x2=14*14*256'''
    '''輸出:14*14*256'''
    residual3 = ResNet(residual2, conv3_3, 'residual3')

    '''輸入:14*14*256'''
    '''輸出:14*14*64'''
    conv4_1 = con2d_layer(residual3, 64, 1, 'conv4_1', strides=1)

    '''輸入:14*14*64'''
    '''輸出:14*14*64'''
    conv4_2 = con2d_layer(conv4_1, 64, 3, 'conv4_2', strides=1)

    '''輸入:14*14*64'''
    '''輸出:14*14*256'''
    conv4_3 = con2d_layer(conv4_2, 256, 1, 'conv4_3', strides=1)

    '''輸入:x1=14*14*256, x2=14*14*256'''
    '''輸出:14*14*256'''
    residual4 = ResNet(residual3, conv4_3, 'residual4')

    '''輸入:x1=14*14*256'''
    '''輸出:7*7*256'''
    pool4 = maxPoolLayer(residual4, 'pool4', ksize=2, strides=2)

    '''將pool_5變換爲一維向量'''
    pool4_flatten_dims = int(np.prod(pool4.get_shape().as_list()[1:]))
    pool4_flatten = tf.reshape(pool4, [-1, pool4_flatten_dims])

    '''(7*7*256) * 1024'''
    fc5 = fc_layer(pool4_flatten, 1024, 'fc5')
    dropout5 = tf.nn.dropout(fc5, _dropout)
    '''1024 * n_cls全連接層'''
    w = tf.Variable(tf.truncated_normal(shape=[1024, n_cls], mean=0, stddev=0.1))
    b = tf.Variable(tf.constant(0.1, shape=[n_cls]))
    fc6 = tf.matmul(dropout5, w) + b
    # fc2 = fc_layer(dropout1, n_cls, 'fc2')
    return fc6


# tensorflow基於mnist實現VGG11
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
n_cls = 10              # 識別種類

x = tf.placeholder(tf.float32, [None, 784])
y = tf.placeholder(tf.float32, [None, n_cls])
sess = tf.InteractiveSession()

x1 = tf.reshape(x, [-1, 28, 28, 1])
keep_prob = tf.placeholder(tf.float32)
y_conv = VGG11(x1, keep_prob, n_cls)

# 建立損失函數,在這裏採用交叉熵函數
cross_entropy = tf.reduce_mean(
    tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=y_conv))

train_step = tf.train.AdamOptimizer(1e-3).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
tf.summary.scalar('accuracy', accuracy)

# 初始化變量
sess.run(tf.global_variables_initializer())
merged = tf.summary.merge_all()
writer = tf.summary.FileWriter("./log", sess.graph)
for i in range(3001):
    batch = mnist.train.next_batch(10)
    if i % 100 == 0:
        result = sess.run(merged, feed_dict={
            x: batch[0], y: batch[1], keep_prob: 1.0})
        writer.add_summary(result, i)
        train_accuracy = accuracy.eval(feed_dict={
            x: batch[0], y: batch[1], keep_prob: 1.0})
        print("step %d, training accuracy %g" % (i, train_accuracy))
    train_step.run(feed_dict={x: batch[0], y: batch[1], keep_prob: 0.5})

# print("test accuracy %g"%accuracy.eval(feed_dict={
#     x: mnist.test.images, y: mnist.test.labels, keep_prob: 1.0}))

writer.close()
sess.close()

源碼下載鏈接:https://download.csdn.net/download/OEMT_301/12571313

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