tensorlfow初学--mnist手写数字识别

mmnist手写数据集

不知道为什么就入了tensorflow的坑,然后一个人没事就渐渐的学了起来,感觉虽然刚开始各种不懂,但渐渐的有了一些兴趣了。记录一下,算是备忘。


#tensoflow_mnist v1


#-------------------------------------------------------------------------------------------------
 # @Author: mcc 
 # @Date: 2018-12-13 02:42:54 
 # @Last Modified by: mcc 
 # @Last Modified time: 2018-12-13 02:42:54 


#tensoflow_mnist v1


#-------------------------------------------------------------------------------------------------
# import tensorflow as tf
# from tensorflow.examples.tutorials.mnist import input_data
# mnist=input_data.read_data_sets('mnist_dir',one_hot=True)

# image_size=28
# labels_size=10
# learning_rate=0.05
# steps_number=1000
# batch_size=100

# training_data=tf.placeholder(tf.float32,[None,image_size*image_size])
# labels=tf.placeholder(tf.float32,[None,labels_size])

# W=tf.Variable(tf.truncated_normal([image_size*image_size,labels_size],stddev=0.1))
# b=tf.Variable(tf.constant(0.1,shape=[labels_size]))


# output=tf.matmul(training_data,W)+b

# loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=labels,logits=output))

# #train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)
# #优化
# train_step=tf.train.AdamOptimizer(learning_rate).minimize(loss)


# correct_prediction=tf.equal(tf.argmax(output,1),tf.argmax(labels,1))
# accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))

# with tf.Session() as sess:
#     sess.run(tf.global_variables_initializer())
#     for i in range (steps_number):
#         input_batch,labels_batch=mnist.train.next_batch(batch_size)
#         feed_dict={training_data:input_batch,labels:labels_batch}
#         train_step.run(feed_dict=feed_dict)
#         if i%100==0:
#             train_accuracy=accuracy.eval(feed_dict=feed_dict)
#             print("step %d ,training batch accuracy : %g"%(i,train_accuracy*100))
            
#             test_accuracy=accuracy.eval(feed_dict={training_data:mnist.test.images,labels:mnist.test.labels})
#             print("Test accuracy : %g"%(test_accuracy*100))
#----------------------------------------------------------------------------------




#tensorflow_mnist v2

#---------------------------------------------------------------------------------
import tensorflow as tf 
from tensorflow.examples.tutorials.mnist import input_data


#输入层节点--图像像素
INPUT_NODE = 784
#输出层节点--类别数目0-9
OUTPUT_NODE = 10
#单隐藏层节点500
LAYER1_NODE=500
#一个训练batch中的训练数据个数
BATCH_SIZE=100
#基本学习率
LEARNING_RATE_BASE=0.8  
#学习率衰减值
LEARNING_RATE_DECAY=0.99
#描述模型复杂度正则化在损失函数中的系数
REGULARIZATION_RATE=0.0001
#训练轮数
TRAINING_STEPS=3000
#滑动平均衰减率
MOVING_AVERAGE_DACAY=0.99



#定义了一个辅助函数,给定神经网路的输入输出所有参数,计算神经网络的前向传播结果
def inference(input_tensor,avg_class,weights1,biases1,weights2,biases2):
    #如果没有提供滑动平均类
    if avg_class==None:
        #使用relu计算前向传播结果
        layer1=tf.nn.relu(tf.matmul(input_tensor,weights1)+biases1)
        return tf.matmul(layer1,weights2)+biases2
    else:
        #根据avg.average计算变量的滑动平均值,在计算前向传播结果
        layer1=tf.nn.relu(tf.matmul(input_tensor,avg_class.average(weights1))+avg_class.average(biases1))
        return tf.matmul(layer1,avg_class.average(weights2))+avg_class.average(biases2)



def train(mnist):
    x=tf.placeholder(tf.float32,[None,INPUT_NODE],name='x-input')
    y_=tf.placeholder(tf.float32,[None,OUTPUT_NODE],name='y-input')
    #生成隐藏层参数
    weights1=tf.Variable(tf.truncated_normal([INPUT_NODE,LAYER1_NODE],stddev=0.1))
    biases1=tf.Variable(tf.constant(0.1,shape=[LAYER1_NODE]))
    #生成输出层参数
    weights2=tf.Variable(tf.truncated_normal([LAYER1_NODE,OUTPUT_NODE],stddev=0.1))
    biases2=tf.Variable(tf.constant(0.1,shape=[OUTPUT_NODE]))
    y=inference(x,None,weights1,biases1,weights2,biases2)


    #定义存储训练轮数的变量
    global_step=tf.Variable(0,trainable=False)
    #初始化滑动平均类
    variable_average=tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DACAY,global_step)
    variable_average_op=variable_average.apply(tf.trainable_variables())
    average_y=inference(x,variable_average,weights1,biases1,weights2,biases2)
    #计算交叉熵:损失函数
    #采用sparse_softmax_cross_entropy_with_logits函数计算交叉熵,当分类问题只有一个答案时可以使用这个计算交叉熵。
    cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(
        labels=tf.arg_max(y_,1),logits=y)
    #计算交叉熵损失
    cross_entropy_mean=tf.reduce_mean(cross_entropy)
    #计算L2正则化损失
    regularizer=tf.contrib.layers.l2_regularizer(REGULARIZATION_RATE)
    #计算模型的正则化损失
    regularization=regularizer(weights1)+regularizer(weights2)
    #计算总的损失
    loss=cross_entropy_mean+regularization
    #设置指数衰减的学习率
    learning_rate=tf.train.exponential_decay(LEARNING_RATE_BASE,                #基础学习率
    global_step,                                                                #迭代轮数
    mnist.train.num_examples/BATCH_SIZE,                                        #训练所有的数据需要的迭代次数
    LEARNING_RATE_DECAY)                                                        #学习率衰减速度

    #优化算法来优化损失函数
    train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step)
    with tf.control_dependencies([train_step,variable_average_op]):
        train_op=tf.no_op(name='train')
    correct_prediction=tf.equal(tf.argmax(average_y,1),tf.argmax(y_,1))
    accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
    with tf.Session() as sess:
        tf.global_variables_initializer().run()
        validate_feed={x:mnist.validation.images,y_:mnist.validation.labels}
        test_feed={x:mnist.test.images,y_:mnist.test.labels}
        for i in range(TRAINING_STEPS):
            if i%1000==0:
                validate_acc=sess.run(accuracy,feed_dict=validate_feed)
                print('after %d training steps,validation accuracy ' 'using average model is %g'%(i,validate_acc))
            #产生batch
            xs,ys=mnist.train.next_batch(BATCH_SIZE)
            sess.run(train_op,feed_dict={x:xs,y_:ys})
        #验证最终的正确率
        test_acc=sess.run(accuracy,feed_dict=test_feed)
        print('after %d training steps,validation accuracy ' 'using average model is %g'%(i,test_acc))


