对神经网络基础的理解

目录

一、《python神经网络编程》

二、一些粗浅的认识

1) 神经网络也是一种拟合

2)神经网络不是真的大脑

3)网络构建需要反复迭代

三、数字图像识别的实现思路

1)建立一个神经网络类

 2)权重更新的具体实现

3)网络测试

四、总结


一、《python神经网络编程》

最近学习了一本书《python神经网络编程》,该书通过对一个数字识别案例的深入详细讲解,可以让读者对神经网络的思想有更加清晰的理解,明白计算机神经网络是如何工作的。在没有真正接触神经网络之前,总以为这是非常深奥的理论,也不明白神经网络是如何模拟人的大脑进行学习和判断的,难以理解计算机能够模拟人的大脑。《python神经网络编程》确实是一本很好的入门教材,它让读者能够真正踏入人工智能的门槛,奠定深入研究的基础。

二、一些粗浅的认识

1) 神经网络也是一种拟合

在数学中有很多拟合方法,比如线性拟合、多项式拟合等等。在这些拟合中,我们同样需要有确定的已知数据,然后通过这些拟合方法我们可以得到一个确定的数学解析表达式,并通过这个表达式来预测未知的结果。而神经网络的核心思想,我想也是一样的,只是这个实现过程相对复杂。我们最终能得到的是一个预测网络,也称模型,而不是一个精确的数学方程表达式。我们使用已知输入和输出的大量数据来训练神经网络,就是在让这个网络的输出结果逐渐逼近已知的输出结果。这个网络在训练的过程中,最终建立起了输入与输出之间的对应关系。但是这个对应关系我们无法用一个清晰的数学表达式来描述,可是我们可以使用这个网络来进行预测。正如对于图片中的数字而言,我们人看到图片中的数字就可以知道图中的数字是多少,因为在我们认识数字之前经过了学习,很多次有人告诉我们这个图形对应的数字就是这个数字。就像神经网络不能用一个准确的数学公式来描述输入与输出之间的关系一样,我们人类其实至今也还是不知道我们大脑学习的本质是什么。所以神经网络得到的拟合结果是一个黑盒子,我们针对特定的问题建立了一个黑盒子,然后训练了这个黑盒子,我们只知道给这个黑盒子一个输入,他能给出一个可信的结果。

2)神经网络不是真的大脑

神经网络只是借用了人类大脑神经元的形式。计算机神经网络是否真的能实现动物大脑的能力,我想还是难以断定。我们以前总是认为计算机的工作都是确定的,给它一个输入,我们必然能够准确预测它的输出结果。其实现在的神经网络也是一样的,虽然它是个黑盒子,但是给它相同的输入,它必然能够得到相同的结果,即使我们不知道它具体的计算逻辑,因为在这个网络中所有的参数经过训练后已经确定,计算机计算的每一步都是确定的。但计算机神经网络这种模糊拟合的实现,让我们认识到,当大量简单计算累计到一定数量时,在庞大的信息传递中是否就存在不可预测性。我们不理解自己为什么会思考,或许在不久的将来我们也无法确信庞大计算机系统的运行的真是我们人类设计的程序。

3)网络构建需要反复迭代

在构建神经网络过程中,输入与输出的节点数量需要根据实际问题进行分析。我们需要根据解决的实际问题,分析如何将问题的输入数字化,并设计相应的输入节点。而对于输出也是一样,我们需要分析如何用输出的数字信息来表达我们想要的结果形式,并设计相应的输出节点。我们常见的简单的神经网络通常是3层,包括输入、输出和中间的隐藏层,而隐藏层的层数以及每层的节点数该如何设计,这需要通过不断的尝试。较少的层数和节点数能够获得较高的计算效率,但是性能较低,误差较大,较多的层数和节点数能够获得较高的精度,但是计算效率低。因此,针对具体的问题需要综合考虑,反复迭代后确定网络构建形式。

三、数字图像识别的实现思路

