从几个方面对该网络模型进行优化:
1.首先使用函数封装库tf.contrib.layers重写网络模型,使得代码更加简洁明了,可读性更高。(不过这个函数封装库在Tensorflow即将到来的2.0版本将被取消,所以打算后面运用tf.keras重写一遍。)
2.在实际的卷积训练中,为了加快速度,可以考虑把卷积核裁开。比如一个3x3的卷积核,可以裁成3x1和1x3两个卷积核,分别对原有输入做卷积操作,效果相同,但是运行速度更高。
3.使用多通道卷积技术。即在单个卷积层中加入若干个不同尺寸的卷积核,这样使得生成的feature map特征更加多样性。
4.使用批量归一化技术。相关理论这里不做过多介绍。在实际运用中,批量归一化的收敛速度非常快,并且具有很强的泛化能力,某种情况下可以完全替代正则化,Dropot。主要是运用batch_norm函数实现。
代码如下:
import cifar10_input
import tensorflow as tf
import numpy as np
import tensorflow.contrib.layers as Layers
from tensorflow.contrib.layers.python.layers import batch_norm
batch_size = 28
# 注意数据集的路径
data_dir = r'D:\anaconda\a_lianxi\cifar_study\tmp\cifar10_data\cifar-10-batches-bin'
print('begin')
images_train,labels_train = cifar10_input.inputs(eval_data=False,data_dir=data_dir,batch_size=batch_size)
images_test,labels_test = cifar10_input.inputs(eval_data=True,data_dir=data_dir,batch_size=batch_size)
print('begin data')
# def weight_variable(shape):
# return tf.Variable(tf.truncated_normal(shape, stddev=0.1))
#
# def bias_variable(shape):
# return tf.Variable(0.1,shape=shape)
#
# def conv2d(x,W):
# return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SAME')
#
# def max_pool_2x2(x):
# return tf.nn.max_pool(x,ksize=[1,2,2,1],
# strides=[1,2,2,1],padding='SAME')
#
# def avg_pool_6x6(x):
# return tf.nn.max_pool(x,ksize=[1,6,6,1],
# strides=[1,6,6,1],padding='SAME')
#批量归一化函数
def batch_norm_layer(value,train=None,name='natch_norm'):
if train is not None:
return batch_norm(value,decay=0.9,updates_collections=None,is_training=True)
else:
return batch_norm(value,decay=0.9,updates_collections=None,is_training=False)
x = tf.placeholder(tf.float32,[None,24,24,3])
y = tf.placeholder(tf.float32,[None,10])
train = tf.placeholder(tf.float32)
# 构建网络
x_image = tf.reshape(x,[-1,24,24,3])
#第一层
# h_conv1 = Layers.conv2d(x_image,64,[5,5],1,'SAME',activation_fn=tf.nn.relu)
#卷积核分解
h_conv1 = Layers.conv2d(x_image,64,[5,1],1,'SAME',activation_fn=tf.nn.relu)
h_conv1 = Layers.conv2d(h_conv1,64,[1,5],1,'SAME',activation_fn=tf.nn.relu)
#使用批量归一化函数
h_conv1 = batch_norm_layer(h_conv1,train)
#2x2池化
h_pool1 = Layers.max_pool2d(h_conv1,[2,2],stride=2,padding='SAME')
#第二层
#多通道
# h_conv2 = Layers.conv2d(h_pool1,64,[5,5],1,'SAME',activation_fn=tf.nn.relu)
h_conv2_1x1 = Layers.conv2d(h_pool1,64,[1,1],1,'SAME',activation_fn=tf.nn.relu)
h_conv2_3x3_ = Layers.conv2d(h_pool1,64,[3,1],1,'SAME',activation_fn=tf.nn.relu)
h_conv2_3x3 = Layers.conv2d(h_conv2_3x3_,64,[1,3],1,'SAME',activation_fn=tf.nn.relu)
h_conv2_5x5_ = Layers.conv2d(h_pool1,64,[5,1],1,'SAME',activation_fn=tf.nn.relu)
h_conv2_5x5 = Layers.conv2d(h_conv2_5x5_,64,[1,5],1,'SAME',activation_fn=tf.nn.relu)
h_conv2_7x7_ = Layers.conv2d(h_pool1,64,[7,1],1,'SAME',activation_fn=tf.nn.relu)
h_conv2_7x7 = Layers.conv2d(h_conv2_7x7_,64,[1,7],1,'SAME',activation_fn=tf.nn.relu)
#使用concat函数连接起来
h_conv2 = tf.concat([h_conv2_5x5,h_conv2_7x7,h_conv2_3x3,h_conv2_1x1],3)
h_conv2 = batch_norm_layer(h_conv2,train)
h_pool2 = Layers.max_pool2d(h_conv2,[2,2],stride=2,padding='SAME')
#第三层
h_conv3 = Layers.conv2d(h_pool2,10,[5,1],1,'SAME',activation_fn=tf.nn.relu)
h_conv3 = Layers.conv2d(h_conv3,10,[1,5],1,'SAME',activation_fn=tf.nn.relu)
h_conv3 = batch_norm_layer(h_conv3,train)
h_pool3 = Layers.max_pool2d(h_conv3,[6,6],stride=6,padding='SAME')
#第四层
nt_flat = tf.reshape(h_pool3,[-1,10])
y_conv = Layers.fully_connected(nt_flat,10,activation_fn=tf.nn.softmax)
cross_entropy = -tf.reduce_sum(y*tf.log(y_conv))
#使用退化学习率,每1000次退化0.9
global_step = tf.Variable(0,trainable=False)
decaylearning_rate = tf.train.exponential_decay(0.004,global_step,1000,0.9)
train_step = tf.train.AdamOptimizer(decaylearning_rate).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y_conv,1),tf.argmax(y,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction,"float"))
sess = tf.Session()
sess.run(tf.global_variables_initializer())
tf.train.start_queue_runners(sess=sess)
for i in range(15000):
image_batch,label_batch = sess.run([images_train,labels_train])
label_b = np.eye(10)[label_batch]
train_step.run({x:image_batch,y:label_b,train:1},session=sess)
if i%200 == 0:
train_accuracy = accuracy.eval({x:image_batch,y:label_b},session=sess)
print("step %d, training accuracy %g"%(i,train_accuracy))
image_batch,label_batch = sess.run([images_test, labels_test])
label_b = np.eye(10)[label_batch]
print('finished! test accuracy %g'%accuracy.eval({x:image_batch,y:label_b},session=sess))
卷积神经网络的学习到此告一段落,但是终点就是起点,还有很多地方依旧值得你我进一步学习。愿诸君共勉!