tensorflow实战学习笔记(1)

匿名 (未验证) 提交于 2019-12-03 00:32:02

tensorflow提供了三种不同的加速神经网路训练的并行计算模式

(一)数据并行:

(二)模型并行:

(三)流水线并行:

主流深度学习框架对比(2017):

第一章

Tensorflow实现Softmax Regression识别手写数字

数据集:28x28像素的手写数字组成。

1.在导入mnist 数据集时,会碰到一系列的问题,在这里做一些简要的说明:

(1)导入数据集时报错如下:(图是别地找的,但报错信息就是这样)

碰到这种情况,直接在官网上下载数据集,不用解压,将存放数据集的路径添加到数据读取函数中,就可以解决,具体见后面的代码:

(2)由于我之前用的是cpu版本的tensorflow,在做mnist实验时没有遇到这种情况,后来更换为gpu版本的时,在读取数据时会报错, 具体信息是:SymbolDatabase has no attribute RegisterServiceDescriptor(图是别地找的,但报错信息就是这样)

百度了一下发现解决的方案很少,也没有提供有价值的信息, 最后在github上这里找到了一些信息。看大家的讨论大致意思是由于protobuf版本的问题,打开pycharm的interpreter:

有一个3.2.0版本的protobuf.

怎么会同时从在两个版本的protobuf,我好想知道为什么了



问题解决了。

继续我的mnist手写字体识别。。。。。。。。用一个没有隐含层的神经网络实现mnist手写字体识别。

重点:理解softmax regression

在处理多分类问题时,通常需要使用softmax regression模型,它的工作原理是:将可以判断为某类的特征相加,

然后将这写特征转换为判定是这一类的概率。具体的原理及数学推导可参考这篇博客。

2.理解交叉熵损失函数:

cross-entropy的定义如下:


现在有了损失函数定义,现在再定义一个优化算法,就可以对模型进行训练:

常见的优化算法有随机梯度下降。

完整代码:

import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data  mnist_data_path = r'E:\code\112\tensorflow_project\chapter5\data\tensorflow_data' mnist = input_data.read_data_sets(mnist_data_path, one_hot=True)  input_nodes = 28 * 28 out_nodes = 10 x = tf.placeholder(dtype=tf.float32, shape=[None, input_nodes], name='x-input') y_ = tf.placeholder(dtype=tf.float32, shape=[None, out_nodes], name='y-input') # 定义权重矩阵 w = tf.Variable(initial_value=tf.random_normal(shape=[input_nodes, out_nodes], mean=0, stddev=0.1),                 dtype=tf.float32, trainable=True) b = tf.Variable(initial_value=tf.zeros([10]), dtype=tf.float32, trainable=True) output = tf.matmul(x, w) + b y = tf.nn.softmax(output) # 定义一个loss function来描述模型对分类问题的分类精度 cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y))) train_step = tf.train.GradientDescentOptimizer(learning_rate=0.5).minimize(cross_entropy)  correction_prediction = tf.equal(tf.argmax(y, axis=1), tf.argmax(y_, axis=1)) accuracy = tf.reduce_mean(tf.cast(correction_prediction, tf.float32))  with tf.Session() as sess:     init_op = tf.initialize_all_variables()     sess.run(init_op)     for i in range(1000):         # 每次训练都从数据集中随机抽取一百个数据,构成一个mini-batch,对神经网络进行训练         # 使用一小部分样本进行训练称为随机梯度下降(SGD),如果每次训练都使用全部样本,计算量大,而且也不容易跳出局部最优。         # 使用随机梯度下降可以得到更快的收敛速度         batch_x, batch_y = mnist.train.next_batch(100)         sess.run(train_step, feed_dict={x: batch_x, y_: batch_y})         # print(i)         if i % 10 == 0:             accuracy_result = sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels})             print('After {} iterations the accuracy is {} .'.format(i, accuracy_result))      

运行结果:

通过上面的例子,实现了一个非常简单的softmax regression算法

下面对之前的程序进行一些改进:对神经网络添加隐藏层, 隐藏层的节点数为500,同时对神经网络参数的更新采用滑动均值模型,采用指数衰减的学习率。

(1)关于滑动均值模型:在网络的训练中采用滑动均值模型,在测试中不使用。滑动均值模型与一阶滞后滤波具有相似性,一阶滞后滤波具体表达式为:

a的取值范围为[0, 1].

本次采样值+a上次滤波结果,

采用此算法的优点是:

1、降低周期性的干扰;

2、在波动频率较高的场合有很好的效果。

tf.train.ExponentialMovingAverage 来实现滑动平均模型,在采用随机梯度下降算法训练神经网络时,使用其可以提高模型在测试数据上的鲁棒性(robustness)。TensorFlow下的 tf.train.ExponentialMovingAverage 需要提供一个衰减率参数decay。该衰减率用于控制模型更新的速度。ExponentialMovingAverage 对每一个待更新的变量(variable)都会维护一个影子变量(shadow variable)。影子变量的初始值就是这个变量的初始值:

上述公式与之前介绍的一阶滞后滤波法的公式相比较,会发现有很多相似的地方,从名字上面也可以很好的理解这个算法的原理:平滑、滤波,即使数据平滑变化,通过调整参数来调整变化的稳定性。

在滑动平滑模型中, decay 决定了模型更新的速度,越大越趋于稳定。实际运用中,decay 一般会设置为十分接近 1 的常数(0.999或0.9999)。为了使得模型在训练的初始阶段更新得更快,ExponentialMovingAverage 还提供了 num_updates 参数来动态设置 decay 的大小:

关于滑动平均模型参考了这篇博客,作者表达的很清楚,引用一下

(2)在模型中添加正则化:通过正则化,能够将表征模型复杂度的指标加入到损失函数中。

regularizer_L2 = tf.contrib.layers.l2_regularizer(regularizer_rate) loss_function = cross_entropy_mean + regularizer_L2(weight_1) + regularizer_L2(weight_2)

(3)指数衰减学习率:

在训练模型的时候,通常会遇到这种情况:我们平衡模型的训练速度和损失(loss)后选择了相对合适的学习率(learning rate),但是训练集的损失下降到一定的程度后就不在下降了,比如training loss一直在0.8和0.9之间来回震荡,不能进一步下降。如下图所示:

遇到这种情况通常可以通过适当降低学习率(learning rate)来实现。但是,降低学习率又会延长训练所需的时间。

学习率衰减(learning rate decay)就是一种可以平衡这两者之间矛盾的解决方案。学习率衰减的基本思想是:学习率随着训练的进行逐渐衰减。

  学习率衰减基本有两种实现方法:

  1. 线性衰减。例如:每过5个epochs学习率减半
  2. 指数衰减。例如:每过5个epochs将学习率乘以0.1

我采用的是指数衰减的方法:

采用指数衰减必须初始化一个初始的学习率,以及一个衰减的速率。

计算的公式为:

decayed_learning_rate = learning_rate * decay_rate^(global_step/decay_steps)

其中:

同时将神经网络的前向传播过程结构化:通过inference函数来表示

再通过定义train()函数来训练神经网络:

程序的运行结果如下所示:


后面持续更行,会添加模型保存以及调用tensorboard的部分程序。。。














易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!