政安晨:【深度学习神经网络基础】(六)—— 前馈神经网络

目录

简述

前馈神经网络结构

计算输出

初始化权重

径向基函数神经网络

径向基函数


政安晨的个人主页政安晨

欢迎 👍点赞✍评论⭐收藏

收录专栏政安晨的机器学习笔记

希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正!

简述

由于其用途广泛,前馈神经网络架构非常受欢迎。因此,我们将探索如何训练它,以及它如何处理模式。

“前馈”一词描述了该神经网络如何处理和记忆模式。在前馈神经网络中,神经网络的每一层都包含到下一层的连接。如这些连接从输入向前延伸到隐藏层,但是没有向后的连接。后面,我们也将分析前馈神经网络的结构及其记忆模式的方式。

我们可以使用多种反向传播算法中的各种技术来训练前馈神经网络,这是一种有监督的训练形式。本文重点介绍应用优化算法来训练神经网络的权重。尽管可以用几种优化算法来训练权重,但我们主要将注意力集中在模拟退火上。

优化算法会调整一个数字向量,旨在根据一个目标函数获得良好的得分。目标函数基于该神经网络的输出与预期输出的匹配程度,为神经网络提供得分。该得分允许用任何优化算法来训练神经网络。

优化算法会调整一个数字向量,旨在根据一个目标函数获得良好的得分。目标函数基于该神经网络的输出与预期输出的匹配程度,为神经网络提供得分。该得分允许用任何优化算法来训练神经网络。

前馈神经网络类似于我们已经探讨过的神经网络。其从一个输入层开始,可能连接到隐藏层或输出层。如果连接到隐藏层,则该隐藏层可以随后连接到另一个隐藏层或输出层。隐藏层可以有任意多层。

前馈神经网络结构

我们讨论了神经网络可以具有多个隐藏层,并分析了这些层的用途。我们将从输出层的结构开始,聚焦于输入神经元和输出神经元的结构。问题的类型决定了输出层的结构。分类神经网络将为每个类别提供一个输出神经元,而回归神经网络将只有一个输出神经元。

用于回归的单输出神经网络

管前馈神经网络可以具有多个输出神经元,但我们将从回归问题中的单输出神经网络开始。用于回归的单输出神经网络能够预测单个数值。

下图展示了一个单输出前馈神经网络。

单输出前馈神经网络

这个神经网络将输出一个数值。我们可以通过以下方式使用这种类型的神经网络。

● 回归:根据输入计算数值(如特定类型的汽车每加仑可行驶多少英里)。

● 二元分类:根据输入确定两个选项(如在给定的特征下,哪个是恶性肿瘤)。

我们在本文中提供了一个回归示例,该示例利用有关各种汽车模型的数据,预测汽车的MPG。

有关各种汽车模型的数据来自于汽车MPG数据集,这个数据集的一小部分示例如下:

mpg,cylinders,displacement,horsepower,weight,acceleration,model_year,origin,car_name
18,8,307,130,3504,12,70,1,"chevrolet chevelle malibu"
15,8,350,165,3693,11,70,1,"buick skylark 320"
18,8,318,150,3436,11,70,1,"plymouth satellite"
16,8,304,150,3433,12,70,1,"amc rebel sst"

对于回归问题,神经网络将创建气缸数、排量、马力和车重等列来预测MPG。

这些值是上面数据集示例中使用的所有字段,用于指定每辆汽车的特征。

在这个例子中,目标是预测MPG。但是,我们也可以利用MPG、汽缸数、马力、车重和加速等来预测排量。

为了用神经网络对多个值执行回归,可以使用多个输出神经元。

如气缸、排量和马力可以预测MPG和车重。尽管多输出神经网络可以对两个变量进行回归,但我们不建议使用此技术。对于要预测的每个回归结果,通常使用单独的神经网络可以获得更好的结果。

计算输出

单个神经元的输出就是其输入和偏置的加权和。

该和被传递给一个激活函数。下面公式总结了神经网络的计算输出:

