Python神经网络学习--神经网络知识先导(一)--什么是神经网络?
本文介绍了神经网络的基本概念,将神经元比作简单的函数,并通过温度转换的例子解释了神经元如何组合成神经网络。文章还讨论了神经网络的分类,并通过调整参数的学习过程展示了如何通过迭代优化实现更好的结果。核心思想是通过简单的函数和参数调整,逐步逼近真实结果,体现了神经网络的核心思想。
前言
长时间处于沉寂状态之后,原本计划撰写一份基于Go语言的无框架建站教程,然而经过反思,发现过去一年中我对Go语言的关注度较低,这导致Go语言的工程模式确实出现了新的变化。随后,经过与导师的交流,了解到其要求我深入学习神经网络相关知识,因此,我决定先将Go语言建站的相关日程往后调整,以便先集中精力学习神经网络知识。
一如既往,我的目标仍然是让你看了之后就能和别人讲。
今天是个好机会,我们来学习一下神经网络的基本概念吧。对了,前几篇可能涉及较多的理论知识,等到后面再进行实际操作。
什么是神经网络?
这里不会对这一概念进行解释,让我们一步一步去理解这个神秘的东西。
神经元是该函数的组成部分吗?
生物中的神经元
作为读者,高中阶段的知识涉及生物学科的基础内容。生物大脑中存在神经元结构,草图展示了一个神经元的结构示意图。

左侧接收其他神经元传递来的信号,经过处理后,若需要做出反应,末梢将释放神经递质,以传递信号到下一个神经细胞。尽管上述解释可能不够精确,但大致能理解该神经细胞的作用。
简单来说,一个神经元有三个基本的功能:‘
1. 接收刺激或者信号
2. 处理这些信息
3. 根据信号做出相应反应
程序语言中的函数
在程序设计中,我们经常遇到各种各样的操作,包括函数(function)、方法(method)以及其他的途径,为了简化表述,我们可以暂且将它们统称为函数。比如,一个简单的最大值函数:
# 返回num1和num2的最大值
def Max(num1, num2):
if num1 > num2:
num2 = num1
return num2
可以看到
1. 这个函数接收了两个参数:num1和num2
2. 比较了num1和num2的大小
3. 返回了最大值
神经元!函数!
现在,不难理解,其实,一个神经元可以简单地认为是一个简单的函数。这个神经元(函数)接收输入信号(参数),经过信息处理后,产生输出(返回值)。多么简单,现在,我们编程时就不用说写一个功能函数了,而可以说,来吧,编写一个计算最大值和最小值的神经元吧。
神经元+神经元 = 神经网络
高中生物课本指出,多个神经元共同构成神经网络。人体内约有数十亿个神经元。即使是简单的蚂蚁,其体内也拥有几十万个神经元。数量如此之多的神经元彼此连接,形成了一种令人惊叹的协作机制,这种机制赋予了生物体智能。这个网络系统,通常被称为神经网络。
所以,神经元(函数)+神经元(函数) = 神经网络(人工神经网络)。
该表述虽然不够精确,但也具有一定的局限性,但同时也能够帮助理解编程语言在构建神经网络时的工作原理。实际上,我们需要将一个函数的输出作为后续函数的输入,其中,一个函数的输出会被传递给下一个甚至多个后续函数作为输入。每个函数的输入也可能来源于一个或多个 preceding 函数的输出,如示意图所示:




理解了上面的四张图,相信我,你已经步入了神经网络编程的大门。恭喜你!
编程中,神经网络的分类
据我目前的知识,神经网络大致分为两类:预测机和分类机。
实际上,这两类神经网络在性能上并无显著差异。例如,在自动驾驶场景中,通过一张道路状况的照片,我们可以同时表述为:预测下一步的动作,是左拐、右拐或其他,或者判断该场景属于左拐、右拐或其他类别。因此,在分类处理上无需过分纠结。
在缺乏明确的转换公式的情况下,这样的神经网络只能充当预测工具,因为它们仅接受华氏度数据,并通过处理生成可能的摄氏度转换结果。
如果以分类机为目标,则问题就显得十分突出。例如,在73华氏度至74华氏度之间,存在着无限多个温度数值,因此无法全部进行分类。
函数:摄氏度转为华氏度函数
# 将摄氏度转为华氏度
def CToF(C):
return 1.8 * C + 32
其功能极为简单,不复杂,其主要作用是将摄氏温度转换为华氏温度。无论输入何种摄氏度数值,都能准确地得到对应的华氏度数值。
但是,这是我们想要的吗?不是!我们需要的是神经网络!
神经元:摄氏度->华氏度
当我们观察一个运算,比如41×41时,我们能迅速判断其结果超过1600。但要直接看出结果却并非易事,而计算机则能立即得出准确结果1681。
同样地,我们知道,人的正常体温通常在36.5℃到37.5℃之间,或者在97.7℉到100.7℉之间,然而,我们无法确切知道当前的体温是多少。但是,神经元能够通过自身的“经验”来“估计”我们当前的体温应该是多少。
由此可见,这里存在一个有趣的现象:神经网络的计算不需要精确,仅需近似即可。在编程神经网络时,不需要过于精确,实际上,精确计算是不可能的。在实际生活中,无论哪个领域,总能找到一些特殊的案例,有些人戏称这些现象为"地球OL的BUG"。
神经网络:温度转换
这个转换看起来有点棘手,因为公式F = 1.8 * C + 32有些模糊。虽然我们知道需要加32,但忘记乘以1.8了。幸运的是,大脑中有一个闲置的神经元可以用来完成这个转换,手上同时拥有一个华氏温度计和一个摄氏温度计,这样可以随时验证结果。
设置初始条件
已知摄氏度与华氏度之间的转换公式为:F = 常数 \times C + 32,为了估算该常数的值,现令该常数为1,即初始转换公式为:F = 1 \times C + 32。
我们使用温度计测量了下面一组数据:
| 华氏度 | 摄氏度 |
|---|---|
| 97.7 | 36.5 |
| 77 | 25 |
| 212 | 100 |
经过设置,我们的闲置的神经网络设置为如下图所示:

