一文速学-让神经网络不再神秘,一天速学神经网络基础-输出层(四)

news2024/12/27 11:39:59


前言

思索了很久到底要不要出深度学习内容,毕竟在数学建模专栏里边的机器学习内容还有一大半算法没有更新,很多坑都没有填满,而且现在深度学习的文章和学习课程都十分的多,我考虑了很久决定还是得出神经网络系列文章,不然如果以后数学建模竞赛或者是其他更优化模型如果用上了神经网络(比如利用LSTM进行时间序列模型预测),那么就更好向大家解释并且阐述原理了。但是深度学习的内容不是那么好掌握的,包含大量的数学理论知识以及大量的计算公式原理需要推理。且如果不进行实际操作很难够理解我们写的代码究极在神经网络计算框架中代表什么作用。不过我会尽可能将知识简化,转换为我们比较熟悉的内容,我将尽力让大家了解并熟悉神经网络框架,保证能够理解通畅以及推演顺利的条件之下,尽量不使用过多的数学公式和专业理论知识。以一篇文章快速了解并实现该算法,以效率最高的方式熟练这些知识。

现在很多竞赛虽然没有限定使用算法框架,但是更多获奖的队伍都使用到了深度学习算法,传统机器学习算法日渐式微。比如2022美国大学生数学建模C题,参数队伍使用到了深度学习网络的队伍,获奖比例都非常高,现在人工智能比赛和数据挖掘比赛都相继增多,对神经网络知识需求也日渐增多,因此十分有必要掌握各类神经网络算法。

博主专注建模四年,参与过大大小小数十来次数学建模,理解各类模型原理以及每种模型的建模流程和各类题目分析方法。此专栏的目的就是为了让零基础快速使用各类数学模型、机器学习和深度学习以及代码,每一篇文章都包含实战项目以及可运行代码。博主紧跟各类数模比赛,每场数模竞赛博主都会将最新的思路和代码写进此专栏以及详细思路和完全代码。希望有需求的小伙伴不要错过笔者精心打造的专栏。


输出层

神经网络在解决不同类型的问题时,使用不同的激活函数来适应任务的需求。对于分类问题和回归问题,我们选择了不同的策略来构建网络。

首先,让我们考虑分类问题。在分类问题中,我们常常面临将数据分成不同类别的挑战。对于二分类问题,这意味着我们需要将数据分为两个可能的类别。在这种情况下,我们选择使用 Sigmoid 函数作为输出层的激活函数。Sigmoid 函数能够将输出值映射到 0 到 1 之间,这使得我们可以将输出视为某个类别的概率。

而在处理多分类问题时,我们的目标是将数据分成多个可能的类别。这时,我们使用 Softmax 函数作为输出层的激活函数。Softmax 函数可以将每个类别的原始分数转换为表示各类别概率的形式。这使得我们能够确定哪个类别最有可能是给定输入的正确类别。

而在回归问题中,我们关心的是预测连续数值的输出,而不是离散的类别。在这种情况下,我们通常不使用激活函数,因为我们希望网络的输出可以取任意实数值,以便与问题的需求相匹配。

综上所述,神经网络在不同问题类型中的激活函数选择是根据问题的性质和目标而定的。通过选择适当的激活函数,我们能够更好地让网络适应不同类型的任务。

一、工作过程

为了方便理解,我们仍然以一个实际案例来进行,采用Softmax来进行多分类。

一个多分类问题,C=4.线性分类器模型最后的输出层包含了四个输出值,分别是:

V=\begin{pmatrix} -3\\ 2\\ -1\\ 0 \end{pmatrix}

经过Softmax处理后,数值转化为如下所示概率:

S=\begin{pmatrix} 0.0057\\ 0.8390\\ 0.0418\\ 0.1135 \end{pmatrix}

 很明显根据计算的概率我们很容易发现S2=0.8390对应的概率最大。Softmax将连续数值转化为相对概率,更利于我们理解。当然如果我们拿到的是[1000,1001,1002],我们会得到inf,如果是[-1000,-999,-1000]还是不行,也会得到-inf。

