学习目标

  • 目标

    • 知道softmax回归的原理
    • 应用softmax_cross_entropy_with_logits实现softamx以及交叉熵损失计算
    • 应用matmul实现多隐层神经网络的计算
  • 应用
    • 应用TensorFlow完成Mnist手写数字势识别

到目前为止,我们所接触的都是二分类问题,神经网络输出层只有一个神经元,表示预测输出\hat{y}​y​^​​是正类的概率{P}(y=1|x), \hat{y} > {0.5}P(y=1∣x),​y​^​​>0.5则判断为正类,反之判断为负类。那么对于多分类问题怎么办?

2.1.1 Softmax 回归

对于多分类问题,用 N表示种类个数,那么神经网络的输出层的神经元个数必须为L[output]=N, 每个神经元的输出依次对应属于N个类别当中某个具体类别的概率,即 P(y=N_1|x),..,P(y=N_n|x)P(y=N​1​​∣x),..,P(y=N​n​​∣x)。

输出层即:

Z^{[L]} = W^{[L]}a^{[L-1]} + b^{[L]}Z​[L]​​=W​[L]​​a​[L−1]​​+b​[L]​​,Z的输出值个数为类别个数

需要对所有的输出结果进行一下softmax公式计算:

a^{[L]}_i = \frac{e^{Z^{[L]}_i}}{\sum^C_{i=1}e^{Z^{[L]}_i}}a​i​[L]​​=​∑​i=1​C​​e​Z​i​[L]​​​​​​e​Z​i​[L]​​​​​​,并且满足\sum^C_{i=1}a^{[L]}_i = 1∑​i=1​C​​a​i​[L]​​=1,我们来看一下计算案例:

2.1.2 交叉熵损失

对于softmax回归(逻辑回归代价函数的推广,都可称之为交叉熵损失),它的代价函数公式为:

L(\hat y, y) = -\sum^C_{j=1}y_jlog\hat y_jL(​y​^​​,y)=−∑​j=1​C​​y​j​​log​y​^​​​j​​

总损失函数可以记为J = \frac{1}{m}\sum^m_{i=1}L(\hat y, y)J=​m​​1​​∑​i=1​m​​L(​y​^​​,y)

逻辑回归的损失也可以这样表示,:

所以与softmax是一样的,一个二分类一个多分类衡量。

对于真实值会进行一个one-hot编码,每一个样本的所属类别都会在某个类别位置上标记。

上图改样本的损失值为:

0log(0.10)+0log(0.05)+0log(0.15)+0log(0.10)+0log(0.05)+0log(0.20)+1log(0.10)+0log(0.05)+0log(0.10)+0log(0.10)0log(0.10)+0log(0.05)+0log(0.15)+0log(0.10)+0log(0.05)+0log(0.20)+1log(0.10)+0log(0.05)+0log(0.10)+0log(0.10)

注:关于one_hot编码

框架使用

  • 便于编程:包括神经网络的开发和迭代、配置产品;

  • 运行速度:特别是训练大型数据集时;

目前最火的深度学习框架大概是 Tensorflow 了。Tensorflow 框架内可以直接调用梯度下降算法,极大地降低了编程人员的工作量。例如以下代码:

2.1.3 案例:Mnist手写数字识别神经网络实现

2.1.3.1 数据集介绍

文件说明:

  • train-images-idx3-ubyte.gz: training set images (9912422 bytes)
  • train-labels-idx1-ubyte.gz: training set labels (28881 bytes)
  • t10k-images-idx3-ubyte.gz: test set images (1648877 bytes)
  • t10k-labels-idx1-ubyte.gz: test set labels (4542 bytes)

网址:http://yann.lecun.com/exdb/mnist/

2.1.3.2 特征值

2.1.3.3 目标值

2.1.3.4 Mnist数据获取API

TensorFlow框架自带了获取这个数据集的接口,所以不需要自行读取。

  • from tensorflow.examples.tutorials.mnist import input_data

    • mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True)

      • mnist.train.next_batch(100)(提供批量获取功能)
      • mnist.train.images、labels
      • mnist.test.images、labels

2.1.3.5 网络设计

我们采取两个层,除了输入层之外。第一个隐层中64个神经元,最后一个输出层(全连接层)我们必须设置10个神经元的神经网络。