尝试计算
现在准备好了一切,我们把测量的36.5输入到网络中,网络计算后,输出了68.5。
然后计算误差项:97.7 - 68.5 = 29.2。(请注意,误差项可以是正数、负数或零。误差等于真实值减去计算值,当然,你也可以用计算值减去真实值来计算误差,只要你知道计算的依据,并且在计算过程中避免颠倒顺序。)
29.2华氏度,这个误差数值仍有一定规模。接下来,我们计划将C的系数提升至1.5。在乘以1.5后,我必须承认,这个变化幅度确实较大,但这是为了便于理解,实际上我们希望变化幅度更小一些。神经元变成了下面的样子:

输入第二个摄氏度的数据(25),再次计算,网络输出为69.5。
当前误差计算为:77 - 69.5 = 7.5。误差骤减,但误差依然存在,因此我们需要持续进行调整。1.5乘以1.5等于2.25,由此,神经元的结构如下所示:

现在计算第三个摄氏度的数据(100),得到257。
当前误差计算得出:212 - 257 = -45,无论采用真实值与计算值之差,还是计算值与真实值之差,均需保持一致。这一误差数值再次扩大,并呈现负值特征,这反映出我们的调整过于激进。由于后续的测量数据已无可用信息,因此我们被迫选择系数1.5作为神经元的训练目标,以确保误差控制在较为合理的范围内。
最终结果
通过一系列计算,我们最终得出了一个将摄氏度转换为华氏度的公式:F = 1.5 * C + 32。虽然与标准公式(F = 1.8 * C + 32)存在差异,但这种思路在神经网络领域被视为一种基础且关键的思想。在训练过程中,我们采用随机初始化的数据(如本例中的F = 1 * C + 32),通过使用三组测量数据计算误差,然后通过反复调整数据进行计算,以降低误差。最终获得了一个较为精确的公式(F = 1.5 * C + 32),这被视为神经网络训练过程中的一个成果。
这是我个人的总结,可能与官方表述有所不同,但核心思想只要大家能够理解,相信学习起来会相对容易。
上面的神经元的改进
最初,当参数设置为1时,计算结果出现了显著的误差。调整参数后,计算误差显著下降。然而,尽管我们尝试了多种调整策略,但最终仍采用了乘以1.5的方法,这导致参数变化过于剧烈,最终引发了误差的显著波动。
在计算过程中,第一次误差为29.2,第二次为7.5。如果我们每次仅调整误差的1%呢?比如,取误差的1%来试试。试试看。还是从头开始吧!
最初的神经元

尝试训练
把第一组数据的摄氏度36.5输入网络,得到输出为:68.5。
计算误差 :97.7 - 68.5 = 29.2。此时调整参数1为:1 + 29.2 / 100 = 1.292。现在新的神经元如下:

把第二组数据的摄氏度25输入网络,得到输出为:64.3。
计算误差为77减去64.3,结果为12.7。可见,尽管误差值没有发生剧烈变化,但至少误差值在稳步下降,朝着正确的目标稳步下降。
此时调整参数为:1.292 + 12.7 / 100 = 1.419。现在新的神经元如下:

此时将最后一组数据摄氏度100输入网络,得到输出为173.9。
计算误差为:212减去173.9等于38.1。调整后的参数值为:1.419加上38.1除以100,结果为1.8。很遗憾,通过误打误撞的方法,我竟然计算出一个精确的1.8,这种情况属于偶然现象,不是所有神经网络都能达到如此精确的结果。但希望各位能够理解,这里所传达的核心思想。
而此时新的神经元如下:

到此,训练数据结束。
选择最终结果
通常情况下,个人认为可以选择最后两次的任意之一作为最终的结果。本次纯属偶然获得精确的1.8的值,实际应用中可能比1.419更接近1.8,或者超过1.8。在数轴上,最后一次计算的参数应位于黄色区域。

鉴于此,在未知条件下,两次结果可能更优。其中改进版本乘以1.5可能更优,而倒数第二次乘以1.5可能更优。相比之下,经过改进后的版本中,最终结果明显更优(相较于之前的版本)。
写到最后
尽管今天的内容看似简单,但这也是神经网络的核心内容之一。掌握了这些,学好神经网络并非难事。然而,为了取得更好的学习效果,建议大家记住几个实用的建议。
1. 适当的改变参数,大误差大调整,小误差小调整。
神经元的参数设置不需要非常精确,仅需一个近似值即可使用,即使看似有些不切实际,同样可以作为有效的参数设置。
3. 每次训练要建立在前一次训练调整后的基础上。
如果感兴趣,不妨将改进版本中的调整率调整为2%来计算最终结果,不妨一试吧哈哈。
最近即将开学,在家中找了一份兼职工作。白天工作,利用业余时间学习和记录。更新内容不规律,尽量每周更新或每两周更新,感谢大家的包容!期待下次见面!