实际应用中,需要对V进行一些数值处理:即V中的每个元素减去V中的最大值。

def _softmax(x):
    c=np.max(x)
    exp_x = np.exp(x-c)
    return exp_x/np.sum(exp_x)

scores = np.array([123,456,789]) 
p = _softmax(scores)
print(p)

 以数值的形式计算可能有些抽象,那么我们以图片分类来举例:

假设我们把猫分为类1,狗为类2,小鸡为类3,如果不属于以上任何一类就分到“其他”,从左到右第一个图是一只小鸡,所以我们将它归为类3,以此类推:

假设我们输入一张猫的图片,其对应的真实标签是0100(类别已经转换成one-hot编码形式)。

真值y为\begin{pmatrix} 0\\ 1\\ 0\\ 0 \end{pmatrix}其中,y^{i=1}是1,其余的都是0,经过Softmax计算之后得到的是预测值y_predict,假设预测值为\begin{pmatrix} 0.3\\ 0.2\\ 0.1\\ 0.4 \end{pmatrix},它是一个包括总和为1的概率的向量,这样的话神经网络计算得到的结果告诉我们猫的概率值分配到20%。般来说,神经网络是将输出值最大的神经元所对应的类别作为识别结果,而且即使使用Softmax函数也只会改变值的大小而不能改变神经元的位置,另外指数函数的运算也需要一定的计算机运算量,因此可以考虑在多分类问题中省去Softmax函数。

二、输出层的神经元个数

输出层中神经元的数量应当根据解决问题的要求来选择。在处理不同问题时,输出层神经元的个数需要进行相应的设置。特别是在分类问题中,我们需要根据类别的数量来决定输出层的神经元数目。以 MNIST(手写数字识别)为例,这是一个将手写数字分为0到9共10个类别的问题,因此在输出层我们会设置10个神经元,每个神经元对应一个数字类别。

基于MNIST数据集的前向传播

MNIST(Modified National Institute of Standards and Technology)数据集是一个广泛应用于计算机视觉领域的经典数据集,用于手写数字识别任务。该数据集由美国国家标准与技术研究所(NIST)创建,并经过修改以便在机器学习研究中使用。

MNIST数据集包含了一系列的手写数字图像,涵盖了0到9的数字。每张图像的尺寸为28x28像素,以灰度图像的形式呈现。数据集共分为两部分:训练集和测试集。

训练集: 训练集包含了60,000张手写数字图像,每张图像都有对应的标签,指明该图像所表示的数字。这些图像和标签被广泛用于训练机器学习模型,特别是用于构建手写数字识别模型。

测试集: 测试集包含了10,000张手写数字图像,同样也带有对应的标签。这些图像用于评估已经训练好的模型在未见过数据上的性能。通过测试集的结果,可以了解模型的泛化能力和准确性。

通过torch直接下载即可:

#MNIST dataset
train_dataset = dsets.MNIST(root = '/ml/pymnist',  #选择数据的根目录
                            train = True,  #选择训练集
                            transform = None,  #不考#MNIST dataset
train_dataset = dsets.MNIST(root = '/ml/pymnist',  #选择数据的根目录
                            train = True,  #选择训练集
                            transform = None,  #不考虑使用任何数据预处理
                            download = True  #从网络上下载图片
                           )
test_dataset = dsets.MNIST(root = '/ml/pymnist',#选择数据的根目录
                           train = False,#选择测试集
                           transform = None, #不考虑使用任何数据预处理
                           download = True #从网络上下载图片
                          )虑使用任何数据预处理
                            download = True  #从网络上下载图片
                           )
test_dataset = dsets.MNIST(root = '/ml/pymnist',#选择数据的根目录
                           train = False,#选择测试集
                           transform = None, #不考虑使用任何数据预处理
                           download = True #从网络上下载图片
                          )

首先我们要初始化网络init_network函数,需要设置weight_scale变量用于控制随机权重,统一将bias设置为1.

