TensorFlow-6实现进阶的卷积神经网络

1 数据

cifar-10数据,该数据集包含60000张32X32的彩色图像,其中训练集50000张,测试集10000张。标注为10类,每一类6000张图片,这10类分别是airplane、automobile bird cat deer dog frog horse ship truck,其中没有任何重叠的情况。
数据可从 https://github.com/tensorflow/models.git 下载,并且下载cifar10_input.py以读取cifar数据

2 网络构建

Layer名称描述
conv1卷积层和ReLu激活函数
pool1最大池化
norm1LRN
conv2卷积层和ReLu激活函数
norm2
LRN
pool2
最大池化
fc1全连接层和ReLu激活函数
fc2全连接层和ReLu激活函数
logits模型Inference的输出结果

损失函数采用交叉熵+L2正则项,这是为了防止过拟合。一般来说L1正则会制造稀疏的特征,大部分无用特征会被置为0,而L2正则会让特征的权重不过大,使得特征的权重比较平均,因此,对fc1和fc2层的权重添加L2正则。

cifar10_input类中的distorted_input函数产生训练需要使用的数据,每次执行会产生一个batch_size的数量的样本。并对数据进行了数据增强(data Augmentation),包括随机的水平翻转、随机剪切一块24X24大小的图片,设置随机的亮度和对比度,以及对数据进行标准化,通过这些操作,原来的一幅图片样本可以变为多张图片,相当于扩大样本量。

LRN(局部响应归一化)操作最早见于Alex用CNN参加ImageNet比赛的论文,解释为:LRN层模仿了生物神经系统的“侧抑制”机制,对局部神经元的活动创建竞争环境,使得其中响应比较大的值变得相对更大,并抑制其他反馈较小的神经元,增强了模型的泛化能力。

最终输出的为top1的分类精度。

3 代码实现

#__author__ = 'Administrator'
'''
实现进阶的卷积神经网络
'''
import cifar10_input
import tensorflow as tf
import numpy as np
import time
import math

def weights_with_weight_loss(shape,stddev,w1):
    '''
    初始化权重,求权重的正则化项
    :param shape: weights的shape
    :param stddev: weights的初始标准方差
    :param w1: 正则化项系数
    :return:初始化的weights
    '''
    weights=tf.Variable(tf.truncated_normal(shape,stddev=stddev)) #weights
    if w1 is not None:#w1存在的话 求weights的L2正则项
        weights_loss=tf.multiply(tf.nn.l2_loss(weights),w1)
        tf.add_to_collection('weights_loss', weights_loss)
    return weights

def bias(value,shape):
    '''
    初始化bias项
    :param value: bias的初始值
    :param shape: bias的shape
    :return: 初始化的b
    '''
    b=tf.Variable(tf.constant(value,shape=shape))
    return b

def conv2d(x,kernel):
    '''
    卷积
    :param x: 卷积对象,特征
    :param kernel: 卷积核设置
    :return:卷积后的特征
    '''
    feature=tf.nn.conv2d(x,kernel,[1,1,1,1],padding='SAME')#Strides=[1,1,1,1]表明输出图像与原图大小相等
    return feature

def loss(logits,labels):
    '''
    计算带有L2正则项的loss
    :param logits: 输出层的输出值
    :param labels: 真实标签
    :return:带有L2正则项的loss
    '''
    labels=tf.cast(labels,tf.int64)
    cross_entropy=tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits,labels=labels,
                                                                 name='cross_entropy_per_example')
    cross_entropy_mean=tf.reduce_mean(cross_entropy,name='cross_entropy')
    tf.add_to_collection('losses',cross_entropy_mean)
    return tf.add_n(tf.get_collection('losses'),name='total_loss')

#参数设置
batch_size=128
max_steps=3000
data_dir='./cifar-10-batches-bin'

#导入数据,并进行数据增强处理
images_train,labels_train=cifar10_input.distorted_inputs(data_dir,batch_size=batch_size)
images_test,labels_test=cifar10_input.inputs(eval_data=True,data_dir=data_dir,batch_size=batch_size) #True:表明载入test数据