1)建立一个神经网络类

《python神经网络编程》书中给出了一个实现数字识别的例子。在Python中首先定义一个3层神经网络类neuralNetwork。在类的初始化函数中确定网络的输入层节点数、隐藏层节点数、输出层节点数和学习率4个参数。并确定使用的激活函数。输入层与隐藏层、隐藏层和输出层之间的初始权重矩阵随机生成。

训练神经网络时,先根据训练数据的输入,正向逐层计算,最后得到网络的输出结果。然后计算网络输出结果与实际结果的误差值,然后再将误差进行反向传播,更新权重矩阵。这样,一组数据的训练就完成。

网络输出就是利用测试数据对网络进行一次正向输出的过程,最后根据输出数据给出网络的图像识别结果,具体实现后面再叙述。

class neuralNetwork:# 初始化函数def __int__(self, inputnodes, hiddennodes, outputnodes, learningrate):self.inodes = inputnodes  # 输入节点数self.hnodes = hiddennodes  # 隐藏节点数self.onodes = outputnodes  # 输出节点数self.wih = numpy.random.normal(0.0, pow(self.hnodes, -0.5), (self.hnodes, self.inodes))  # 随机生成初始的输入层到隐藏层的权重矩阵self.who = numpy.random.normal(0.0, pow(self.hnodes, -0.5), (self.onodes, self.hnodes))  # 随机生成初始的隐藏层到输出层的权重矩阵self.learn = learningrate   # 权重更新率self.active_function = lambda x: scipy.special.expit(x)  # 选择需要使用的激活函数pass# 定义训练函数def train(self, input_list, target_list):  # 提供已知的输入和输出结果inputs = numpy.array(input_list, ndmin=2).T  # 将输入转换为二维矩阵形式targets = numpy.array(target_list, ndmin=2).Thidden_inputs = numpy.dot(self.wih, inputs)  # 计算隐藏层的输入值,输入层到隐藏层的权重矩阵乘以输入hidden_outputs = self.active_function(hidden_inputs)  # 计算隐藏层的输出值,将隐藏层的输入值带入激活函数final_inputs = numpy.dot(self.who, hidden_outputs)  # 计算输出层的输入值,隐藏层到输出层的权重矩阵乘以隐藏层的输出值final_outputs = self.active_function(final_inputs)  # 计算输出层的输出结果,将输出层的输入值带入激活函数output_errors = targets - final_outputs  # 计算误差值,已知的输出结果-输出层的输出值hidden_errors = numpy.dot(self.who.T, output_errors)  # 传递误差# 更新权重矩阵self.who += self.learn * numpy.dot((output_errors * final_outputs * (1.0 - final_outputs)),numpy.transpose(hidden_outputs))self.wih += self.learn * numpy.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)),numpy.transpose(inputs))pass# 定义输出函数def query(self, input_list):inputs = numpy.array(input_list, ndmin=2).Thidden_inputs = numpy.dot(self.wih, inputs)hidden_outputs = self.active_function(hidden_inputs)final_inputs = numpy.dot(self.who, hidden_outputs)final_outputs = self.active_function(final_inputs)return final_outputs

 2)权重更新的具体实现

权重矩阵反复更新,就是神经网络不断学习,获得正确拟合结果的过程。权重更新根据严格的数学推导公式,程序实现过程不能直观反映具体的实现思想。它的核心就是利用每次训练的计算误差来修正权重矩阵。

(1)误差计算

在训练神经网络过程中计算误差时,程序中我们直接将实际结果与计算结果相减(output_errors = targets - final_outputs),得到一个误差向量。但是理论分析时,直接相减计算误差的方法并不合适,我们通常使用差的平方来表示,所有节点的总误差如下:

error=\sum_{n}^{} \left (t_{n} -o_{n}\right )^{2}

 (2)误差传递