def init_network():
    network={}
    weight_scale=1e-3
    network['W1']=np.random.randn(784,50)*weight_scale
    network['b1']=np.ones(50)
    network['W2']=np.random.randn(50,100)*weight_scale
    network['b2']=np.ones(100)
    network['W3']=np.random.randn(100,10)*weight_scale
    network['b3']=np.ones(10)
    return network

之后是进行前向传播过程,这里采用ReLU函数:

def _relu(x):
    return np.maximum(0,x)
def forward(network,x):
    w1,w2,w3 = network['W1'],network['W2'],network['W3']
    b1,b2,b3 = network['b1'],network['b2'],network['b3']
    a1 = x.dot(w1) + b1
    z1 = _relu(a1)
    a2 = z1.dot(w2) + b2
    z2 = _relu(a2)
    a3 = z2.dot(w3) + b3
    y = a3
    return y

最后我们计算得到最终结果:

network = init_network()
accuracy_cnt = 0
x = test_dataset.test_data.numpy().reshape(-1,28*28)
labels = test_dataset.test_labels.numpy() #tensor转numpy
for i in range((len(x))):
    y = forward(network,x[i])
    p = np.argmax(y) #获取概率最高的元素的索引
    if p == labels[i]:
        accuracy_cnt += 1
print("Accuracy:"+ str(float(accuracy_cnt)/len(x)*100)+'%')

 

 因为是初始权重,故10分类猜对的概率为10%正常不过,因为我们只是前向传播,没有反向传播,故所有的bias权重都不是最优的。那么下一章我们将为反向传播做好准备,详细讲述一下损失函数的作用,在我之前的文章基本把所有的损失函数都讲了一遍,十分详细完善,推荐大家有能力阅读一下:

损失函数(Loss Function)一文详解-分类问题常见损失函数Python代码实现+计算原理解析

下篇文章着重将讲述实际案例中损失函数的使用以及功能。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/949952.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flutter 混合开发调试

针对Flutter开发的同学来说,大部分的应用还是Native Flutter的混合开发,所以每次改完Flutter代码,运行整个项目无疑是很费时间的。所以Flutter官方也给我们提供了混合调试的方案【在混合开发模式下进行调试】,这里以Android Stud…

Python基础学习第四天:Python注释

创建注释 注释以 # 开头,Python 将忽略它们: 实例 #This is a comment print("Hello, World!")运行实例 注释可以放在一行的末尾,Python 将忽略该行的其余部分: 实例 print("Hello, World!")…

1-8 隐语小课|私有信息检索(PIR)及其应用场景

“隐语”是开源的可信隐私计算框架,内置 MPC、TEE、同态等多种密态计算虚拟设备供灵活选择,提供丰富的联邦学习算法和差分隐私机制 开源项目 github.com/secretflow gitee.com/secretflow 前言 欢迎来到小剧场全新系列节目「隐语小课」!本…

Run the Docker daemon as a non-root user (Rootless mode)

rootless 简介 rootless模式是指以非root用户身份运行Docker守护程序和容器。那么为什么要有rootless mode呢?因为在root用户下安装启动的容器存在安全问题。存在的安全问题具体来说是容器内的root用户就是宿主机的root用户,容器内uid1000的用户就是宿主…

csp认证真题——重复局面——Java题解

目录 题目背景 问题描述 输入格式 输出格式 样例输入 样例输出 样例说明 子任务 提示 【思路解析】 【代码实现】 题目背景 国际象棋在对局时,同一局面连续或间断出现3次或3次以上,可由任意一方提出和棋。 问题描述 国际象棋每一个局面可以…

vscode 清除全部的console.log

在放页面的大文件夹view上面右键点击在文件夹中查找 console.log.*$ 注意:要选择使用正则匹配 替换为 " " (空字符串)

多线程应用——单例模式

