神经网络解决多分类问题的方法与案例演示

释放双眼,带上耳机,听听看~!
本文介绍神经网络如何解决多分类问题,包括使用Softmax分类和交叉熵损失函数的方法。通过TensorFlow案例演示,展示了神经网络在手写数字识别中的应用。

1. 多分类问题

思考一个问题,神经网络输出的结果如何解决分类问题呢?解决多分类问题,一个常用的方法就是:我们主要考虑在logistic后加上Softmax分类映射,输出分类的概率,进而进行分类。

  • 从神经网络结构的角度去看,对神经网络设置n个输出节点,其中n就是分类的类别数
  • softmax回归:softmax回归可以将神经网络的n个输出节点转换成该分类的发生概率

神经网络解决多分类问题的方法与案例演示

根据softmax计算公式可以看出,若上一步计算出的结果越大,则经过softmax计算后的结果也越大,说明该事件发生的概率越大。softmax好处是n个输出节点经过softmax计算出的概率,加和等于1(所有事件发生的可能性总和为1)。

1.1 损失函数

回想一下,线性回归的损失函数我们常用均方误差(MSE),逻辑回归的损失函数常用对数似然函数。损失函数是用来后续梯度下降优化的关键,那么多分类问题的损失函数应该用哪一个呢?神经网络常用的衡量损失的方法是交叉熵损失函数。

  • 为了衡量距离,目标值需要进行one-hot编码,能与概率值一一对应

TensorFlow中交叉熵损失API:

tf.nn.softmax_cross_entropy_with_logits(labels=None, logits=None, name=None)

  • 计算logits和label之间的交叉损失熵
  • labels:标签值(真实值)
  • logits:样本加权之后的值,线性加权后的输出
  • return:返回损失值列表

tf.reduce_mean(input_tensor)

  • 计算张量的尺寸的元素平均值

2. 案例演示

Mnist数据集介绍,每一张图片包含2828=784个像素。特征值由2828个元素组成,对于目标值,总共有0-9十个类别。因为是分类问题,使用的是one-hot编码。

接下来,我们考虑使用全连接神经网络进行手写数字识别:

  • 全连接神经网路参数变化形式:y=w1x1+w2x2+w3x3+…+wnxny=w1x1+w2x2+w3x3+…+wnxn

  • 张量变化形式:x[batch,784]∗w[784,10]+bias=ypredict[batch,10]x[batch, 784] * w[784, 10] + bias = y_predict[batch, 10]

下面将进行案例演示:

2.1 步骤1

  • 导入所需模块,因为本地下载的是Tensoflow2.x版本,想要运行Tensorflow1.x版本语法,需要开启兼容模式,禁用2.x版本语法。
  • 另外,我们需要通过api直接导入mnist数据,所以,需要额外导入input_data方法。
import tensorflow as tf
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()
import os
from tensorflow.examples.tutorials.mnist import input_data 

步骤2:

构造函数,进行神经网络搭建及训练,主要分为如下几步:

  • 准备数据
    • 使用占位符构造x数据与y_true数据
  • 构建模型
    • 构造weight,bias,y_predict
    • 构造参数传递关系过程
  • 构造损失函数
    • 我们使用交叉熵损失函数,函数内部传入真实值变量与预测值变量
  • 优化损失
    • 使用梯度下降优化器进行优化损失
    • 学习率设置为0.02
  • 开启会话
    • 开启会话才能查看内部参数,使其运行起来
    • 一次批处理大小为100
  • 开始训练
    • 训练轮数设置为500次
    • 接受训练过程中的损失值
def full_connection():
    """
    用全连接神经网络识别手写数字
    """
    # 1. 准备数据
    mnist = input_data.read_data_sets("./mnist_data", one_hot=True)
    x = tf.placeholder(dtype=tf.float32, shape=(None, 784)) # 784列:一张图片由784个像素组成,一次传入N张图片
    y_true = tf.placeholder(dtype=tf.float32, shape=(None, 10)) # 10列
    
    # 2. 构建模型
    weights = tf.Variable(initial_value=tf.random_normal(shape=(784, 10)))
    bias = tf.Variable(initial_value=tf.random_normal(shape=[10])) # 10个标量
    y_predict = tf.matmul(x, weights) + bias
    
    # 3. 构造损失函数
    error = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true, logits=y_predict)) # 交叉熵损失函数,再求平均值
    
    # 4. 优化损失
    optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.02).minimize(error) # 梯度下降优化器,最小化损失
    
    # 初始化变量
    init = tf.global_variables_initializer()
    
    # 开启会话
    with tf.Session() as sess:
        sess.run(init)
        image, label = mnist.train.next_batch(100)
        
        
        print("训练之前的损失loss为:%f" % sess.run(error, feed_dict={x:image, y_true:label}))
        
        # 开始训练
        for i in range(500):
            _, loss = sess.run([optimizer,error], feed_dict={x:image, y_true:label}) # optimizer是一个操作,不需要其返回值,用_(None)来接收
            print("第%d次训练,损失为%f" % (i+1, loss))
            
    return None
        
full_connection()      

代码运行结果如下图所示:

  • 图中可以看出经过500论训练,损失变为1.16左右。还有下降趋势,可以继续增大训练轮数。

神经网络解决多分类问题的方法与案例演示

本文正在参加「金石计划 . 瓜分6万现金大奖」

本网站的内容主要来自互联网上的各种资源,仅供参考和信息分享之用,不代表本网站拥有相关版权或知识产权。如您认为内容侵犯您的权益,请联系我们,我们将尽快采取行动,包括删除或更正。
AI教程

图表征学习:传统方法和现代技术

2023-11-25 14:47:55

AI教程

如何用LangChain解决知识库应用中的问题

2023-11-25 14:54:14

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索