def main(argv=None):
    mnist=input_data.read_data_sets('mnist_dir\\mnist',one_hot=True)
    train(mnist)

if __name__=='__main__':
    tf.app.run()
        




        




一些重要的函数

1.激活函数(前向传播,产生一个结果)

线性激活函数和激活函数去线性化
一般需要对线性函去线性化,tensorflow中定义了7中非线性激活函数tf.nn.relu,tf.sigmoid,tf.tanh等

2.损失函数(计算得到的结果和正确值之间的差距)

1损失函数包括经典的softmax等损失函数,通过将前向传播的结果作为输入,产生一个不同类别概率输出。

3.反向传播 梯度下降(神经网络优化)

梯度下降就是通过不断调节参数,使总损失朝着更小的方向移动,这里的小有可能是局部最小。由于损失计算太过耗时,为了加速计算,出现了随机梯度下降,这种算法优化的不是全部训练数据的损失,而是在每一轮迭代中,随机优化某一条数据上的损失,这样每一轮参数更新的速度就加快了,缺点,因为不是全部数据,所以无法达到全局最优,甚至无法到达局部最优。
为了综和梯度下降和随机梯度下降,采取了折中的策略——每次计算一小部分训练数据的损失函数,也就是batch_size,在一个batch上优化参数速度快,且在全局可减小收敛迭代次数,有点分治的感觉

4.补充(神经网络的进一步优化)

听过设置学习率控制参数更新的幅度,不宜过大,也不宜过小,过大不容易收敛,过小太过耗时,收敛较慢,tensorflow中给出了设置学习率的方法——指数衰减法,它会随着迭代的继续减小学习率,使得衰减趋于平缓

5.正则化(过拟合问题)

过拟合就是训练出来的的模型可能对训练数据刻画的太好,而对时间数据的预测却并不能很好的预测。正则化就是在损失函数中加入刻画模型复杂度的指标。 R ( w ) = J ( θ ) + λ ∗ R ( w ) R(w)=J(\theta)+\lambda*R(w) R(w)=J(θ)+λR(w)。其中R(w)刻画的是模型的复杂程度, λ \lambda λ是权重。这里的 θ \theta θ值得是神经网路所有的参数。一般模型复杂度由w决定。常见的刻画模型复杂度的函数 R ( w ) R(w) R(w)有两种,一种是 L 1 L1 L1正则化 R ( w ) = ∣ ∣ w ∣ ∣ 1 = ∑ i ∣ w i ∣ R(w)=||w||_1=\sum_i|w_i| R(w)=w1=iwi
L 2 L2 L2正则化
R ( w ) = ∣ ∣ w ∣ ∣ 2 2 = ∑ i ∣ w i 2 ∣ R(w)=||w||_2^2=\sum_i|w_i^2| R(w)=w22=iwi2
正则化就是通过限制权重的大小防止模型任意拟合随机噪声 L 1 L1 L1会让参数变得稀疏, L 2 L2 L2则不会,相对来说 L 2 L2 L2更为简洁在实际中需要结合二者 R ( w ) = ∑ i α ∣ w i ∣ + ( 1 − α ) ∗ w i 2 R(w)=\sum_i\alpha|w_i|+(1-\alpha)*w_i^2 R(w)=iαwi+(1α)wi2

滑动平均模型

滑动平均模型可使模型在测试数据数据上更加健壮,在使用梯度下降时使用滑动平均模型可以提高模型在测试集上的表现tensorflow提供了tf.ExponentialMovingAverage来实现滑动平均模型,在初始化ExponentialMovingAverage需要提供decay(衰减率),这个衰减率用于控制模型更新的速率。ExponentialMovingAverage会为每个参数维护一个影子变量,每次更新变量都会更新影子变量

总结

总结一下自己对于神经网络的了解
首先,神经网络分为输入层,隐藏层,输出层,每层都有一个维度,也就是这里的每层的节点,这里想说一下batch_size
batch_size:每次训练的样本数
如果设置的过大
1.对内存要求较高
2.训练到一定程度参数便变化不大,梯度下降方向也不变了
如果设置的过小
收敛困难,每次修正参数都会有比较大的变化
再就是前向传播产生预测值,通过反向传播更新参数,达到训练目的则停止训练,反之,则重新取下一个样本进行训练,最后得到结果

感受

感觉今天比较开心吧,想学习更多,备战明年的数模。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值