单例模式 文章目录 单例模式一.什么是单例模式二.如何实现1.口头实现2.利用语法特性 三.实现方式(饿汉式懒汉式)1.饿汉式2.懒汉式3.线程安全的单例模式4.双重检查锁5.禁止指令重排序 一.什么是单例模式 单例模式(Singleton Pattern&#xff…

数据集学习笔记(六):目标检测和图像分割标注软件介绍和使用,并转换成YOLO系列可使用的数据集格式

文章目录 一、目标检测1.1 labelImg1.2 介绍1.3 安装1.4 使用1.5 转换1.6 验证 二、图像分割2.1 labelme2.2 介绍2.3 安装2.4 使用2.5 转换2.6 验证 一、目标检测 1.1 labelImg 1.2 介绍 labelImg是一个开源的图像标注工具,用于创建图像标注数据集。它提供了一个…

2023-08-30 LeetCode每日一题(到家的最少跳跃次数)

2023-08-30每日一题 一、题目编号 1654. 到家的最少跳跃次数二、题目链接 点击跳转到题目位置 三、题目描述 有一只跳蚤的家在数轴上的位置 x 处。请你帮助它从位置 0 出发,到达它的家。 跳蚤跳跃的规则如下: 它可以 往前 跳恰好 a 个位置&#x…

OpenCVSharp入门学习①-获取本地摄像头数据

1. nuget包安装opencvsharp4和opencvsharp4.extensiongs和opencvsharp4.runtime.win 如果不安装opencvsharp4.runtime.win的话会报 System.TypeInitializationException:““OpenCvSharp.Internal.NativeMethods”的类型初始值设定项引发异常。”DllNotFoundException: 无法加…

vue v-for 例子

vue v-for 例子 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head&…

AssemblyManager 程序集管理器

AssemblyManager 程序集管理器 程序执行中使用反射对框架的搭建有着强大的影响&#xff0c;如何管理程序集方便使用反射获取类型操作对象是本文章的重点 1.AssemblyInfo 对于一个程序集这里使用一个AssemblyInfo对象进行管理 Assembly &#xff1a;对应的程序集AssemblyTyp…

Java多线程与并发编程

课程地址&#xff1a; https://www.itlaoqi.com/chapter.html?sid98&cid1425 源码文档&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1WMvM3j6qhyjIeAT87kIcxg 提取码&#xff1a;5g56 Java多线程与并发编程 1-并发背后的故事什么是并发 2-你必须知道线程的概念程…

Cadence网表导出常见错误

前言 好不容易绘制出来原理图&#xff0c;结果导出报了很多条错误&#xff0c;由于哥们还是小白&#xff0c;所以很多事情还不懂&#xff0c;有错误的地方希望大佬们能够指出&#xff0c;主要还是以我遇到的为主。 生成网表时候的常见错误 36002-封装名缺失 36003-多part器…

pdf怎么调整大小kb?一分钟学会pdf压缩

PDF是一种常见的文件格式&#xff0c;有时候我们需要将PDF文件的大小进行压缩&#xff0c;以便于传输或存储&#xff0c;那么怎么调整PDF文件的大小呢&#xff1f;接下来就给大家分享几个简单又实用的方法&#xff0c;帮助我们轻松解决PDF文件过大的问题。 方法一&#xff1a;嗨…

【高等数学重点题型篇】——一元函数微分学的应用

本文仅用于个人学习记录&#xff0c;使用的教材为汤家凤老师的《高等数学辅导讲义》。本文无任何盈利或者赚取个人声望的目的&#xff0c;如有侵权&#xff0c;请联系删除&#xff01; 文章目录 一、证明f ( n ) \ ^{(n)} (n)(ξ) 0二、待证结论中只有一个中值ξ&#xff0c;不…

【编译原理】课程一:编译原理入门

目录 1.为什么要学习编译原理 2.什么是编译原理 3.编译与计算机程序设计语言的关系 3.1.程序设计语言的转换方式 3.2.编译的转换过程 3.3.编译器在语言处理系统中的位置 3.4.编译系统的结构 3.4.1.词法分析(扫描) 3.4.2.语法分析(parsing) 3.4.1.1.语法分析的定义 3…

四轴飞行器的电池研究(MatlabSimulink仿真)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…