tensorflow实战自学【四】

6 篇文章 0 订阅
3 篇文章 0 订阅

卷积神经网络进阶

相比于【三】,此卷积神经网络新增加了一些心技巧,这也是此CNN的关键。
1.对weights进行了L2正则化。在机器学习中,不管是分类还是回归任务,都因为特征过多而导致过拟合,一般可以通过减少特征或者惩罚不重要的特征来缓解这个问题。但通常我们不知道该惩罚哪些特征的权重,而正则化就是帮助我们乘法这些特称权重的,即特征的权重也会成为损失函数的一部分。可以理解为,为了使用某个特征,我们需要付出loss的代价,除非这个特征非常有效,否则就会被loss的增加覆盖效果。这样我们就可以筛选出最有效的特征,减少特征权重防止过拟合。这也就是奥卡姆剃刀法则,越简单的东西越有效。L1正则会制造稀疏的特征,大部分无用的特征会被重置为0,而L2则会让这些特征的权重不过大,使得特征的权重比较平均。
2.对图片进行了反转,随机剪切等数据增强,制造了更多样本
3.在每个卷积-最大池化后面使用了LRN层(局部响应标准化),增强了模型的泛化能力。局部响应归一化层完成一种“临近抑制”操作,对局部输入区域进行归一化。

NOTE:因为网络原因cifar10无法下载,因此只给出神经网络构建的代码实现,以及主要思路,代码我并没有实际运行过。

代码实现部分

实现思路

整体思路并没有太大改变,主要部分依旧是2层卷积+最大池化,不过在第一次池化过后,接一层LRN,第二次连接LRN是在第2次卷积之后连接的。在2次卷积+池化过后是1层flatten,最后为2层全连接层,第1层全连接层将隐含节点减半,第二层全连接层设置隐含节点数为10,即分类的数目。损失函数依旧使用交叉熵。

代码

# -*- coding: utf-8 -*-
"""
Created on Tue Jul 23 13:59:18 2019

@author: Administrator
"""
#cd cifar10
import tensorflow as tf
import numpy as np
import time
import cifar10,cifar10_input

max_steps=3000
batch_size=128
data_dir='/cifar-10-batches-bin'

def variable_with_weight_loss(shape,stddev,wl):
    var=tf.Variable(tf.truncated_normal(shape,stddev=stddev))
    if wl is not None:
        weight_loss=tf.multiply(tf.nn.l2_loss(var),wl,name='weight_loss')
        tf.add_to_collection('losses',weight_loss)
    return var

#使用cifar10类下载数据集,并解压,展开到其默认位置
cifar10.maybe_download_and_extract()

images_train,labels_train=cifar10_input.distorted_inputs(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)

#图片大小24*24,图片通道3,因为batch_size在之后的网络结构中要用到,所以需要预先设定
image_holder=tf.placeholder(tf.float32,[batch_size,24,24,3])
label_holder=tf.placeholder(tf.int32,[batch_size])

#第一层卷积+池化
weight1=variable_with_weight_loss(shape=[5,5,3,64],stddev=5e-2,wl=0.0)
kernel1=tf.nn.conv2d(image_holder,weight1,[1,1,1,1],padding='SAME')
bias1=tf.Variable(tf.constant(0.0,shape=[64]))
conv1=tf.nn.relu(tf.nn.bias_add(kernel1,bias1))
pool1=tf.nn.max_pool(conv1,ksize=[1,3,3,1],strides=[1,2,2,1],padding='SAME')
norm1=tf.nn.lrn(pool1,4,bias=1.0,alpha=0.001/9.0,beta=0.75)

#第二层卷积+池化
weight2=variable_with_weight_loss(shape=[5,5,64,64],stddev=5e-2,wl=0.0)
kernel2=tf.nn.conv2d(norm1,weight2,[1,1,1,1],padding='SAME')
bias2=tf.Variable(tf.constant(0.1,shape=[64]))
conv2=tf.nn.relu(tf.nn.bias_add(kernel2,bias2))
norm2=tf.nn.lrn(conv2,ksize=[1,3,3,1],strides=[1,2,2,1],padding='SAME')
pool2=tf.nn.max_pool(norm2,ksize=[1,3,3,1],strides=[1,2,2,1],padding='SAME')

#flatten
reshape=tf.reshape(pool2,[batch_size,-1])
dim=reshape.get_shape()[1].value
weight3=variable_with_weight_loss(shape=[dim,384],stddev=0.04,wl=0.004)
bias3=tf.Variable(tf.constant(0.1,shape=[384]))
local3=tf.nn.relu(tf.matmul(reshape,weight3)+bias3)

#全连接层,隐含节点数减半
weight4=variable_with_weight_loss(shape=[384,192],stddev=0.04,wl=0.004)
bias4=tf.Variable(tf.constant(0.1,shape=[192]))
local4=tf.nn.relu(tf.matmul(local3,weight4)+bias4)

#全连接层
weight5=variable_with_weight_loss(shape=[192,10],stddev=1/192.0,wl=0.0)
bias5=tf.Variable(tf.constant(0.0,shape=[10]))
logits=tf.add(tf.matmul(local4,weight5),bias5)

def loss(logits,labels):
    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')

loss=loss(logits,label_holder)

train_op=tf.train.AdamOptimizer(1e-3).minimize(loss)

top_k_op=tf.nn.in_top_k(logits,label_holder,1)

sess=tf.InteractiveSession()
tf.global_variables_initializer.run()

tf.train.start_queue_runners()

for step in range(max_steps):
    start_time=time.time()
    image_batch,label_batch=sess.run([images_train,labels_train])
    _,loss_value=sess.run([train_op,loss],feed_dict={image_holder:image_batch,\
                          label_holder:label_batch})
    duration=time.time()-start_time
    
    if step%10==0:
        examples_per_sec=batch_size/duration
        sec_per_batch=float(duration)
        
        format_str=('step %d,loss=%.2f(%.1f example/sec;%.3f sec/batch)')
        print(format_str%(step,loss_value,examples_per_sec,sec_per_batch))

num_examples=10000
import math
num_iter=int(math.ceil(num_examples/batch_size))
true_count=0
total_sample_count=num_iter*batch_size
step=0
while step<num_iter:
    image_batch,label_batch=sess.run([images_test,labels_test])
    predictions=sess.run([top_k_op],feed_dict={image_holder:image_batch,\
                         label_holder:label_batch})
    true_count+=np.sum(predictions)
    step+=1
    
precision=true_count.total_sample_count
print('precision@1=%.3f'%precision)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值