#构建模型
x=tf.placeholder(tf.float32,[batch_size,24,24,3]) #size 24X24 3个通道
y_=tf.placeholder(tf.int64,[batch_size])#存放标签
#卷积层1 池化1
w_conv1=weights_with_weight_loss([5,5,3,64],stddev=5e-2,w1=0.0)
b_conv1=bias(0.0,[64])
h_conv1=tf.nn.relu(conv2d(x,w_conv1)+b_conv1)
h_pool1=tf.nn.max_pool(h_conv1,[1,3,3,1],[1,2,2,1],padding='SAME') #核 3X3 步长: 2X2
h_norm1=tf.nn.lrn(h_pool1,4,bias=0.1,alpha=0.001/9.0,beta=0.75)

#卷积层2 池化2
w_conv2=weights_with_weight_loss([5,5,64,64],stddev=5e-2,w1=0.0)
b_conv2=bias(0.1,[64])
h_conv2=tf.nn.relu(conv2d(h_norm1,w_conv2)+b_conv2)
h_norm2=tf.nn.lrn(h_conv2,4,bias=0.1,alpha=0.001/9.0,beta=0.75)
h_pool2=tf.nn.max_pool(h_norm2,[1,3,3,1],[1,2,2,1],padding='SAME')

#全连接层1
h_pool2_flat=tf.reshape(h_pool2,[batch_size,-1])
dim=h_pool2_flat.get_shape()[1].value
w_fc1=weights_with_weight_loss([dim,384],stddev=0.04,w1=0.004)
b_fc1=bias(0.1,[384])
h_fc1=tf.nn.relu(tf.matmul(h_pool2_flat,w_fc1)+b_fc1)

#全连接层2
w_fc2=weights_with_weight_loss([384,192],stddev=0.04,w1=0.004)
b_fc2=bias(0.1,shape=[192])
h_fc2=tf.nn.relu(tf.matmul(h_fc1,w_fc2)+b_fc2)

#输出层
w_fc3=weights_with_weight_loss([192,10],stddev=1/192.0,w1=0.0)
b_fc3=bias(0.0,[10])
logits=tf.add(tf.matmul(h_fc2,w_fc3),b_fc3)

#计算loss,选择优化
loss=loss(logits,y_)
optimizer=tf.train.AdamOptimizer(1e-3).minimize(loss)
#输出分数最高的那一类的准确率
top_k_op=tf.nn.in_top_k(logits,y_,1)

#开启会话窗口
sess=tf.InteractiveSession()
tf.global_variables_initializer().run()

#启动图片数据增强的线程队列,利用16线程进行加速
tf.train.start_queue_runners()

#训练
for step in range(max_steps):
    start_time=time.time()
    images_batch,labels_batch=sess.run([images_train,labels_train])
    loss_value,_=sess.run([loss,optimizer],feed_dict={x:images_batch,y_:labels_batch})
    running_time=time.time()-start_time
    if step%10==0:
        example_per_sec=batch_size/running_time
        sec_per_batch=float(running_time)
        form_str=('step %d,loss=%.2f (%.1f example/sec; %.3f sec/batch)')
        print(form_str % (step,loss_value,example_per_sec,sec_per_batch))

#检测
num_examples=10000
iter_num=int(math.ceil(num_examples/batch_size))
total_examples=iter_num*batch_size
true_count=0
step=0
while step<iter_num:
    images_batch,labels_batch=sess.run([images_test,labels_test])
    precidion=sess.run(top_k_op,feed_dict={x:images_batch,y_:labels_batch})
    true_count+=np.sum(precidion)
    step+=1

precision=true_count/total_examples
print('precision @1 %.2f '% precision)

4 实验结果

时间那块比较多,只输出后边一些
step 2930,loss=1.10 (345.0 example/sec; 0.371 sec/batch)
step 2940,loss=0.83 (344.1 example/sec; 0.372 sec/batch)
step 2950,loss=0.88 (342.1 example/sec; 0.374 sec/batch)
step 2960,loss=0.82 (345.9 example/sec; 0.370 sec/batch)
step 2970,loss=1.30 (345.0 example/sec; 0.371 sec/batch)
step 2980,loss=0.81 (345.8 example/sec; 0.370 sec/batch)
step 2990,loss=0.86 (342.2 example/sec; 0.374 sec/batch)
precision @1 0.71 

5 改进说明

1.增加max_steps,可以期望分类精度增加
2.如果max_steps比较大,使用学习速率衰减(decay)的SGD进行训练。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

勤劳的凌菲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值