神经元将输入向量(x)乘以权重(w),然后将结果传递给一个激活函数(φ)。偏置是权重向量(w)中的最后一个值,添加偏置的方法是将值1.0连接到输入之后。如考虑具有两个输入和一个偏置的神经元,如果输入为0.1和0.2,则输入向量如下所示:

[0.1, 0.2, 1.0]

在这个示例中,添加值1.0以支持偏置权重。

我们也可以用以下权重向量来计算该值

[0.01, 0.02, 0.3]

值0.01和0.02是神经元两个输入的权重,值0.3是偏置的权重。计算加权和:

(0.1 * 0.01) + (0.2 * 0.02) + (1.0 * 0.3)

然后将计算结果0.305传递给激活函数。

计算整个神经网络的输出本质上是对神经网络中的每个神经元都执行这个相同的过程。这个过程使你可以从输入神经元一直计算到输出神经元。你可以为神经网络中的每个连接创建对象,或将这些连接值安排到矩阵中,从而实现这个过程。

面向对象的编程让你可以为每个神经元及其权重定义一个对象。

这种方法能产生可读性强的代码,但是它有两个重要的问题:

● 权重存储在许多对象中;

● 性能受影响,因为需要许多函数调用和内存访问才能将所有权重加在一起。

在神经网络中,将权重作为单个向量创建很有价值。各种不同的优化算法可以调整一个向量,让得分函数产生最优的结果。在后文,我们将看到模拟退火如何优化神经网络的权重向量。

为了创建一个权重向量,我们首先来看一个具有以下特征的神经网络。

● 输入层:2个神经元,1个偏置。

● 隐藏层:2个神经元,1个偏置。

● 输出层:1个神经元。

这些特征使得该神经网络共有7个神经元。

为了创建该向量,可以用以下方式对这些神经元编号:

Neuron 0: Output 1

Neuron 1: Hidden 1

Neuron 2: Hidden 2

Neuron 3: Bias 2 (set to 1, usually)

Neuron 4: Input 1

Neuron 5: Input 2

Neuron 6: Bias 1 (set to 1, usually)

用图形方式表示该简单神经网络,如下图所示:

简单神经网络

你可以创建几个其他向量来定义神经网络的结构。

这些向量保存索引值,以便快速访问权重向量。这些向量在这里列出:

layerFeedCounts: [1, 2, 2]
layerCounts: [1, 3, 3]
layerIndex: [0, 1, 4]
layerOutput: [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0]
weightIndex: [0, 3, 9]

每个向量中保存值的顺序是首先输出层,然后向上直到输入层。

layerFeedCounts向量保存每一层中非偏置神经元的计数。

该特征实际上是非偏置神经元的数量。

layerOutput向量保存每个神经元的当前值。

最初,所有神经元都从0.0开始,除了偏置神经元从1.0开始。

layerIndex向量保存每个层在layerOuput向量中的起始位置的索引。

weightIndex保存指向权重向量中每一层位置的索引。

权重存储在它们自己的向量中,其结构如下:

Weight 0 : H1−>01

Weight 1 : H2−>01

Weight 2 : B2−>01

Weight 3 : I1−>H1

Weight 4 : I2−>H1

Weight 5 : B1−>H1

Weight 6 : I1−>H2

Weight 7 : I2−>H2

Weight 8 : B1−>H2

一旦安排好向量,计算神经网络的输出就相对容易了。

如下代码可以完成这种计算。

计算前馈输出

def compute(net, input):sourceIndex = len(net.layerOutput)- net.layerCounts[len(net.layerCounts) - 1]# Copy the input into the layerOutput vectorarray_copy(input, 0, net.layerOutput, sourceIndex, net.inputCount)# Calculate each layerfor i in reversed(range(0,len(layerIndex))):compute_layer(i)# update context valuesoffset = net.contextTargetOffset[0]# Create resultresult = vector(net.outputCount)array_copy(net.layerOutput, 0, result, 0, net.outputCount)return resultdef compute_layer(net,currentLayer):inputIndex = net.layerIndex[currentLayer]outputIndex = net.layerIndex[currentLayer - 1]inputSize = net.layerCounts[currentLayer]outputSize = net.layerFeedCounts[currentLayer - 1]index = this.weightIndex[currentLayer - 1]limit_x = outputIndex + outputSizelimit_y = inputIndex + inputSize# weight valuesfor x in range(outputIndex,limit_x):sum = 0;for y in range(inputIndex,limit_y):sum += net.weights[index] * net.layerOutput[y]net.layerSums[x] = sumnet.layerOutput[x] = sumindex = index + 1net.activationFunctions[currentLayer - 1].activation_function(net.layerOutput, outputIndex, outputSize)

