介绍
如今, 科学家正在努力探索人脑的奥秘, 他们试图通过模仿人脑, 来找到大数据的解决方案.
我感觉现在没有深入浅出的, 实用的介绍神经网络 (NN) 的文章. 我一直想弄清楚人脑是怎么工作的, 但我还有很多问题没有答案, 而且总是很难把握神经网络工作的细节. 这篇文章中, 我想回答的最关键的问题是:
1. 人脑是如何工作的?
2. "感知器" 如何充当人工神经元?-- 前向神经网络 3. 什么是神经网络的权重? 4. 生物体内的神经元权重是多少? 5. 神经网络中激励函数起什么作用? 6. 生物体内什么东西起到了神经元激励函数的功能? 7. 反向传播如何工作? 8. 反向传播神经网络的确切的数学逻辑是什么? 9. 如何实现反向传播神经网络?
1. 人脑是如何工作的?
要理解神经网络如何工作, 最好先研究一下人脑的运作机理. 人脑有约一千亿个神经元, 彼此之间紧密相连. 当你看到一个动物 -- 比如猫, 其大小, 颜色, 形状等特征会从眼睛传入大脑. 然后, 这些输入的信息将被一些小细胞处理, 这些细胞被称作神经元, 它们负责处理输入大脑的数据.
首先, 神经元会搜索你以前见过的猫的图像, 然后比较你记忆中的猫和新看到的猫的图像. 这种比对是 "监督学习" 的基础, 它让你的大脑就像一个比较器一样, 这就是为什么人们看见什么东西都想要比较一番. 经过比较后会得到结果: 你看到的是一只猫 -- 因为你之前看到过猫.
借助眼睛, 你的大脑可以每秒处理 20 Mb 的信息. 这很神奇, 因为这与你的学习能力, 分辨某人声音或者听觉的能力如何没有关系. 所以, 你的大脑是一个难以置信的巨大的 CPU.
如果把这个庞大系统的规模简化到很小, 就可以解决今天不同领域的问题. 比如说, 用很小一部分的人脑的特征就可以解决诸如语言, 面部或图像的识别问题, 情感分析, 观点或情绪的理解问题, 自动驾驶汽车, 甚至疾病诊断等问题.
下图就是神经元细胞, 包括树突, 轴突和细胞核. 从左到右看, 树突负责接收信息, 细胞核负责处理数据, 处理结果将从轴突传递到神经元的尾部. 这一整个神经元的结构, 在人工智能中被称作 "感知器".
右侧的另一个神经元细胞将受到某些化学物质的激励, 从而接收左侧神经元的反应. 这种激励造成了数据在细胞间的传递, 转移. 所以, 左侧神经元的输出就是右侧神经元的输入. 其他的神经单元也存在同样的过程. 就这样, 大脑一千亿个神经元相互协作, 以达成目标.
你每天都要做这么多的信号处理来过好你的生活, 而大脑做这些都毫不费力. 一天结束时, 你只需要 7 个小时来恢复这些小细胞. 神经科学家发现, 越是学习, 你的树突就会越强, 因为激发神经元细胞之间的联系也是一种锻炼, 就像锻炼肌肉一样. 因此, 大脑用得越多, 越不可能患上阿尔茨海默病.
2."感知器" 如何充当人工神经元?-- 前向神经网络
下图是一个简单的感知器模型, 以及他获得输出结果的计算操作. 首先有两个输入 X1 和 X2, 然后每个连接都有相应的权重. 在神经网络中, 所有的处理单元都是节点. 尽管计算机系统有复杂的处理单元, 但在神经网络中存在着简单的处理单元.
我们先让输入 (X) 和权重 (W) 相乘, 然后对所有结果求和, 并把结果代入一个激励函数, 最终的结果就是这个感知器的输出.
上述过程称作神经网络的前向传播. 但实际上, 在神经网络学习中, 我们用更多的节点和层数. 我之前说过, 在我们的大脑中有数十亿层, 这个庞大的系统造就了我们今天的人类. 所以, 为了学习得更好, 我们把层数增多, 这样一般会提高学习, 训练的结果. 下图中有两个隐含层, 用浅蓝色表示, 每个节点都像上述的简单感知器一样工作.
3. 什么是神经网络的权重?
权重是指节点之间的连接强度. 无符号 (没有正负) 的权重大小取决于节点之间的连接有多强.
而权重可以是正值或负值, 正值代表传递数据的可能性更大, 神经元之间有强大的联系, 反之亦然. 一开始, 我们随机选择权重, 但为了让结果更合理, 最好将输入数据进行如下的归一化, 其中 X 是输入数据:
Standardize=\frac{X-\mu}{Standard\;Deviation(X)}
Standard\;Deviation=\sqrt{\sum{\frac{(x-\mu)^2}{n-1}}}
因为本文中的激励函数是累加型的, 所以有一个简便方法来随机地选择权重值: 把权重限制在一个特定的区间内 -- 如下面的公式. 这个公式取决于平均分布, 其内在逻辑在此暂且不表, 下一篇文章中我们会展开来说.
(-w,w)\;w=4\sqrt{\frac{6}{number_{input}+number_{output}}}\;n∈number\;of\;input
以上公式请参考: Deep Learning Tutorials (深度学习教程); Glorot and Bengio (2010)
我提到说, 神经网络是高度互连的, 而权重是实现这种互连的最重要的因素. 我们在第一阶段中随机选择权重值. 首先, 从左到右地完成前向传播.
然后比较一下结果和真实值的误差有多大, 真实值是训练数据集中的 "Y" 值. 然后进行反向传播计算 -- 即在相反的路径上进行计算.
前向传播是从左到右, 而反向传播是从右到左, 以此优化并获得新的权重, 使下一次的输出值被优化. 如果下一次的输出值与 "Y" 的误差小于之前输出值的误差, 则表明我们的优化方式是正确的.
可见, 权重是将节点彼此连接起来的一种工具, 也是训练神经网络减少错误的一个因素. 通过多次测量反向传播, 前向传播并进行权重校准, 可以获得新的权重和准确的输出值, 从而降低误差.
为了更好地理解神经网络中的权重扮演的角色, 我请您阅读我关于 "机器学习和梯度下降" 的文章. 神经网络中的权重基本接近 Y 值的预测线中的斜率 "a",Y=aX+b. 准确的 "a" 值可以帮助我们找到更好的预测线来对数据进行分类. 这里神经网络的权重也是一个类似 "a" 的因素, 我们努力找出它的精确值, 以求更准确的分类.
4. 生物体内的神经元权重是多少?
所有的神经网络结构都是从人脑中得到灵感启发的. 因此, 加权的无符号值表示: 神经元之间的树突连接数 + 树突之间的突触数 + 突触的前, 后末端 + 神经元之间间隙的形状 + 连接强度; 还有髓鞘的状态也很重要.
髓鞘是在神经元细胞轴突周围的白色的脂肪物质, 它像保护膜一样保护着它们. 下图中, 信号在有髓鞘的右侧神经元的比在没有髓鞘的左侧神经元中传播得快得多. 这种现象是由跳跃传导产生的.
频繁, 快速的传播会形成更多, 更强的突触, 这对大脑学习能力起着重要的作用. 对大脑更强大的人进行的功能性磁共振成像 (FMRI) 的结果表明, 他们的突触和脑活化区域更多.
因此, 神经网络中的权重与生物中的上述因素的组合是一样的.
https://en.wikipedia.org/wiki/Myelin
5. 神经网络中激励函数起什么作用?
激励函数 (虽然只在一定程度上) 起到 "极化" 和 "稳定化" 的效果. 我想举例说明一下 "极化" 和数学上的 "稳定化". 为方便计算, 我们需要对数据做一点极化处理, 尤其是对十进制数. 例如, 我们有 1.298456, 我们只需要一个数字作为小数.
为了四舍五入, 极化, 计算简捷, 我们将 1.298456 化为 1.3-- 因为小数点后 2 的下一个数字是 9,9 大于 5, 所以我们将 2 转换为 3. 这种情况下, 四舍五入可以有更简洁的值和结果.
在神经网络中, 我们希望更精确地分类和预测, 而非线性函数图像有更多的弧度, 弯曲. 如下图, 相比线性和非线性函数, 显然非线性函数预测的精度更高, 并且有能更好的区分两类不同事物的分界线.
我在梯度下降中使用了 "误差平方和(SSE)". 神经网络的激励函数应该是像指数或正切一类的非线性函数. 而因为在反向传播中, 我们要找到全局最小点, 所以函数也必须是可微的. 实际上, 正是反向传播造成了梯度下降. 详情请阅读关于梯度下降的文章: 点击这里.
误差平方和 (SSE)= ½Σ(Y 真实值 - Y 预测值)²
SSE 代表 Y 的预测值和真实值之间的误差. 因此, 为了获得最佳预测线而不是直接用上图的蓝线, 我们要对 SSE 求微分, 然后计算出该线的新的斜率.
您可以从下列函数中选一个作为激励函数, 详情请参考 这个链接 .
6. 生物体内什么东西起到了神经元激励函数的功能?
神经网络中的激励函数也称作传递函数, 其根据自己的输入给出该节点的输出. 激励函数在生物学中被称作动作电位, 其与信号在轴突中传播方式有关.
化学物质引起电信号激励, 并刺激神经元, 然后刺激其轴突, 以便在神经元上单向传输信号. 它辅助神经元产生输出结果. 详情请参考 这个链接 .
7. 反向传播如何工作?
为了串联起以上所有的概念, 我想把反向传播工作流程分成以下几个步骤来说明:
* 一开始有一组训练数据, 数据中既有 X 也有 Y,X 有一列或多列, 而 Y 作为一个要考虑的参量. 这样, 输入和输出层单元的数量就确定了.
* 接着我们需要选择隐藏层的层数. 隐藏层的层数代表了学习的深度, 层数越多, 模仿人脑就越像, 结果也就越准确. 但主要问题是隐藏层越多, 计算量越大, 内存消耗也就越大, 反向传播时尤其如此.
* 隐藏层确定后, 我们需要正态随机选择的权重值, 例如在本文第三部分我解释过一个公式.
* 正向传播得到输出结果:
每一层都有节点, 我假设它们输出有两种值: 一种是不套用 Sigmoid 函数的 "Input_{sigma}" 或 "hidden_{sigma}", 另一种是套用了 Sigmoid 函数的 "hidden_{node}" 和 "output_{node}". 然后我们从左到右计算, 进行前向传播.
(1) input_{sigma}=input_{node}\times weight_1
(2) hidden_{node}=Sigmoid(input_{sigma})
(3) hidden_{sigma}=hidden_{node}\times weight_2
(4) Sigmoid(hidden_{sigma})=output_{node}
(5) margin_{error}=expected-output_{node}
* 反向传播优化权重:
在反向传播中, 因为我们要找到最优权重值, 所以我们对 Sigmoid 函数求微分, 然后从右向左反向计算, 以找到新的权重值.
(6) output_{node}^\prime=Sigmoid^\prime(hidden_{sigma})\times margin
(7) weight_2^\prime=(output_{node}^\prime\;/\;hidden_{node})+weight_2
(8) hidden_{node}^\prime=(output_{node}^\prime\;/\;weight_2)\times Sigmoid^\prime(input_{sigma})
(9) weight_1^\prime=(hidden_{node}^\prime\;/\;input_{node})+weight_1
(10) 如果当前误差小于之前的误差, 则说明我们优化的方向正确, 就用新得到的权重值重复执行 1-5 步.
(11) 重复步骤 1 到 10, 直到结果接近 "Y".
8. 反向传播神经网络的确切的数学逻辑是什么?
反向传播和梯度下降作用相同, 我们需要对激励函数求微分. 它的计算过程如下:
XOR(异或运算)是测试我们神经网络的最简单的样例. XOR 的真值表如下, 它有两个操作数和一个结果:
例如我想要实现第四行操作:(1,1)=0
Y 是 0, 输出是 0.68, 所以边际误差是 - 0.68. 下一个输出是 0.57, 边际误差小于 0.68.
9. 如何实现反向传播神经网络?
执行文件:
基于上述知识, 我要在 Matlab 中实现神经网络. 首先, 我创建了 "execution.m" 文件用来调用我的预测函数.
%% 机器学习 - 神经网络 - 简要例程
%% 初始化
clear ; close all; clc
input_node = [1 1]; %1*2
% 通过正态分布获得权重
Weight_1 = [ -0.5 1.01 0.23 ; -0.32 -0.24 -0.12 ]; %2*3
Weight_2 = [ 0.15 1.32 -0.37 ]; %1*3
pred = mypredict(Weight_1, Weight_2, input_node);
fprintf('反向传播最终输出: %f\n', perd);
预测文件:
然后, 我写了 "myprerdict.m", 这是最主要的代码:
function p = mypredict(Weight_1, Weight_2, input_node)
% 前向传播
input_sigma = input_node * Weight_1;
hidden_node = sigmoid(input_sigma); % 1 * 3 hidden_sigma = hidden_node * Weight_2 ';
output_node = sigmoid(hidden_sigma);
for jj=1:1000
%sigmoid' = f(x)(1 - f(x)) % output_node_prime = s '(inner_sigma)*margin
if jj>1
Weight_2 = Weight_2_prime;
Weight_1 = Weight_1_prime;
end
margin = 0 - output_node;
sigmoid_prime_hidden_sigma = sigmoid(hidden_sigma);
output_node_prime = (sigmoid_prime_hidden_sigma *(1-sigmoid_prime_hidden_sigma))*margin;
delta_weight = (output_node_prime)./hidden_node; % 1*3
Weight_2_prime = Weight_2 + delta_weight;
sigmoid__prime_input_sigma = sigmoid_derivative(input_sigma);
mydivide = output_node_prime./Weight_2;
hidden_node_prime = zeros(1,3);
hidden_node_prime(1,1) = mydivide(1,1) * sigmoid__prime_input_sigma(1,1);
hidden_node_prime(1,2) = mydivide(1,2) * sigmoid__prime_input_sigma(1,2);
hidden_node_prime(1,3) = mydivide(1,3) * sigmoid__prime_input_sigma(1,3);
delta_weight_2 = hidden_node_prime' * input_node;
Weight_1_prime = Weight_1 + delta_weight_2 ';
input_sigma = input_node*Weight_1_prime;
hidden_node = sigmoid(input_sigma); % 1*3
hidden_sigma = hidden_node*Weight_2_prime';
output_node = sigmoid(hidden_sigma);
end p = output_node;
end
Sigmoid 函数:
function y = sigmoid(x)
y = 1.0 ./ (1.0 + exp(-x));
end
Sigmoid 派生函数:
function y = sigmoid_derivative(x) % sigmoid ' = f(x)*(1-f(x))
sigmoid_helper_2 = zeros(1,3);
for i=1:3
a= x(1,i);
sigmoid_helper_2(1,i)= sigmoid(a)*(1-sigmoid(a));
end
y = sigmoid_helper_2;
end'
亮点
我发现神经网络非常令人激动, 我认为我们可以把它称作人工智能之母.
神经网络的最大优缺点是:
归一化的数据集和选择最优解可以使我们在海量的训练数据中得到更精确的输出;
系统性能和准确度取决于权重, 如果你的权重在合适的区间中, 那就可以得到性能和准确性的提高;
相比其他的方式, 反向传播会消耗更多的内存.
最后, 我强烈建议您在 coursera.org 上加入机器学习: https://www.coursera.org/learn/machine-learning
另外, 我的 github 可以用作学习指导:
https://github.com/Hassankashi?tab=repositories
反馈
欢迎对本文留言, 期待看到您对此代码的意见和支持. 如果您有任何问题, 请直接在这里问我.
来源: https://cloud.tencent.com/developer/article/1029994