7.卷积神经网络(CNN)之手写数字(MNIST)识别(3)

1.卷积神经网络

详见 直白介绍卷积神经网络

2.代码实现:

与全连接网络不通,本篇去掉了 正则化方法,改用了 Dropout方法,加入两个 卷积层 与 池化层

import tensorflow as tf
import pylab
import os
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MNIST_data/',one_hot=True)
os.environ["CUDA_VISIBLE_DEVICES"] = "0,1"

#定义图片和标签的占位符
#None 表示张量的第一维度可以接受任意长度
x = tf.placeholder(tf.float32,[None,784])
y = tf.placeholder(tf.float32,[None,10])

#定义权重及偏置值变量
W1 = tf.Variable(tf.random_normal(([7*7*60,600])))
b1 = tf.Variable(tf.constant(0.1,shape=[600]))
W2 = tf.Variable(tf.random_normal(([600,10])))
b2 = tf.Variable(tf.constant(0.1,shape=[10]))

#定义权重方法:
def get_filter(shape):
    return tf.Variable(tf.truncated_normal(shape,stddev=0.1))

#定义偏置值方法:
def get_bias(shape):
    return tf.Variable(tf.constant(0.1,shape=shape))

#定义隐藏层
def hidden_layer(inputs):
    #要用激活函数
    return tf.nn.relu(tf.matmul(inputs,W1)+b1)

w_con1 = get_filter([5,5,1,30])
b_con1 = get_bias([30])
w_con2 = get_filter([5,5,30,60])
b_con2 = get_bias([60])

#将[100,784]转换为[100,28,28,1]
x_reshape = tf.reshape(x,[-1,28,28,1])
#第一层卷积输出,输出大小为100X28X28X30:
h_conv1 = tf.nn.conv2d(x_reshape,filter=w_con1,strides=[1,1,1,1],padding='SAME')+b_con1
#激活函数:
h1 = tf.nn.relu(h_conv1)
#第一层池化输出,输出大小为100X14X14X30:
h_pool1 = tf.nn.max_pool(h1,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
#第二层卷积输出,输出大小为100X14X14X60:
h_conv2 = tf.nn.conv2d(h_pool1,filter=w_con2,strides=[1,1,1,1],padding='SAME')+b_con2
#激活函数:
h2 = tf.nn.relu(h_conv2)
#第一层池化输出,输出大小为100X7X7X60:
h_pool2 = tf.nn.max_pool(h2,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')

      
#将池化后的输出改变下尺寸,
h_reshape = tf.reshape(h_pool2,[-1,7*7*60])
    
#隐藏层输出,并使用dropout
h3 = hidden_layer(h_reshape)
keep_prob  = tf.placeholder(tf.float32)
h_drop1 = tf.nn.dropout(h3,keep_prob)

#预测值,这里不用激活函数,因为等下要用tensorflow定义好的softmax交叉熵函数
pred = tf.matmul(h_drop1,W2) + b2

#定义交叉熵
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits=pred,labels=y)

#定义总的损失函数
loss = tf.reduce_mean(cross_entropy)

#定义初始学习率
learning_rate = 0.005

#定义优化器
opt = tf.train.AdamOptimizer(learning_rate).minimize(loss)

#定义参数
#总共循环训练轮数
train_epochs = 15
#每轮循环中,每次训练的图片张数
batch_size = 100  
#将所有图片训练一轮所需要的总的训练次数
total_batch = int(mnist.train.num_examples/batch_size) 
#以下是测试模型
correct_prediction = tf.equal(tf.argmax(pred,1),tf.argmax(y,1))
#准确率:
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))

#启动session
with tf.Session() as sess:
    
    #初始化变量,必写
    sess.run(tf.global_variables_initializer())
    
    print("以下是训练模型每轮训练误差:")
    #循环训练
    for epoch in range(train_epochs):
        #定义平均loss值
        avg_loss = 0.
        #循环所有数据
        for i in range(total_batch):
            batch_xs,batch_ys = mnist.train.next_batch(batch_size)
            _,c,acc = sess.run([opt,loss,accuracy],feed_dict={x:batch_xs,y:batch_ys,keep_prob:0.8})
            
            #平均loss
            avg_loss += c / total_batch
        
        #显示每轮的结果
        print('Epoch:',epoch+1,',     loss:','{:.9f}'.format(avg_loss),',     accuracy:','{:.5f}'.format(acc))
        
    print("\n训练模型结束,以下是测试模型准确率:")
    
    acc = sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels,keep_prob:1.0})
    print('Accuracy:',acc)

在这里插入图片描述

3.相关代码

3.1Dtopout
#隐藏层输出,并使用dropout
h3 = hidden_layer(h_reshape)
keep_prob  = tf.placeholder(tf.float32)
h_drop1 = tf.nn.dropout(h3,keep_prob)
3.2卷积池化操作
#定义权重方法:
def get_filter(shape):
    return tf.Variable(tf.truncated_normal(shape,stddev=0.1))

#定义偏置值方法:
def get_bias(shape):
    return tf.Variable(tf.constant(0.1,shape=shape))

w_con1 = get_filter([5,5,1,30])
b_con1 = get_bias([30])
w_con2 = get_filter([5,5,30,60])
b_con2 = get_bias([60])

#将[100,784]转换为[100,28,28,1]
x_reshape = tf.reshape(x,[-1,28,28,1])
#第一层卷积输出,输出大小为100X28X28X30:
h_conv1 = tf.nn.conv2d(x_reshape,filter=w_con1,strides=[1,1,1,1],padding='SAME')+b_con1
#激活函数:
h1 = tf.nn.relu(h_conv1)
#第一层池化输出,输出大小为100X14X14X30:
h_pool1 = tf.nn.max_pool(h1,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
#第二层卷积输出,输出大小为100X14X14X60:
h_conv2 = tf.nn.conv2d(h_pool1,filter=w_con2,strides=[1,1,1,1],padding='SAME')+b_con2
#激活函数:
h2 = tf.nn.relu(h_conv2)
#第一层池化输出,输出大小为100X7X7X60:
h_pool2 = tf.nn.max_pool(h2,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')

#将池化后的输出改变下尺寸,
h_reshape = tf.reshape(h_pool2,[-1,7*7*60])
3.3优化器的选择

一开始还是选择了tf.train.GradientDescentOptimizer()+退化学习率的方法,但效果非常差。后来选择了tf.train.AdamOptimizer(),而且还不需要用退化学习率,效果非常好,然后我将这个用在了之前的两个识别代码中,效果依然很棒。因此建议以后优先使用 tf.train.AdamOptimizer()的方法!

#定义优化器
opt = tf.train.AdamOptimizer(learning_rate).minimize(loss)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值