我们可以直接计算出输出层的误差,但是最终的误差是由前面的计算逐层、逐节点计算累计得到的,该如何将最终的误差反向分配到每个节点上呢?通常我们认为节点之间连接权重越大的链路,计算引入的误差也越大,因此,我们也同样通过权重来分配误差。针对本例而言,我们已经得到了输出层的误差,还需要计算隐藏层的误差。输入层不需要计算,因为默认输入层输入与输出是相同的,不需要使用激活函数。那么隐藏层的输出误差计算如下:

error_{hidden}=\bigl(\begin{smallmatrix} W_{1,1} & W_{1,2}& W_{1,3}\\ W_{2,1}& W_{2,2}& W_{2,3}\\ W_{3,1}& W_{2,3}& W_{3,3} \end{smallmatrix}\bigr)\bullet \begin{pmatrix} e_{1}\\ e_{2}\\ e_{3}\end{pmatrix}

此处需要注意的是,误差反向传播计算的矩阵正好是正向计算时隐藏层到输出层权重矩阵的转置,至于为什么是转置,我们手动简单计算一下就知道了。同时需要注意的是,通过上式计算得到的总误差并不是输出层的总误差(\sum e_{n}) 。因为,更新权重矩阵时,我们其实并不关心过程中的误差大小,而是更关心是哪个链路导致的误差更大,只要能体现出各链路误差的相对大小就可以。

(3)更新权重

在此例中使用跟新权重的方法是梯度下降法,这也是使用非常广泛的一种方法。我们需要建立起权重与误差之间的关系。我们以最后的输出层为例,输出层的输入是隐藏层的输出乘以隐藏层和输出层之间的权重矩阵:

In_{final}=W\bullet O_{hidden}

将此结果代入激活函数,则输出层的结果为:

O_{final}=sigmoid(In_{final})

sigmoid函数为激活函数,形式为:

s = \frac{1}{1+e^{-x}}

则每个节点的输出误差为:

error=\left ( t -o\right )^{2} 

将上述公式联合,然后对权重w求导,就可以得到误差相对于权重的导数(斜率):

\frac{\partial E}{\partial w}=-2\left ( t-o \right )\bullet o\bullet (1-o)\bullet o_{hidden}

权重更新公式为:

W_{new}=W_{old}-\alpha \frac{\partial E}{\partial w}

上述公式中,我们实际使用时并不关心常系数2,因此在代码实现时省略了。

3)网络测试

网络测试的具体实现可参见代码。

# 测试网络
scorecard = []
i = 0
for record in test_data_list:i += 1if(i != 10):  # 可调整数字,逐张识别continuepassall_values = record.split(',')correct_label = int(all_values[0])inputs = (numpy.asarray(all_values[1:], numpy.float32) / 255.0 * 0.99) + 0.01image_array = numpy.asarray(all_values[1:], numpy.int32).reshape((28, 28))fig = matplotlib.pyplot.figure(figsize=(5, 5))matplotlib.pyplot.imshow(image_array, cmap='Greys', interpolation='None')matplotlib.pyplot.show()outputs = n.query(inputs)  # 网络识别的结果label = numpy.argmax(outputs)  # 输出结果中的最大值print("输入数字:", all_values[0], "识别结果:", label)  # 打印出实际值if(label == correct_label):scorecard.append(1)else:scorecard.append(0)passpassscorecard_array = numpy.asarray(scorecard)
print("performance = ", scorecard_array.sum() / scorecard_array.size)

四、总结

《python神经网络编程》与书中的示例简明阐述了神经网络的核心思想和基本架构,任何复杂的神经网络均可基于此构建。我们可以通过使用不同的网络层数、节点数、激活函数以及链路连接方式等,构建不同的适用于各种应用的神经网络模型。或许正式因为神经网络内部的不可描述性,对网络结构的各种优化,为研究神经网络开辟了广阔空间。

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

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

相关文章

新项目传到git步骤