2.1.3.6 全连接层计算

  • tf.matmul(a, b,name=None)+bias

    • return:全连接结果,供交叉损失运算
  • tf.train.GradientDescentOptimizer(learning_rate)
    • 梯度下降
    • learning_rate:学习率
    • method:
      • minimize(loss):最小优化损失

2.1.3.7 前期确定事情与流程

  • 确定网络结构以及形状

    • 第一层参数:输入:x [None, 784] 权重:[784, 64] 偏置[64],输出[None, 64]
    • 第二层参数:输入:[None, 64] 权重:[64, 10] 偏置[10],输出[None, 10]
  • 流程:
    • 获取数据
    • 前向传播:网络结构定义
    • 损失计算
    • 反向传播:梯度下降优化
  • 功能完善
    • 准确率计算
    • 添加Tensorboard观察变量、损失变化
    • 训练模型保存、模型存在加载模型进行预测

2.1.3.8 主网络搭建流程

  • 获取数据
mnist = input_data.read_data_sets("./data/mnist/input_data/", one_hot=True)
  • 定义数据占位符,Mnist数据实时提供给placeholder
# 1、准备数据
# x [None, 784] y_true [None. 10]
with tf.variable_scope("mnist_data"):x = tf.placeholder(tf.float32, [None, 784])y_true = tf.placeholder(tf.int32, [None, 10])
  • 两层神经元网络结果计算
# 2、全连接层神经网络计算# 类别:10个类别  全连接层:10个神经元# 参数w: [784, 10]   b:[10]# 全连接层神经网络的计算公式:[None, 784] * [784, 10] + [10] = [None, 10]# 随机初始化权重偏置参数,这些是优化的参数,必须使用变量op去定义# 要进行全连接层的矩阵运算 [None, 784]*[784, 64] + [64] = [None,64]# [None, 64]*[64, 10] + [10] = [None,10]with tf.variable_scope("fc_model"):# 第一层:随机初始化权重和偏置参数,要使用变量OP 定义weight_1 = tf.Variable(tf.random_normal([784, 64], mean=0.0, stddev=1.0),name="weightes_1")bias_1 = tf.Variable(tf.random_normal([64], mean=0.0, stddev=1.0),name='biases_1')# 第二层:随机初始化权重和偏置参数,要使用变量OP 定义weight_2 = tf.Variable(tf.random_normal([64, 10], mean=0.0, stddev=1.0),name="weightes_2")bias_2 = tf.Variable(tf.random_normal([10], mean=0.0, stddev=1.0),name='biases_2')# 全连接层运算# 10个神经元# y_predict = [None,10]y1 = tf.matmul(x, weight_1) + bias_1y_predict = tf.matmul(y1, weight_2) + bias_2
  • 损失计算与优化
    # 3、softmax回归以及交叉熵损失计算with tf.variable_scope("softmax_crossentropy"):# labels:真实值 [None, 10]  one_hot# logits:全脸层的输出[None,10]# 返回每个样本的损失组成的列表loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true,logits=y_predict))# 4、梯度下降损失优化with tf.variable_scope("optimizer"):# 学习率train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

2.1.3.9 完善模型功能

  • 1、增加准确率计算
  • 2、增加变量tensorboard显示
  • 3、增加模型保存加载
  • 4、增加模型预测结果输出

如何计算准确率

  • equal_list = tf.equal(tf.argmax(y, 1), tf.argmax(y_label, 1))
  • accuracy = tf.reduce_mean(tf.cast(equal_list, tf.float32))

  • 模型评估(计算准确性)

    # 5、得出每次训练的准确率(通过真实值和预测值进行位置比较,每个样本都比较)with tf.variable_scope("accuracy"):equal_list = tf.equal(tf.argmax(y_true, 1), tf.argmax(y_predict, 1))accuracy = tf.reduce_mean(tf.cast(equal_list, tf.float32))

