Tensorflow入门第三课——高级版MNIST手写数字识别(代价函数、优化方法)

一、代价函数

具体见:
https://blog.csdn.net/haha0825/article/details/102491643

二、优化器

具体见:
https://blog.csdn.net/haha0825/article/details/102503487

三、高级版MNIST手写数字识别

高级版主要做了以下改进:
(1)增加了隐藏层
(2)增加了每层的神经元
(3)改变了代价函数
(4)改变了优化器
(5)增加了dropout

# MNIST手写数字识别(高级版)

import tensorflow as tf

from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets("MNIST_data",one_hot=True)    # 载入数据放在当前路径

sess = tf.InteractiveSession()
batch_size = 100   # 每个批次的大小
# n_batch = mnist.train.num_example    # 一共有多少批次
n_batch = 5000
# 定义两个占位符
x = tf.placeholder(tf.float32,[None,784])
y = tf.placeholder(tf.float32,[None,10])
keep_prob = tf.placeholder(tf.float32)
# 创建一个神经网络
# 输入层
W1 = tf.Variable(tf.truncated_normal([784,1000],stddev=0.1))
b1 = tf.Variable(tf.zeros([1000])+0.1)
L1 = tf.nn.tanh(tf.matmul(x,W1)+b1)
L1_drop = tf.nn.dropout(L1,keep_prob)  #keep_prob=0.4就是有40%的神经元失活
# 隐藏层1
W2 = tf.Variable(tf.truncated_normal([1000,1000],stddev=0.1))
b2 = tf.Variable(tf.zeros([1000])+0.1)
L2 = tf.nn.tanh(tf.matmul(L1_drop,W2)+b2)
L2_drop = tf.nn.dropout(L2,keep_prob)
# 隐藏层2
W3 = tf.Variable(tf.truncated_normal([1000,500],stddev=0.1))
b3 = tf.Variable(tf.zeros([500])+0.1)
L3 = tf.nn.tanh(tf.matmul(L2_drop,W3)+b3)
L3_drop = tf.nn.dropout(L3,keep_prob)
# 输出层
W4 = tf.Variable(tf.truncated_normal([500,10],stddev=0.1))
b4 = tf.Variable(tf.zeros([10])+0.1)
prediction = tf.nn.softmax(tf.matmul(L3_drop,W4)+b4)

# 二次代价函数
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=prediction))

# 优化器
# train_step = tf.train.GradientDescentOptimizer(1e-2).minimize(loss)    #1e-2也就是0.01
train_step = tf.train.MomentumOptimizer(momentum=0.9,learning_rate=0.01).minimize(loss)

tf.global_variables_initializer().run()

correct_prediction = tf.equal(tf.arg_max(y,1),tf.arg_max(prediction,1))
# equal()两个值相等返回true,否则false
# arg_max返回一维张量中最大值的位置,对于y,里面是1个1和9个0,最大的那个位置就是该数字,比如第2个位置是1,则第二个位置最大,则该数字就是2
# 对于prediction来说,返回最大的概率的那个位置,其实同样也就是预测的数字。如果这两个值相等说明预测正确了.
# 总体的结果存放在一个布尔型列表中

# 准确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
# cast :将布尔类型转换为float32类型,然后reduce_mean:求平均值.true转为1.0,false转为0.0


for epoch in range(21):
    for batch in range(n_batch):      # 循环总共的批次
        batch_xs, batch_ys = mnist.train.next_batch(batch_size)
        # 取出100张图片,数据保存在batch_xs,标签保存在batch_yx,下一次再取出100张图片。
        train_step.run({x:batch_xs,y:batch_ys,keep_prob:0.7})

    test_acc = sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels,keep_prob:1.0})  # 训练一批输出一次准确率
    train_acc = sess.run(accuracy,feed_dict={x: mnist.train.images, y: mnist.train.labels, keep_prob:1.0})
    print("Iter" + str(epoch) + ",Testing Accuracy"+ str(test_acc)+",Training Accuracy"+str(train_acc))

输出结果
(1)在原来基础上仅仅改变代价函数或优化方法
改变代价函数(使用交叉熵代价函数):
在这里插入图片描述
改变优化方法(使用Adam):
在这里插入图片描述
(2)1000个神经元,梯度下降法
在这里插入图片描述
(3)2000个神经元,梯度下降法
在这里插入图片描述
(4)1000个神经元,Momentum优化器
在这里插入图片描述
(5)2000个神经元,Momentum优化器
在这里插入图片描述
(6)2000个神经元,Momentum优化器,dropout比例为0.8
在这里插入图片描述
(7)1000个神经元,Momentum优化器,不加dropout
在这里插入图片描述
可以看出:
(1)在相同的情况下,简单版的正确率只有不到93%,而这里改变了代价函数,正确率稍微有了提升
(2)使用Adam优化器,虽然最终结果没有提升,但是收敛速度极快;后面使用Momentum优化器,正确率和收敛速度都有较大提升。
(3)在这样情况下增加神经元数量已经没什么意义了,太多的神经元还会导致过拟合以及增加训练时间。
(4)增加了dropout的比例,效果稍微有了一些提升
(5)不加dropout时,1000个神经元已经有了明显的过拟合

四、继续改进

(1)继续填加隐藏层
(2)更改神经元数量
(3)更改dropout失活比例
(4)更改优化方法,学习率
(5)更改激活函数
(6)增加训练次数
(7)更改代价函数

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值