我tm吹爆batch_norm
!!!!!一开始以为换了tfrecord
之后也可以和以前直接读取图片那样不需要batch_norm
,但是几天的训练精度都在0.2,我不禁怀疑起了人生,最后用了batch_norm
,一切都回来了。现在我把两个版本的代码都放上来,留作纪念,并希望可以帮助到需要的人。
附上个batch_norm
的教程链接。Batch Normalization – Solutions
在定义网络层的时候,如果要通过tf.get_variable()
来用进行参数的xavier
初始化tf.contrib.layers.xavier_initializer()
,那么在前面应该使用tf.variable_scope
而不是tf.name_scope()
。这是因为name_scope
和get_variable
之间会存在参数复用的问题,会报错。
没有batch_norm
的代码如下:
"""
# AlexNet模型
"""
import tensorflow as tf
'''
获取tensor信息
'''
def print_tensor_info(tensor):
print("tensor name:",tensor.op.name,"-tensor shape:",tensor.get_shape().as_list())
def inference(input, num_class, keep_prob):
# 定义参数
parameters = []
# 第一层卷积层
with tf.variable_scope("conv1"):
# 设置卷积核5×5,3通道,32个卷积核
# kernel1 = tf.Variable(tf.truncated_normal([5,5,3,32],mean=0,stddev=0.1,
# dtype=tf.float32),name="weights")
kernel1 = tf.get_variable("weight", [5, 5, 3, 32],
initializer=tf.contrib.layers.xavier_initializer())
# 卷积,卷积的横向步长和竖向补偿都为4
conv = tf.nn.conv2d(input,kernel1,[1,1,1,1],padding="SAME")
#初始化偏置
biases = tf.get_variable("bias", [32], initializer=tf.contrib.layers.xavier_initializer())
bias = tf.nn.bias_add(conv,biases)
#RELU激活函数
conv1 = tf.nn.relu(bias)
#输出该层的信息
print_tensor_info(conv1)
#统计参数
parameters += [kernel1,biases]
#lrn处理
#lrn1 = tf.nn.lrn(conv1,4,bias=1,alpha=1e-3/9,beta=0.75,name="lrn1")
#最大池化
pool1 = tf.nn.max_pool(conv1,ksize=[1,2,2,1],strides=[1,2,2,1],padding="SAME",name="pool1")
print_tensor_info(pool1)
# 可视化输出
with tf.variable_scope('visual'):
x_min = tf.reduce_min(kernel1)
x_max = tf.reduce_max(kernel1)
kernel_0_to_1 = (kernel1 - x_min) / (x_max - x_min)
# to tf.image_summary format [batch_size, height, width, channels]
kernel_transposed = tf.transpose(kernel_0_to_1, [3, 0, 1, 2])
# this will display random 3 filters from the 64 in conv1
tf.summary.image('conv1/filters', kernel_transposed, max_outputs=3)
layer1_image1 = conv1[0:1, :, :, 0:16]
layer1_image1 = tf.transpose(layer1_image1, perm=[3, 1, 2, 0])
tf.summary.image("filtered_images_layer1", layer1_image1, max_outputs=16)
#第二层卷积层
with tf.variable_scope("conv2"):
#初始化权重
kernel2 = tf.get_variable("weight", [5, 5, 32, 64],
initializer=tf.contrib.layers.xavier_initializer())
conv = tf.nn.conv2d(pool1,kernel2,[1,1,1,1],padding="SAME")
#初始化偏置
biases = tf.get_variable("bias", [64], initializer=tf.contrib.layers.xavier_initializer())
bias = tf.nn.bias_add(conv,biases)
#RELU激活
conv2 = tf.nn.relu(bias)
print_tensor_info(conv2)
parameters += [kernel2,biases]
#LRN
#lrn2 = tf.nn.lrn(conv2,4,1.0,alpha=1e-3/9,beta=0.75,name="lrn2")
#最大池化
pool2 = tf.nn.max_pool(conv2,[1,2,2,1],[1,2,2,1],padding="SAME",name="pool2")
print_tensor_info(pool2)
#第三层卷积层
with tf.variable_scope("conv3"):
#初始化权重
kernel3 = tf.get_variable("weight", [3, 3, 64, 128],
initializer=tf.contrib.layers.xavier_initializer())
conv = tf.nn.conv2d(pool2,kernel3,strides=[1,1,1,1],padding="SAME")
biases = tf.get_variable("bias", [128], initializer=tf.contrib.layers.xavier_initializer())
bias = tf.nn.bias_add(conv,biases)
#RELU激活层
conv3 = tf.nn.relu(bias)
parameters += [kernel3,biases]
print_tensor_info(conv3)
# 最大池化
pool3 = tf.nn.max_pool(conv3, [1, 2, 2, 1], [1, 2, 2, 1], padding="SAME", name="pool2")
print_tensor_info(pool3)
#第四层卷积层
with tf.variable_scope("conv4") as scope:
#初始化权重
kernel4 = tf.get_variable("weight", [3, 3, 128, 256],
initializer=tf.contrib.layers.xavier_initializer())
#卷积
conv = tf.nn.conv2d(conv3,kernel4,strides=[1,2,2,1],padding="SAME")
biases = tf.get_variable("bias", [256], initializer=tf.contrib.layers.xavier_initializer())
bias = tf.nn.bias_add(conv,biases)
#RELU激活
conv4 = tf.nn.relu(bias)
parameters += [kernel4,biases]
print_tensor_info(conv4)
# 最大池化
pool4 = tf.nn.max_pool(conv4, [1, 2, 2, 1], [1, 2, 2, 1], padding="SAME", name="pool2")
print_tensor_info(pool4)
# 第五层卷积层
with tf.variable_scope("conv5") as scope:
# 初始化权重
kernel5 = tf.get_variable("weight", [3, 3, 256, 128],
initializer=tf.contrib.layers.xavier_initializer())
# 卷积
conv = tf.nn.conv2d(conv4, kernel5, strides=[1, 2, 2, 1], padding="SAME")
biases = tf.get_variable("bias", [128], initializer=tf.contrib.layers.xavier_initializer())
bias = tf.nn.bias_add(conv, biases)
# RELU激活
conv5 = tf.nn.relu(bias)
parameters += [kernel5, biases]
print_tensor_info(conv5)
# 最大池化
pool5 = tf.nn.max_pool(conv5, [1, 2, 2, 1], [1, 2, 2, 1], padding="SAME", name="pool2")
print_tensor_info(pool5)
#第六层-全连接层1
with tf.variable_scope('fc1'):
pool6 = tf.reshape(pool5,(-1, 4*4*128))
weight6 = tf.get_variable('weight',[4*4*128, 1024],initializer=tf.truncated_normal_initializer(stddev=0.1))
# ful_bias1 = tf.Variable(tf.constant(0.0,dtype=tf.float32,shape=[1024]),name=
# weight6 = tf.contrib.layers.l2_regularizer(0.0001)(weight6)
regularizer1 = tf.contrib.layers.l2_regularizer(0.0001)
tf.add_to_collection('losses', regularizer1(weight6))
ful_bias1 = tf.get_variable("bias", [1024], initializer=tf.constant_initializer(0.1))
# ful_con1 = tf.nn.relu(tf.add(tf.matmul(pool5,weight6),ful_bias1))
ful_con1 = tf.nn.xw_plus_b(pool6, weight6, ful_bias1)
ful_con1 = tf.nn.relu(ful_con1)
ful_con1 = tf.nn.dropout(ful_con1, keep_prob)
#第七层-全连接层2
with tf.variable_scope('fc2'):
weight7 = tf.get_variable('weight', [1024,512], initializer=tf.truncated_normal_initializer(stddev=0.1))
# weight7 = tf.contrib.layers.l2_regularizer(0.0001)(weight7)
regularizer2 = tf.contrib.layers.l2_regularizer(0.0001)
tf.add_to_collection('losses', regularizer2(weight7))
# ful_bias2 = tf.Variable(tf.constant(0.0,dtype=tf.float32,shape=[512]),name="ful_bias2")
ful_bias2 = tf.get_variable("bias", [512], initializer=tf.constant_initializer(0.1))
# ful_con2 = tf.nn.relu(tf.add(tf.matmul(ful_con1,weight7),ful_bias2))
ful_con2 = tf.nn.xw_plus_b(ful_con1, weight7, ful_bias2)
ful_con2 = tf.nn.relu(ful_con2)
ful_con2 = tf.nn.dropout(ful_con2, keep_prob)
#第八层-全连接层3
with tf.variable_scope('fc3'):
weight8 = tf.get_variable('weight', [512, num_class],initializer=tf.truncated_normal_initializer(stddev=0.1))
# weight9 = tf.contrib.layers.l2_regularizer(0.0001)(weight9)
regularizer3 = tf.contrib.layers.l2_regularizer(0.0001)
tf.add_to_collection('losses', regularizer3(weight8))
# bias9 = tf.Variable(tf.constant(0.0,shape=[num_class]),dtype=tf.float32,name="bias9")
bias8 = tf.get_variable("bias", [num_class], initializer=tf.constant_initializer(0.1))
# fc3 = tf.matmul(ful_con2,weight9)+bias9
fc3 = tf.nn.xw_plus_b(ful_con2, weight8, bias8)
# logits = tf.nn.l2_loss(output_softmax)
return fc3, parameters
添加了batch_norm
的代码如下:
import tensorflow as tf
def print_tensor_info(tensor):
print("tensor name:", tensor.op.name,
"-tensor shape:", tensor.get_shape().as_list())
def inference(input, num_class, keep_prob, is_training):
with tf.variable_scope('conv1'):
conv1 = tf.layers.conv2d(input, 32, 3, (1,1), 'same', use_bias=False, activation=tf.nn.relu)
print_tensor_info(conv1)
conv1_pool = tf.layers.max_pooling2d(conv1, (2,2), 2, 'same')
print_tensor_info(conv1_pool)
conv1_batch = tf.layers.batch_normalization(conv1_pool, training=is_training)
with tf.variable_scope('conv2'):
conv2 = tf.layers.conv2d(conv1_batch, 64, 3, (1,1), 'same', use_bias=False, activation=tf.nn.relu)
print_tensor_info(conv2)
conv2_pool = tf.layers.max_pooling2d(conv2, (2,2), 2, 'same')
print_tensor_info(conv2_pool)
conv2_batch = tf.layers.batch_normalization(conv2_pool, training=is_training)
with tf.variable_scope('conv3'):
conv3 = tf.layers.conv2d(conv2_batch, 128, 3, (1,1), 'same', use_bias=False, activation=tf.nn.relu)
print_tensor_info(conv3)
conv3_pool = tf.layers.max_pooling2d(conv3, (2,2), 2, 'same')
print_tensor_info(conv3_pool)
conv3_batch = tf.layers.batch_normalization(conv3_pool, training=is_training)
with tf.variable_scope('conv4'):
conv4 = tf.layers.conv2d(conv3_batch, 256, 3, (1,1), 'same', use_bias=False, activation=tf.nn.relu)
print_tensor_info(conv4)
conv4_pool = tf.layers.max_pooling2d(conv4, (2,2), 2, 'same')
print_tensor_info(conv4_pool)
conv4_batch = tf.layers.batch_normalization(conv4_pool, training=is_training)
with tf.variable_scope('conv4_flatten'):
orig_shape = conv4_batch.get_shape().as_list()
flatten = tf.reshape(conv4_batch, shape=[-1, orig_shape[1] * orig_shape[2] * orig_shape[3]])
print_tensor_info(flatten)
with tf.variable_scope('fc1'):
fc1 = tf.layers.dense(flatten, 512, use_bias=False, activation=None)
fc1 = tf.layers.batch_normalization(fc1, training=is_training)
fc1 = tf.nn.relu(fc1)
fc1 = tf.nn.dropout(fc1, keep_prob)
with tf.variable_scope('fc2'):
fc2 = tf.layers.dense(fc1, 128, use_bias=False, activation=None)
fc2 = tf.layers.batch_normalization(fc2, training=is_training)
fc2 = tf.nn.relu(fc2)
fc2 = tf.nn.dropout(fc2, keep_prob)
with tf.variable_scope('fc3'):
fc3 = tf.layers.dense(fc2, num_class, use_bias=False, activation=None)
fc3 = tf.layers.batch_normalization(fc3, training=is_training)
fc3 = tf.nn.relu(fc3)
return fc3