增加变量tensorboard显示

  • 在会话外当中增加以下代码
 # (1)、收集要显示的变量# 先收集损失和准确率tf.summary.scalar("losses", loss)tf.summary.scalar("acc", accuracy)# 维度高的张量值tf.summary.histogram("w1", weight_1)tf.summary.histogram("b1", bias_1)# 维度高的张量值tf.summary.histogram("w2", weight_2)tf.summary.histogram("b2", bias_2)# 初始化变量opinit_op = tf.global_variables_initializer()# (2)、合并所有变量opmerged = tf.summary.merge_all()
  • 在会话当中去创建文件写入每次的变量值
# (1)创建一个events文件实例
file_writer = tf.summary.FileWriter("./tmp/summary/", graph=sess.graph)# 运行合变量op,写入事件文件当中
summary = sess.run(merged, feed_dict={x: mnist_x, y_true: mnist_y})file_writer.add_summary(summary, i)

增加模型保存加载

创建Saver,然后保存

# 创建模型保存和加载
saver = tf.train.Saver()# 每隔100步保存一次模型
if i % 100 == 0:saver.save(sess, "./tmp/modelckpt/fc_nn_model")

在训练之前加载模型

# 加载模型
if os.path.exists("./tmp/modelckpt/checkpoint"):saver.restore(sess, "./tmp/modelckpt/fc_nn_model")

增加模型预测结果输出

增加标志位

tf.app.flags.DEFINE_integer("is_train", 1, "指定是否是训练模型,还是拿数据去预测")
FLAGS = tf.app.flags.FLAGS

然后判断是否训练,如果不是训练就直接预测,利用tf.argmax对样本的真实目标值y_true,和预测的目标值y_predict求出最大值的位置

            # 如果不是训练,我们就去进行预测测试集数据for i in range(100):# 每次拿一个样本预测mnist_x, mnist_y = mnist.test.next_batch(1)print("第%d个样本的真实值为:%d, 模型预测结果为:%d" % (i+1,tf.argmax(sess.run(y_true, feed_dict={x: mnist_x, y_true: mnist_y}), 1).eval(),tf.argmax(sess.run(y_predict, feed_dict={x: mnist_x, y_true: mnist_y}), 1).eval()))