1.首先创建远程仓库,创建一个空白项目,即可生成一个克隆URL,可以是http也可以是SSH,copy下这个地址 2.找到项目的本机目录,进入根目录,打开git bash here命令行 3.初始化: git init 4.关联远程地址: git remote add origin "远程仓库的URL" 5.查看关联 git re…

PAT甲级-1024 Palindromic Number

题目 题目大意 一个非回文数,加上它的翻转数所得的和,进行k次,有可能会得到一个回文数。给出一个数n,限制相加次数为k次,如果小于k次就得到回文数,那么输出该回文数和相加的次数;如果进行k次还…

appium自动化环境搭建

一、appium介绍 appium介绍 appium是一个开源工具、支持跨平台、用于自动化ios、安卓手机和windows桌面平台上面的原生、移动web和混合应用,支持多种编程语言(python,java,Ruby,Javascript、PHP等) 原生应用和混合应用&#xf…

C#高级:常用的扩展方法大全

1.String public static class StringExtensions {/// <summary>/// 字符串转List&#xff08;中逗 英逗分隔&#xff09;/// </summary>public static List<string> SplitCommaToList(this string data){if (string.IsNullOrEmpty(data)){return new List&…

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.1 从零搭建NumPy环境:安装指南与初体验

1. 从零搭建NumPy环境&#xff1a;安装指南与初体验 NumPy核心能力图解&#xff08;架构图&#xff09; NumPy 是 Python 中用于科学计算的核心库&#xff0c;它提供了高效的多维数组对象以及用于处理这些数组的各种操作。NumPy 的核心能力可以概括为以下几个方面&#xff1a…

【SpringBoot教程】Spring Boot + MySQL + HikariCP 连接池整合教程

&#x1f64b;大家好&#xff01;我是毛毛张! &#x1f308;个人首页&#xff1a; 神马都会亿点点的毛毛张 在前面一篇文章中毛毛张介绍了SpringBoot中数据源与数据库连接池相关概念&#xff0c;今天毛毛张要分享的是关于SpringBoot整合HicariCP连接池相关知识点以及底层源码…

Java进阶(一)

目录 一.Java注解 什么是注解&#xff1f; 内置注解 元注解 二.对象克隆 什么是对象克隆? 为什么用到对象克隆 三.浅克隆深克隆 一.Java注解 什么是注解&#xff1f; java中注解(Annotation)又称java标注&#xff0c;是一种特殊的注释。 可以添加在包&#xff0c;类&…

【PyCharm】将包含多个参数的 shell 脚本配置到执行文件来调试 Python 程序

要配置 PyCharm 以使用包含多个参数的 shell 脚本&#xff08;如 run.sh&#xff09;来调试 Python 程序&#xff0c;您可以按照以下步骤操作&#xff1a; 创建一个新的运行/调试配置&#xff1a; 在 PyCharm 中&#xff0c;点击“运行”菜单旁边的齿轮图标&#xff0c;选择“…

即梦(Dreamina)技术浅析(二):后端AI服务

1. 文本处理(Text Processing) 1.1 功能概述 文本处理模块的主要任务是将用户输入的文字提示词转换为机器可以理解的向量表示。这一过程包括分词、词嵌入和语义编码,旨在捕捉文本的语义信息,为后续的图像和视频生成提供准确的指导。 1.2 关键技术 1.分词(Tokenization…

蓝桥杯之c++入门(一)【第一个c++程序】

目录 前言一、第⼀个C程序1.1 基础程序1.2 main函数1.3 字符串1.4 头文件1.5 cin 和 cout 初识1.6 名字空间1.7 注释 二、四道简单习题&#xff08;点击跳转链接&#xff09;练习1&#xff1a;Hello,World!练习2&#xff1a;打印飞机练习3&#xff1a;第⼆个整数练习4&#xff…

【C++初阶】第11课—vector

文章目录 1. 认识vector2. vector的遍历3. vector的构造4. vector常用的接口5. vector的容量6. vector的元素访问7. vector的修改8. vector<vector\<int\>>的使用9. vector的使用10. 模拟实现vector11. 迭代器失效11.1 insert插入数据内部迭代器失效11.2 insert插入…

【AIGC学习笔记】扣子平台——精选有趣应用,探索无限可能

背景介绍&#xff1a; 由于近期业务发展的需求&#xff0c;我开始接触并深入了解了扣子平台的相关知识&#xff0c;并且通过官方教程自学了简易PE工作流搭建的技巧。恰逢周会需要准备与工作相关的分享主题&#xff0c;而我作为一个扣子平台的初学者&#xff0c;也想探索一下这…

mysql 学习6 DML语句,对数据库中的表进行 增 删 改 操作

添加数据 我们对 testdatabase 数据中 的 qqemp 这张表进行 增加数据&#xff0c;在这张表 下 打开 命令行 query console 在 软件中就是打开命令行的意思 可以先执行 desc qqemp; 查看一下当前表的结构。 插入一条数据 到qqemp 表&#xff0c;插入时要每个字段都有值 insert…

Java Web-Request与Response

在 Java Web 开发中&#xff0c;Request 和 Response 是两个非常重要的对象&#xff0c;用于在客户端和服务器之间进行请求和响应的处理&#xff0c;以下是详细介绍&#xff1a; Request&#xff08;请求对象&#xff09; Request继承体系 在 Java Web 开发中&#xff0c;通…

李沐vscode配置+github管理+FFmpeg视频搬运+百度API添加翻译字幕

终端输入nvidia-smi查看cuda版本 我的是12.5&#xff0c;在网上没有找到12.5的torch&#xff0c;就安装12.1的。torch&#xff0c;torchvision&#xff0c;torchaudio版本以及python版本要对应 参考&#xff1a;https://blog.csdn.net/FengHanI/article/details/135116114 创…

论文阅读(十六):利用线性链条件随机场模型检测阵列比较基因组杂交数据的拷贝数变异

1.论文链接&#xff1a;Detection of Copy Number Variations from Array Comparative Genomic Hybridization Data Using Linear-chain Conditional Random Field Models 摘要&#xff1a; 拷贝数变异&#xff08;CNV&#xff09;约占人类基因组的12%。除了CNVs在癌症发展中的…

Alibaba Spring Cloud 十三 Nacos,Gateway,Nginx 部署架构与负载均衡方案

在微服务体系中&#xff0c;Nacos 主要承担“服务注册与发现、配置中心”的职能&#xff0c;Gateway&#xff08;如 Spring Cloud Gateway&#xff09;通常负责“路由转发、过滤、安全鉴权、灰度流量控制”等功能&#xff0c;而 Nginx 则常被用作“边缘反向代理”或“统一流量入…

Next.js 实战 (十):中间件的魅力,打造更快更安全的应用

什么是中间件&#xff1f; 在 Next.js 中&#xff0c;中间件&#xff08;Middleware&#xff09;是一种用于处理每个传入请求的功能。它允许你在请求到达页面之前对其进行修改或响应。 通过中间件&#xff0c;你可以实现诸如日志记录、身份验证、重定向、CORS配置、压缩等任务…

ElasticSearch-文档元数据乐观并发控制

文章目录 什么是文档&#xff1f;文档元数据文档的部分更新Update 乐观并发控制 最近日常工作开发过程中使用到了 ES&#xff0c;最近在检索资料的时候翻阅到了 ES 的官方文档&#xff0c;里面对 ES 的基础与案例进行了通俗易懂的解释&#xff0c;读下来也有不少收获&#xff0…

实验二 数据库的附加/分离、导入/导出与备份/还原

实验二 数据库的附加/分离、导入/导出与备份/还原 一、实验目的 1、理解备份的基本概念&#xff0c;掌握各种备份数据库的方法。 2、掌握如何从备份中还原数据库。 3、掌握数据库中各种数据的导入/导出。 4、掌握数据库的附加与分离&#xff0c;理解数据库的附加与分离的作用。…