TensorFlow(二)MNIST数字识别 与 相关知识
代码在最后
线性模型有局限性,如果一个问题能够用一条直线划分,那么线性模型就可以解决这个问题
将神经元的输出通过激活函数–非线性化
经典损失函数:
- 分类问题:
交叉熵刻画了两个概率分布之间的记录距离。(交叉熵越小,两者越接近)使用交叉熵前提:结果是概率分布。可以使用Softmax函数:
(1) 回归问题:常用的损失函数是均方误差(MSE)
tensorflow的实现:mse = tf.reduce_mean(tf.square(y_ - y))
反向传播算法和梯度下降算法(常用的优化方法)
梯度下降算法会迭代更新参数,还需定义学习率,来指定每次参数更新的幅度
梯度下降算法不一定得到全局最优解,需保证是凸函数
每次只计算一小部分训练数据的损失函数,称为一个batch
神经网络的优化的过程分类为两个阶段:
- 通过前向传播算法计算得到预测值
- 通过反向传播算法计算损失函数对每一个参数的梯度,再根据梯度和学习率使用梯度下降算法更新每一个参数
更加灵活的学习率的设置方法——指数衰减法
避免过拟合问题——正则化(L1,L2)
regularizer = tf.contrib.layers.l2_regularizer(REGULARIZATION_RATE)
在随机梯度下降算法中,使用滑动平均模型,提高准确率:
tf.train.ExponentialMovingAverage
来实现,下面例子详细介绍:
(详细注释)
import tensorflow as tf
import tensorflow.contrib as ct
old_v = tf.logging.get_verbosity()
tf.logging.set_verbosity(tf.logging.ERROR)
from tensorflow.examples.tutorials.mnist import input_data
tf.logging.set_verbosity(old_v)
INPUT_NODE = 784 # 输入层的节点数。对于 MNIST 数据集,就等于图片的像素
OUTPUT_NODE = 10 # 输出层的节点数。这个等于类别的数目。因为在 MNIST 的数据集中需要区分的是 0~9 这 10 个数字,所以这里输出层的节点数为 10
# 配置神经网络的参数
LAYER1_NODE = 500 # 隐藏层节点数。这里使用只有一个隐藏层的网络结构作为样例。这个隐藏层有500个节点
BATCH_SIZE = 100 # 一个训练 batch 中的训练数据个数。数字越小时,训练过程越接近随机梯度下降;数字越大时,训练越接近梯度下降
LEARNING_RATE_BASE = 0.8 # 基础的学习率
LEARNING_RATE_DECAY = 0.99 # 学习率的衰减率
REGULARIZATION_RATE = 0.0001 # 描述模型复杂度的正则化项在损失函数中的系数
TRAINING_STEPS = 30000 # 训练轮数
MOVING_AVERAGE_DECAY = 0.99 # 滑动平均衰减率
# 一个辅助函数,给定神经网络的输入和所有参数,计算神经网络的前向传播结果。在这里定义了一个使用 ReLU 激活函数的三层全连接神经网络。
# 通过加入隐藏层实现了多层网络结构, 通过 ReLU 激活函数实现了去线性化。在这个函数中也支持传入用于计算参数平均值得类,这样方便在
# 测试时使用滑动平均模型。
def inference(input_tensor, avg_class, weights1, biases1, weights2, biases2):
# 当没有提供滑动平均类时,直接使用参数当前的取值
if avg_class is None:
# 计算隐藏层的前向传播结果,这里使用了 ReLU 激活函数
layer1