4.7.3.6 完整代码

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data# 定义一个是否训练、预测的标志
tf.app.flags.DEFINE_integer("is_train", 1, "训练or预测")FLAGS = tf.app.flags.FLAGSdef full_connected_nn():"""全连接层神经网络进行Mnist手写数字识别训练:return:"""mnist = input_data.read_data_sets("./data/mnist/input_data/", one_hot=True)# 1、获取数据,定义特征之和目标值张量# xwith tf.variable_scope("data"):# 定义特征值占位符x = tf.placeholder(tf.float32, [None, 784], name="feature")# 定义目标值占位符y_true = tf.placeholder(tf.int32, [None, 10], name="label")# 2、根据识别的类别数,建立全连接层网络# 手写数字10个类别# 设计了一层的神经网络,最后一层,10个神经元# 确定网络的参数weight [784, 10] bias[10]# 要进行全连接层的矩阵运算 [None, 784]*[784, 64] + [64] = [None,64]# [None, 64]*[64, 10] + [10] = [None,10]with tf.variable_scope("fc_model"):# 第一层:随机初始化权重和偏置参数,要使用变量OP 定义weight_1 = tf.Variable(tf.random_normal([784, 64], mean=0.0, stddev=1.0),name="weightes_1")bias_1 = tf.Variable(tf.random_normal([64], mean=0.0, stddev=1.0),name='biases_1')# 第二层:随机初始化权重和偏置参数,要使用变量OP 定义weight_2 = tf.Variable(tf.random_normal([64, 10], mean=0.0, stddev=1.0),name="weightes_2")bias_2 = tf.Variable(tf.random_normal([10], mean=0.0, stddev=1.0),name='biases_2')# 全连接层运算# 10个神经元# y_predict = [None,10]y1 = tf.matmul(x, weight_1) + bias_1y_predict = tf.matmul(y1, weight_2) + bias_2# 3、根据输出结果与真是结果建立softmax、交叉熵损失计算with tf.variable_scope("softmax_cross"):# 先进性网络输出的值的概率计算softmax,在进行交叉熵损失计算all_loss = tf.nn.softmax_cross_entropy_with_logits(labels=y_true,logits=y_predict,name="compute_loss")# 求出平均损失loss = tf.reduce_mean(all_loss)# 4、定义梯度下降优化器进行优化with tf.variable_scope("GD"):train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)# 5、求出每次训练的准确率为with tf.variable_scope("accuracy"):# 求出每个样本是否相等的一个列表equal_list = tf.equal(tf.argmax(y_true, 1), tf.argmax(y_predict, 1))# 计算相等的样本的比例accuracy = tf.reduce_mean(tf.cast(equal_list, tf.float32))# 1、收集要在tensorboard观察的张量值# 数值型-->scalar 准确率,损失tf.summary.scalar("loss", loss)tf.summary.scalar("acc", accuracy)# 维度高的张量值tf.summary.histogram("w1", weight_1)tf.summary.histogram("b1", bias_1)# 维度高的张量值tf.summary.histogram("w2", weight_2)tf.summary.histogram("b2", bias_2)# 2、合并变量merged = tf.summary.merge_all()# 1、创建保存模型的OPsaver = tf.train.Saver()# 开启会话进行训练with tf.Session() as sess:# 初始化变量OPsess.run(tf.global_variables_initializer())# 创建events文件file_writer = tf.summary.FileWriter("./tmp/summary/", graph=sess.graph)# 加载本地模型继续训练或者拿来进行预测测试集# 加载模型,从模型当中找出与当前训练的模型代码当中(名字一样的OP操作),覆盖原来的值ckpt = tf.train.latest_checkpoint("./tmp/model/")# 判断模型是否存在if ckpt:saver.restore(sess, ckpt)if FLAGS.is_train == 1:# 循环训练for i in range(2000):# 每批次给50个样本mnist_x, mnist_y = mnist.train.next_batch(50)_, loss_run, acc_run, summary = sess.run([train_op, loss, accuracy, merged],feed_dict={x: mnist_x, y_true: mnist_y})print("第 %d 步的50个样本损失为:%f , 准确率为:%f" % (i, loss_run, acc_run))# 3、写入运行的结果到文件当中file_writer.add_summary(summary, i)# 每隔100步保存一次模型的参数if i % 100 == 0:saver.save(sess, "./tmp/model/fc_nn_model")else:# 进行预测# 预测100个样本for i in range(100):# label [1, 10]image, label = mnist.test.next_batch(1)# 直接运行网络的输出预测结果print("第 %d 样本,真实的图片数字为:%d, 神经网络预测的数字为:%d " % (i,tf.argmax(label, 1).eval(),tf.argmax(sess.run(y_predict, feed_dict={x: image, y_true: label}), 1).eval()))return Noneif __name__ == '__main__':full_connected_nn()

4.7.4 调整学习率调整网络参数带来的问题

如果我们对网络当中的学习率进行修改,也就是一开始我们并不会知道学习率填哪些值,也并不知道调整网络的参数大小带来的影响(第一部分第四节)。

  • 假设学习率调整到1,2
  • 假设参数调整到比较大的值,几十、几百

总结:参数调整了之后可能没影响,是因为网络较小,可能并不会造成后面所介绍的梯度消失或者梯度爆炸

4.7.5总结

  • 掌握softmax公式以及特点
  • tensorflow.examples.tutorials.mnist.input_data 获取Mnist数据
  • tf.matmul(a, b,name=None)实现全连接层计算
  • tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)实现梯度下降优化

