神经网络是什么?
Y·L??
2024-11-16 18:04:54
最佳回答
以分类垃圾邮件为例。如果用传统程序做,怎么做?容易想到的一个思路是在邮件中搜索一些关键词,比如“**”之类的,然后给每个关键词分配一个分数,再将这些特征的分数加起来,得到一个总分。将这个总分和一个目标分数比较,大于这个分数结果为真(分类为垃圾邮件),小于这个分数结果为假(分类为正常邮件)。boolean detectspam(f1, f2, ..., fn) {if (w1 * f1 + w2 * f2 + ... + wn * fn > t) {return true;} else {return false;}}其中,f1 ... fn 代表匹配到的关键词,w1 ... wn 代表相应的分数。正如你所说:传统程序就是循环判断什么的那上面就是一个判断。detectspam是分类一封邮件的,将它应用到所有邮件上,不正是循环嘛。所以说,这是一个标准的传统程序。好了,现在我们给上面提到的东西起些新名字。分配的分数,我们起名叫权重,目标分数,我们起名叫阈值。最后我们再把返回的布尔值(true、false)改成数字1和0。那么上面的detectspam变成了什么,感知器(perceptron)!所以说,你可以将感知器看成传统程序中某类具有一些特定性质的函数。感知器接受多个输入,计算一个多项式的值(输入乘以权重并相加),返回一个输出(1或0)。之所以叫感知器,是因为它借鉴了神经末梢接受外部的输入,决定是否激动的思路。由于感知器主要是计算多项式的值,那么从直觉上,线性不可分的问题,比如异或(xor)函数,就无法转化成感知器的形式。但实际上,感知器并没有这么弱,将感知器组合一下,就可以表达异或函数。我们准备两个阈值为 0 的感知器,一个是x-y, 另一个是-x+y,将输入分别发给这两个感知器:然后再将输出提供给一个阈值为 0 的x+y感知器:比较输入和最终输出,可以看到我们的这三个感知器运算的结果是符合异或的定义的。这里,前两个感知器(x-y和-x+y)是第一层,最后一个感知器(x+y)是第二层。由此我们看到,通过组合感知器,可以构成一个分层的神经网络,分层的神经网络可以解决线性不可分问题。但是感知器还是看起来很弱啊。 异或函数这么简单的问题,都要这么复杂才能搞定。而稍微正常一点的编程语言,异或函数都能很直接地定义。我们何必要自废武功用感知器和神经网络呢?直接用传统程序不行吗?实际上,感知器和神经网络看起来很弱,但它也有优点:感知器的“接口”很齐整,每个感知器都有多个输入,返回一个结果,这就使得它们组合起来很容易。感知器内部都是在进行多项式运算,而不像传统程序一样千变万化,因此优化起来很容易(特别是现在我们有很强劲的擅长浮点运算的gpu)。感知器的运算结果只取决于它的输入,因此可以很容易地以分布式的方式跑。上面那个例子中x-y, -x+y, x+y的确定,来自于我们对异或函数的理解。假设我们对异或函数一无所知,感知器的结构决定了,我们比较容易通过**的方式(所谓训练神经网络)来尝试各种权重和阈值。相反,我们不太可能通过**的方式生成字符串恰巧撞对异或函数的一般定义。神经网络分层的结构,意味着我们可以逐层尝试,来逼近预期的结果。以上只是神经网络的基本原理。实际使用的神经网络要复杂很多。比如,我们的感知器只能输出 0 或者 1,而既然是**尝试,那我们就希望整个网络对参数的调整敏感一点。这时候我们就不再比较多项式的值和阈值来输出 0 或者 1,而是将阈值转化成偏置加到多项式上,并使用一个激活函数对多项式的结果进行处理,得到一个浮点数。最简单的激活函数是 relu, 定义很简单 max(0, n). relu 虽然简单,但出奇地好用。同时,实际工程中使用的神经网络,无论是规模还是结构一般都非常复杂。 20210311