深度学习基础2–神经网络
引言
在前面的一篇内容中,提到了感知机。对简单并不复杂函数能够使用单个感知机来进行实现(与门、与非门、或门等),而对于复杂的函数而言,我们能通过几个感知机相互结合来实现在(异或门)。理论上来说,需要复杂处理的函数都可以通过感知机来实现,然而这里也很明显有一个很现实的问题,那就是权重参数的设定。即我们需要针对问题来确定出一组适当的参数来构建感知机模型。
对于这个问题,神经网络给出了答案,具体来说,神经网络那就是通过从数据中学习到合适研究问题的权重参数。那么对于这篇博客,我的想法是先从神经网络最根本的内容——神经元结构讲起,先从神经网络的构造逐步学习到后面。
感知机到神经网络
深度学习所以用到的神经网络之所以用到了“神经”二字,以我现在所理解的就是因为神经元。神经元和我们上一篇内容所提及的感知机有很多共同点,基本上都是多个输入一个输出的结构。与感知机的差异主要还是体现在神经网络上面,那么让我们看一下神经网络的结构,如下图所示。
我们把最左边的一列称为输入层,最右边的一列称为输出层,中间的是隐藏层,也称为中间层。隐藏层的层数数量不固定,可以设置多层,当然,对应神经网络的复杂度也会变大。一般来说,图中的神经网络我们称为“2层网络”(有些教材上面也说是3层,也是可以的),从输入到输出依次称为第0层、第1层、第2层。从图中来看的话,与上一篇内容所讲的感知机很类似,事实上如果单从每个神经元的连接方式来说,神经网络与 多个感知机连接的模型结构 并没有差异,那也就是说,神经网络的信号其实与感知机的传递方式是一样的!
从感知机到神经元
我们从单个神经元来看,如图所示:
相较于上一篇内容的感知机,似乎多了一个b?我们回到感知机的数学表达式1:
y
=
{
0
w
1
x
1
+
w
2
x
2
≤
θ
1
w
1
x
1
+
w
2
x
2
>
θ
式
1
y = \begin{cases} 0& \text{ } w_{1}x_{1}+w_{2}x_{2}\le \theta \\ 1& \text{ } w_{1}x_{1}+w_{2}x_{2}> \theta \end{cases}\\ 式1
y={01 w1x1+w2x2≤θ w1x1+w2x2>θ式1不难看出吧,这里的b似乎就是感知机模型的
θ
\theta
θ!那也就是说,对于单个神经元的输入方式与感知机是一样的。事实上,这里的b我们称之为偏置,
w
1
w_{1}
w1、
w
2
w_{2}
w2依旧称为权重。神经元的输入可以用表达式:
a
=
x
1
×
w
1
+
x
2
×
w
2
+
1
×
b
式
2
a = x_1×w_1+x_2×w_2 +1×b \\ 式2
a=x1×w1+x2×w2+1×b式2
这和感知机的输入有区别,区别在于把偏置也一起放入到了输入表达式之中了。这算是单个神经元和感知机的一个差异,那么神经元和感知机的差异就只有如此么?当然不是!
神经网路的激活函数
我们刚刚是不是讲到了神经元的输入方式?还没有讲它的输出方式! 我们先回到感知机的输出也就是表达式1,感知机的输出只有1和0。可以看出,感知机的输出需要判定输入的大小,不同的输入有着不同的输出。我们可以用一个表达式来表示(
θ
\theta
θ包含到输入中):
h
(
x
)
=
{
0
x
≤
θ
1
x
>
θ
式
3
h(x) = \begin{cases} 0& \text{ } x\le \theta \\ 1& \text{ } x> \theta \end{cases}\\ 式3
h(x)={01 x≤θ x>θ式3好的,回到神经元,神经元的输出也可以用式3来表示,h(x)函数能够将输入 信号的总和转换为输出信号,这种函数一般称为**激活函数(activation function)**综合一下式2的内容,我们可以把神经元的输入和输出为:
a
=
x
1
×
w
1
+
x
2
×
w
2
+
1
×
b
y
=
h
(
a
)
式
4
a = x_1×w_1+x_2×w_2 +1×b \\ y = h(a)\\ 式4
a=x1×w1+x2×w2+1×by=h(a)式4首先,计算出加权输入和偏置的总和,记为a,然后再将a代入到h(x)中转换为输出有,单个神经元的形式如下图所示:
其实讲了这么多,我们可以发现,神经网络中的神经元似乎与感知机并没有多少差异,在一些教材上面,“朴素感知机”指的是单层网络,而激活函数使用的就是阶跃函数,阶跃函数就是大于0的部分输出1,小于0的部分输出为0,学过信号的同学应该会很清楚。而“多层感知机”也是指神经网络。区别就是在激活函数上。
激活函数
前面,我们已经了解到了激活函数是将输入信号转换为输出信号的一个函数。介于篇幅问题,这里我们简单说一下最常用的激活函数。下一篇将会讲一下激活函数的对比。
阶跃函数
刚刚我们简单说过阶跃函数,阶跃函数就是大于0的部分输出1,小于0的部分输出为0,这不就是表达式3嘛。那就可以通过代码简单得实现:
def step_function(x):
if x> 0:
return 1
else:
return 0
实现起来很简单,读者可以自己画一下函数图像。
sigmoid 函数
神经网络中最常使用的一个激活函数就是sigmoid函数(sigmoid function),也称为s型函数,表达式如式5所示:
h
(
x
)
=
1
1
+
e
−
x
式
5
h(x) = \frac{1}{1+e^{-x} } \\ 式 5
h(x)=1+e−x1式5
e是纳皮尔常数2.7182…。函数实现需要借助numpy库,具体代码如下:
import numpy as np
def sigmoid(x):
return 1 / (1+np.exp(-x))
代码实现很简单,其实就是一个函数,并没有多复杂。
小结
在这一篇中,我们简单介绍了一下神经网络,包括神经网络的输入、输出方式,以及神经网络正向传播中比较重要的激活函数。这节内容篇理解,但问题应该不大。