深度学习进阶:多分类与TensorFlow相关推荐

  1. vs2017 开始自己的第一个深度学习例子——MNIST分类(基于TensorFlow框架)

    这是针对于博客vs2017安装和使用教程(详细)的深度学习例子--MNIST分类项目新建示例 目录 一.新建项目 二.运行代码 三.生成结果 一.新建项目 1.项目创建参照博主文章:vs2017 开始 ...

  2. 阿里巴巴虾米的机器学习与深度学习进阶记

    20世纪70年代初,一名名叫Geoffrey Hinton的英国研究生开始制作简单的数学模型,来描述人脑中的神经元是如何直观地理解世界的.被称为人工神经网络的技术几十年来一直被认为是不切实际的.但是在 ...

  3. 万字总结Keras深度学习中文文本分类

    摘要:文章将详细讲解Keras实现经典的深度学习文本分类算法,包括LSTM.BiLSTM.BiLSTM+Attention和CNN.TextCNN. 本文分享自华为云社区<Keras深度学习中文 ...

  4. 作为深度学习最强框架的TensorFlow如何进行时序预测!(转)

    作为深度学习最强框架的TensorFlow如何进行时序预测! BigQuant 2 个月前 摘要: 2017年深度学习框架关注度排名tensorflow以绝对的优势占领榜首,本文通过一个小例子介绍了T ...

  5. 12大深度学习开源框架(caffe,tensorflow,pytorch,mxnet等)汇总详解

    这是一篇总结文,给大家来捋清楚12大深度学习开源框架的快速入门,这是有三AI的GitHub项目,欢迎大家star/fork. https://github.com/longpeng2008/yousa ...

  6. 基于深度学习的时间序列分类[含代码]

    基于深度学习的时间序列分类 引言 数据集 实验环境搭建 实验设计 实验代码 实验结果 引言 目前,深度学习在计算机视觉和语音识别上有了非常广泛的应用,但是在工业应用方面还没有完善的体系,一方面缺乏数据 ...

  7. 【零基础深度学习教程第二课:深度学习进阶之神经网络的训练】

    深度学习进阶之神经网络的训练 神经网络训练优化 一.数据集 1.1 数据集分类 1.2 数据集的划分 1.3 同源数据集的重要性 1.4 无测试集的情况 二.偏差与方差 2.1 概念定义 2.1.1 ...

  8. 读书笔记:深度学习进阶-自然语言处理(俗称鱼书二)

    文章目录 前言 一.神经网络的复习 二.自然语言和单词的分布式表示 2.1什么是自然语言处理 2.2同义词词典 2.3基于计数的方法 2.3.1基于python的语料库的预处理 2.3.2单词的分布式 ...

  9. 自然语言处理入门实战2:基于深度学习的文本分类

    自然语言处理入门实战2:基于深度学习的文本分类 数据集 数据预处理 模型 模型训练 模型测试 参考 本文参考复旦大学自然语言处理入门练习,主要是实现基于深度学习的文本分类. 环境:python3.7 ...

  10. 自然语言处理入门实战3:基于深度学习的文本分类(2)

    基于深度学习的文本分类(2) 数据集 数据预处理 CNN模型 RNN模型 利用CNN模型进行训练和测试 利用RNN模型进行训练和测试 预测 总结 参考 本文主要是使用CNN和RNN进行文本分类操作. ...

最新文章

  1. solr查询工作原理深入内幕
  2. 2009暑期实践报告
  3. springcloud 消息队列_全面而且简洁介绍SpringCloud微服务
  4. 灯塔的出现给那些有想法,有能力而又缺乏资金的社区人士提供了一条途径
  5. javascript 自定义Map
  6. Java 编码规范11(安全规约)
  7. 常用公差配合表图_机械密封零件的公差配合与技术要求
  8. APP性能测试-FPS测试
  9. li指令 汇编_51单片机(九)汇编指令
  10. matlab拟合反比例函数,y与x的函数关系式图像 已知变量y与x之间的函数
  11. 企业微信周末加班怎么打卡?
  12. 基于Python语言的文件与文件夹管理
  13. Win10 清空回收站选项点不了怎么解决?
  14. 王子恢:手机视频牌照与行政权力租界
  15. 细数一次装修中遇到的几十个坑
  16. iOS应用上传个人头像
  17. expect 中的回车和换行
  18. python爬取12306_python爬取12306列车信息
  19. ofo开放共享单车大数据平台
  20. 最新!中国内地大学ESI排名出炉:362所高校上榜!

热门文章

  1. 总结一下在使用某里云服务器的过程中出现过的一些问题
  2. 伍六七带你学算法 入门篇-矩形重叠
  3. 规范的 Commit Message
  4. Python 多进程笔记 — 启动进程的方式、守护进程、进程间通信、进程池、进程池之间通信、多进程生产消费模型
  5. BERT的通俗理解 预训练模型 微调
  6. OpenCL,OpenGL编译
  7. NVIDIA GPU上的直接线性求解器
  8. nvGRAPH原理概述
  9. 微调BERT:序列级和令牌级应用程序
  10. Android报错:java.lang.NoClassDefFoundError: Failed resolution of: Ljava/util/Base64;如何解决