初始化权重

神经网络的权重决定了神经网络的输出。训练过程可以调整这些权重,使得神经网络产生有用的输出。大多数神经网络训练算法开始都将权重初始化为随机值。然后,训练通过一系列迭代进行,这些迭代不断改进权重,以产生更好的输出。

神经网络的随机权重会影响神经网络的训练水平。

如果神经网络无法训练,你可以通过重新设置一组新的随机权重来解决问题。

但是,当你尝试不同的神经网络的架构,并尝试不同的隐藏层和神经元组合时,这个解决方案可能会令人沮丧。

如果添加新层后,神经网络性能得到改善,你就必须考虑,这种改进是由新层产生的,还是由一组新的权重产生的。

由于存在这种不确定性,我们在权重初始化算法中关注两个关键属性。

● 该算法提供良好权重的一致性如何?

● 该算法提供的权重有多少优势?

权重初始化最常见(但最无效)的方法之一,是将权重设置为特定范围内的随机值,通常选择−1~+1或−5~+5的数字。如果要确保每次都获得相同的随机权重集,则应使用种子。种子指定了要使用的一组预定义随机权重。如种子为1 000,可能会产生0.5、0.75和0.2的随机权重。这些值仍然是随机出现的,你无法预测,但是当你选择1 000作为种子时,总是会获得这些值。

并非所有种子都是生而平等的。随机权重初始化有一个问题,即某些种子创建的随机权重比其他种子更难训练。实际上,权重可能非常糟糕,而无法进行训练。如果发现无法使用特定的权重集训练神经网络,则应使用其他种子生成一组新的权重。

由于权重初始化存在的问题,人们围绕它进行了大量研究。多年来,我们已经考察了这方面的研究,并在Encog项目中添加了6个不同的权重初始化例程。根据我们的研究,由Glorot和Bengio于2006年引入的Xavier权重初始化算法可以产生具有合理一致性的良好权重。这种相对简单的算法使用正态分布的随机数。

要使用Xavier权重初始化,必须了解正态分布的随机数不是大多数编程语言生成的0~1的典型随机数。

实际上,正态分布的随机数以均值μ(mu)为中心,它通常为0。如果以0为中心(均值),那么你将获得数量相等的大于0和小于0的随机数。

下一个问题是这些随机数将从0偏离到多远。

理论上,你可能得到正随机数和负随机数都接近计算机支持的最大正数和负数范围。

但现实情况是,你很可能会看到一些随机数,它们与中心的偏差为0~3个标准差。

标准差σ(sigma)参数指定这个标准差的大小。如果你将标准差指定为10,那么你主要会看到−30~+30的随机数,较接近0的数字具有更高的选择概率。

