神经网络实战之Softmax回归


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

了解深度学习遇到的一些问题
知道批梯度下降与MiniBatch梯度下降的区别
知道指数加权平均的意义
知道动量梯度、RMSProp、Adam算法的公式意义
知道学习率衰减方式
知道参数初始化策略的意义

了解偏差与方差的意义
知道L2正则化与L1正则化的数学意义
知道Droupout正则化的方法
了解早停止法、数据增强法的其它正则化方式

知道常用的一些神经网络超参数
知道BN层的意义以及数学原理

1.多分类与Tensorflow

学习目标:

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

1.1 Softmax回归

在这里插入图片描述

1.2 交叉熵损失

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

交叉熵损失:目标值是one-hot编码. 预测值是概率,所有样本概率和为1.
                   减少损失的过程,就是提高目标值为1的位置,对应的预测值概率的过程.这个原理由交叉熵损失函数决定.
下图是在网址playground下的分类运行演示.
在这里插入图片描述

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

在这里插入图片描述
文件说明:

  • 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)
    网址

1.3.1 特征值

在这里插入图片描述
在这里插入图片描述

1.3.2 目标值

在这里插入图片描述

1.3.3 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

1.3.4 网络设计

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

在这里插入图片描述

1.3.4.1 全连接层计算
  • tf.matmul(a, b,name=None)+bias
    • return:全连接结果,供交叉损失运算
  • tf.train.GradientDescentOptimizer(learning_rate)
    • 梯度下降
    • learning_rate:学习率
    • method:
      • minimize(loss):最小优化损失
1.3.4.2 前期确定事情与流程
  • 确定网络结构以及形状
    • 第一层参数:输入:x [None, 784] 权重:[784, 64] 偏置[64],输出[None, 64]
    • 第二层参数:输入:[None, 64] 权重:[64, 10] 偏置[10],输出[None, 10]
  • 流程:
    • 获取数据
    • 前向传播:网络结构定义
    • 损失计算
    • 反向传播:梯度下降优化
    • 功能完善
  • 准确率计算
    • 添加Tensorboard观察变量、损失变化
    • 训练模型保存、模型存在加载模型进行预测
1.3.4.3 主网络搭建流程
  • 获取数据
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_1

        y_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.3.5.4 完善模型功能
  • 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)

   # 初始化变量op
   init_op = tf.global_variables_initializer()

   # (2)、合并所有变量op
   merged = 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()
                                                      )
                                                      )

在这里插入图片描述

1.3.5 完整代码

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.FLAGS


def full_connected_nn():
    """
    全连接层神经网络进行Mnist手写数字识别训练
    :return:
    """
    mnist = input_data.read_data_sets("./data/mnist/input_data/", one_hot=True)

    # 1、获取数据,定义特征之和目标值张量
    # x
    with 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_1

        y_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、创建保存模型的OP调整学习率调整网络参数带来的问题
    saver = tf.train.Saver()

    # 开启会话进行训练
    with tf.Session() as sess:

        # 初始化变量OP
        sess.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 None


if __name__ == '__main__':
    full_connected_nn()

输出结果:

  • 训练结果:
    在这里插入图片描述
  • 预测结果:
    在这里插入图片描述
    tensorbood结果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.3.6 总结

  • 掌握softmax公式以及特点
  • tensorflow.examples.tutorials.mnist.input_data 获取Mnist数据
  • tf.matmul(a, b,name=None)实现全连接层计算
  • tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)实现梯度下降优化
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
卷积神经网络中的softmax函数是一种常用的激活函数,用于将神经网络的输出转化为概率分布。softmax函数可以将任意实数向量转化为概率分布向量,使得各个元素的取值范围在0到1之间,并且所有元素的和为1。在卷积神经网络中,softmax函数通常被用于最后一层的全连接层,将网络的输出转化为类别概率分布。 通过softmax函数,卷积神经网络可以根据输入图像的特征,计算出每个类别的概率值,从而实现图像分类的任务。softmax函数的输入是一个向量,其中每个元素表示对应类别的得分或激活值。softmax函数通过对输入向量中的每个元素进行指数运算和归一化,得到每个类别的概率值。概率值大的类别被认为是预测结果。 在训练过程中,卷积神经网络通过比较softmax函数输出的概率分布与真实标签的分布,计算出模型的损失值。常用的损失函数包括交叉熵损失函数。交叉熵损失函数可以衡量模型输出的概率分布与真实标签的差异,从而指导模型的参数更新。 总结来说,softmax函数在卷积神经网络中起到将网络的输出转化为概率分布的作用,帮助实现图像分类的任务。同时,交叉熵损失函数可以用来衡量模型输出的概率分布与真实标签的差异。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [深度学习—卷积神经网络(Convolutional Neural Networks)](https://blog.csdn.net/qq_28505705/article/details/102944765)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [卷积神经网络系列之softmaxsoftmax loss和cross entropy的详细讲解 简单明了](https://blog.csdn.net/weixin_42713739/article/details/103203743)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值