下图展示了正态分布。(正态分布

上图展示了中心(在这个例子中为0)将以0.4(40%)的概率生成。另外,在−2或+2个标准差之外,概率降低得非常快。通过定义中心和标准差的大小,你可以控制生成的随机数的范围。

大多数编程语言都具有生成正态分布的随机数的能力。通常,Box-Muller算法是这种能力的基础。本书中的示例将使用内置的正态随机数发生器,或用Box-Muller算法将规则的、均匀分布的随机数转换为正态分布。

Xavier权重初始化将所有权重设置为正态分布的随机数,这些权重总是以0为中心。它们的标准差取决于当前权重层存在多少个连接。具体来说,下面公式可以确定方差:

上面公式展示了如何获得所有权重的方差。方差的平方根是标准差。大多数随机数生成器接受标准差,而不是方差。因此,你通常需要取如上公式的平方根。

下图展示了一层的Xavier初始化过程。

神经网络中的每一层,都要完成这个过程。

径向基函数神经网络

径向基函数(Radial-Basis Function,RBF)神经网络是Broomhead和Lowe(1988)引入的一种前馈神经网络。该神经网络可用于分类和回归。

尽管它们可以解决各种问题,但RBF神经网络的受欢迎程度似乎正在降低。根据其定义,RBF神经网络不能与深度学习结合使用。

RBF神经网络利用一个参数向量(一个指定权重和系数的模型),来允许输入生成正确的输出。通过调整一个随机参数向量,RBF神经网络可产生与鸢尾花数据集一致的输出。

调整该参数向量以产生所需输出的过程称为训练。

训练RBF神经网络有许多不同的方法。

参数向量也代表了RBF神经网络的长期记忆。

我们将简要回顾RBF,并描述这些向量的确切组成。

径向基函数

由于许多AI算法都利用了径向基函数,因此它们是一个非常重要的概念。RBF相对其中心对称,该中心通常在[插图]轴上。RBF将在中心达到其最大值,即峰值。RBF神经网络中典型的峰值通常设置为1,中心会相应地变化。

RBF可以有许多维度。无论传递给RBF的向量维度是多少,它的输出总是单个标量值。

RBF在AI中很常见。我们将从最流行的高斯函数开始讲解。下图展示了以0为中心的一维高斯函数的图像。

你可能认为上述曲线是正态分布或钟形曲线,而这其实是一个RBF。RBF(如高斯函数)可以有选择地缩放数值。请考虑下图所示函数,如果你用这个函数缩放一些数值,那么结果将在中心具有最大强度。从中心向两侧移动时,强度会沿正向或负向减小。


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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Centos7源码方式安装Elasticsearch 7.10.2单机版

版本选择参考:Elasticsearch如何选择版本-CSDN博客 下载 任选一种方式下载 官网7.10.2版本下载地址: https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.10.2-linux-x86_64.tar.gz 网盘下载链接 链接:https://pan…

OpenGL Assimp 加载3D模型介绍

OpenGL Assimp 加载3D模型介绍 Assimp对应模型结构体解说 所有的模型、场景数据都包含在scene对象中,如所有的材质和Mesh。同样,场景的根节点引用也包含在这个scene对象中 场景的Root node(根节点)可能也会包含很多子节点和一个…

c++的学习之路:16、list(3)

上章有一些东西当时没学到,这里学到了将在补充,文章末附上代码,思维导图。 目录 一、赋值重载 二、带模板的创建 三、析构函数 四、代码 五、思维导图 一、赋值重载 这里的赋值重载就是直接利用交换函数进行把传参生成的临时数据和需要…

对称加密学习

对称加密是一种加密技术,它使用相同的密钥进行数据的加密和解密操作。这种加密方法因其高效性和速度优势,在数据加密领域得到了广泛的应用。 下面是两篇文章: AES加密学习-CSDN博客 加密算法学习-CSDN博客 推荐关注加密专栏: …

建模实例评点(6)业务流程-农业大棚

1 00:00:02,650 --> 00:00:06,000 假设这一步不是老司机来做 2 00:00:06,320 --> 00:00:08,430 主管不是老司机,是个小白 3 00:00:08,440 --> 00:00:09,470 比如像我这样 4 00:00:09,990 --> 00:00:11,580 潘加宇去做这个事情 5 00:00:12,460 -->…

C++感受4-HelloWorld中文版——认识编码

及时了解“编码”对编写代码的影响,是中国程序员越早知道越好的知识点。 一分钟了解什么叫“编码”和“解码”;通过实际演示,充分理解中文Windows下,C源代码编码需要注意的地方;通过 -finput-charsetutf8 等 g 编译配置…

如何训练自己的ChatGPT?需要多少训练数据?

近年,聊天机器人已经是很常见的AI技术。小度、siri、以及越来越广泛的机器人客服,都是聊天机器人的重要适用领域。然而今年,ChatGPT的面世让这一切都进行到一个全新的高度,也掀起了大语言模型(LLM)的热潮。…

麒麟系统ARM安装rabbitmq

简单记录下,信创服务器:麒麟系统,安装rabbitmq的踩坑记录。 本文章参考了很多大佬文章,我整理后提供。 一、安装基础依赖 yum -y install make gcc gcc-c kernel-devel m4 ncurses-devel openssl-devel unixODBC-devel 二、下载…

实现自动打包py及替换pyinstaller --add-data参数的方法

2024年了,PyInstaller已经来到了6.5.0版本,可我还是不会用它那个--add-data的方法,度了几圈试了试,始终不(行)如(不)意(通),就是没能把附加文件&a…

【nodejs基础学习三-浏览器偏好设置】

系列文章目录 第一章 nodejs基础学习–注释、变量、运算符、字符串、函数(一) 第二章 nodejs基础学习–循环、对象字符、模块导入出(二) 第三章 nodejs基础学习三-浏览器设置 系列文章目录一、开发者模式二、web偏好设置 一、开发…

2021年团体程序设计天梯赛-总决赛_L1

标题:L1-1 人与神 题目: 跨界大神 L. Peter Deutsch 有一句名言:“To iterate is human, to recurse divine.”(迭代的是人,递归的是神)。本题就请你直接在屏幕上输出这句话。 输入格式: 本题没…

Linux之线程互斥与同步

1.线程互斥相关概念 临界资源:多线程执行流共享的资源就叫做临界资源 。 临界区:每个线程内部,访问临界自娱的代码,就叫做临界区。 互斥:任何时刻,互斥保证有且只有一个执行流进入临界区,访问临…

后端nginx使用set_real_ip_from获取用户真实IP

随着nginx的迅速崛起,越来越多公司将apache更换成nginx. 同时也越来越多人使用nginx作为负载均衡, 并且代理前面可能还加上了CDN加速,但是随之也遇到一个问题:nginx如何获取用户的真实IP地址. 前言:Nginx ngx_http_realip_module…

MapMagic 2 Splines (Beta)

请注意,要使用该模块则必须安装带对象模块的 MapMagic 2 才行。此模块目前正处于早期体验阶段。其功能有限。 MapMagic 2 世界生成器的官方模块。把样条线带到 MapMagic 中,可用于创建道路、溪流、河流或其他加长的对象。 下载:​​Unity资…

c 语言 斐波那契搜索(Fibonacci Search)

给定一个大小为 n 的排序数组 arr[] 和要在其中搜索的元素 x。如果 x 存在于数组中,则返回 x 的索引,否则返回 -1。 例子: 输入: arr[] {2, 3, 4, 10, 40}, x 10输出: 3 元素 x 出现在索引 3 处。 输入&#xff1…

数据结构-合并两个有效数组

题目描述 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。 注意:最终,…

意得辑意得辑

你是否也曾遇到过在发表论文时英语写作水平不尽如人意的困境?审稿意见总是指出语言表达不够好,需要找英语母语者修改?不用担心,我和你一样,也曾历经这样的挑战。但是,我找到了一家值得信赖的专业润色机构—…

Apache Incubator Answer 本地开发部署

文章目录 简介Github文档插件部署 Answer开发环境编译项目初始化项目运行项目 简介 一款适合任何团队的问答平台软件。 Apache Incubator Answer是一个开源项目,它是一个用于构建和部署问答系统的框架。该项目是Apache软件基金会的孵化器项目,提供一个…

Lobe UI - 基于 AntDesign 开发的 AIGC Web 应用的开源 UI 组件库

今天推荐一个可以快速开发 ChatGPT UI 界面的组件库,质量很高,拿来就能用。 Lobe UI 是由 lobehub 团队开发的一套 web UI 组件库,和我之前推荐的很多通用型的 UI 组件库不同,Lobe UI 是专门为目前火热的 AIGC 应用开发而打造&am…