2026/3/25 19:56:13
网站建设
项目流程
抚州南城网站建设,WordPress设置两个域名,电影购票网站开发背景,做网站的个人总结激活函数
式#xff08;3.3#xff09;表示的激活函数以阈值为界#xff0c;一旦输入超过阈值#xff0c;就切换输出。
这样的函数称为“阶跃函数”。因此#xff0c;可以说感知机中使用了阶跃函数作为
激活函数。也就是说#xff0c;在激活函数的众多候选函数中#xf…激活函数式3.3表示的激活函数以阈值为界一旦输入超过阈值就切换输出。这样的函数称为“阶跃函数”。因此可以说感知机中使用了阶跃函数作为激活函数。也就是说在激活函数的众多候选函数中感知机使用了阶跃函数。那么如果感知机使用其他函数作为激活函数的话会怎么样呢实际上如果将激活函数从阶跃函数换成其他函数就可以进入神经网络的世界了。下面我们就来介绍一下神经网络使用的激活函数。sigmoid 函数神经网络中经常使用的一个激活函数就是式3.6表示的sigmoid 函数sigmoid function。公式如下h(x)11exp(−x) h(x) \frac{1}{1 \exp(-x)}h(x)1exp(−x)1式3.6中的exp(−x)exp(-x)exp(−x)表示e−xe^{-x}e−x其中 e 是纳皮尔常数 (2.7182\cdots)。虽然 sigmoid 函数形式看起来复杂但它本质上是一个函数即给定某个输入后会返回某个输出的转换器。例如向 sigmoid 函数输入 1.0 或 2.0会得到如下输出h(1.0)0.731⋯ ,h(2.0)0.880⋯ h(1.0) 0.731 \cdots, \quad h(2.0) 0.880 \cdotsh(1.0)0.731⋯,h(2.0)0.880⋯神经网络中用sigmoid 函数作为激活函数进行信号的转换转换后的信号被传送给下一个神经元。实际上上一章介绍的感知机和接下来要介绍的神经网络的主要区别就在于这个激活函数。其他方面比如神经元的多层连接的构造、信号的传递方法等基本上和感知机是一样的。下面让我们通过和阶跃函数的比较来详细学习作为激活函数的sigmoid 函数。阶跃函数的实现这里我们试着用Python画出阶跃函数的图从视觉上确认函数的形状对理解函数而言很重要。阶跃函数如式3.3所示当输入超过0 时输出1否则输出0。可以像下面这样简单地实现阶跃函数。defstep_function(x):ifx0:return1else:return0这个实现简单、易于理解但是参数x只能接受实数浮点数。也就是说允许形如step_function(3.0)的调用但不允许参数取NumPy数组例如step_function(np.array([1.0, 2.0]))。为了便于后面的操作我们把它修改为支持NumPy数组的实现。为此可以考虑下述实现。defstep_function(x):yx0returny.astype(np.int)上述函数的内容只有两行。由于使用了NumPy中的“技巧”可能会有点难理解。下面我们通过Python解释器的例子来看一下这里用了什么技巧。下面这个例子中准备了NumPy数组x并对这个NumPy数组进行了不等号运算。importnumpyasnpxnp.array([-1.0,1.0,2.0])x array([-1.,1.,2.])yx0y array([False,True,True],dtypebool)对NumPy数组进行不等号运算后数组的各个元素都会进行不等号运算生成一个布尔型数组。这里数组x中大于0 的元素被转换为True小于等于0 的元素被转换为False从而生成一个新的数组y。数组y是一个布尔型数组但是我们想要的阶跃函数是会输出int型的0或1 的函数。因此需要把数组y的元素类型从布尔型转换为int型。yy.astype(np.int)y array([0,1,1])如上所示可以用astype()方法转换NumPy数组的类型。astype() 方法通过参数指定期望的类型这个例子中是np.int型。Python 中将布尔型转换为int型后True会转换为1False会转换为0。以上就是阶跃函数的实现中所用到的NumPy的“技巧”。阶跃函数的图形下面我们就用图来表示上面定义的阶跃函数为此需要使用matplotlib库。importnumpyasnpimportmatplotlib.pylabaspltdefstep_function(x):returnnp.array(x0,dtypenp.int)xnp.arange(-5.0,5.0,0.1)ystep_function(x)plt.plot(x,y)plt.ylim(-0.1,1.1)# 指定y轴的范围plt.show()np.arange(-5.0, 5.0, 0.1) 在−5.0 到5.0 的范围内以0.1 为单位生成NumPy数组[-5.0, -4.9, , 4.9]。step_function()以该NumPy数组为参数对数组的各个元素执行阶跃函数运算并以数组形式返回运算结果。对数组x、y进行绘图结果如图3-6 所示。如图3-6 所示阶跃函数以0 为界输出从0 切换为1或者从1 切换为0。它的值呈阶梯式变化所以称为阶跃函数。sigmoid 函数的实现下面我们来实现sigmoid 函数。用Python可以像下面这样写出式3.6表示的sigmoid 函数。def sigmoid(x): return 1 / (1 np.exp(-x))这里np.exp(-x)对应exp(−x)。这个实现没有什么特别难的地方但是要注意参数x为NumPy数组时结果也能被正确计算。实际上如果在这个sigmoid 函数中输入一个NumPy数组则结果如下所示。xnp.array([-1.0,1.0,2.0])sigmoid(x)array([0.26894142,0.73105858,0.88079708])之所以sigmoid 函数的实现能支持NumPy数组秘密就在于NumPy的广播功能1.5.5 节。根据NumPy 的广播功能如果在标量和NumPy数组之间进行运算则标量会和NumPy数组的各个元素进行运算。这里来看一个具体的例子。tnp.array([1.0,2.0,3.0])1.0t array([2.,3.,4.])1.0/t array([1.,0.5,0.33333333])在这个例子中标量例子中是1.0和NumPy数组之间进行了数值运算、/ 等。结果标量和NumPy数组的各个元素进行了运算运算结果以NumPy数组的形式被输出。刚才的sigmoid 函数的实现也是如此因为np.exp(-x)会生成NumPy数组所以1 / (1 np.exp(-x))的运算将会在NumPy数组的各个元素间进行。下面我们把sigmoid 函数画在图上。画图的代码和刚才的阶跃函数的代码几乎是一样的唯一不同的地方是把输出y的函数换成了sigmoid 函数。xnp.arange(-5.0,5.0,0.1)ysigmoid(x)plt.plot(x,y)plt.ylim(-0.1,1.1)# 指定y轴的范围plt.show()运行上面的代码可以得到图3-7。sigmoid 函数和阶跃函数的比较现在我们来比较一下sigmoid 函数和阶跃函数如图3-8 所示。两者的不同点在哪里呢又有哪些共同点呢我们通过观察图3-8 来思考一下。观察图3-8首先注意到的是“平滑性”的不同。sigmoid 函数是一条平滑的曲线输出随着输入发生连续性的变化。而阶跃函数以0 为界输出发生急剧性的变化。sigmoid 函数的平滑性对神经网络的学习具有重要意义。另一个不同点是相对于阶跃函数只能返回0 或1sigmoid 函数可以返回0.731 . . .、0.880 . . . 等实数这一点和刚才的平滑性有关。也就是说感知机中神经元之间流动的是0 或1 的二元信号而神经网络中流动的是连续的实数值信号。如果把这两个函数与水联系起来则阶跃函数可以比作“竹筒敲石”Asigmoid 函数可以比作“水车”。阶跃函数就像竹筒敲石一样只做是否传送水0 或1两个动作而sigmoid 函数就像水车一样根据流过来的水量相应地调整传送出去的水量。接着说一下阶跃函数和sigmoid 函数的共同性质。阶跃函数和sigmoid函数虽然在平滑性上有差异但是如果从宏观视角看图3-8可以发现它们具有相似的形状。实际上两者的结构均是“输入小时输出接近0为0随着输入增大输出向1 靠近变成1”。也就是说当输入信号为重要信息时阶跃函数和sigmoid函数都会输出较大的值当输入信号为不重要的信息时两者都输出较小的值。还有一个共同点是不管输入信号有多小或者有多大输出信号的值都在0 到1 之间。非线性函数阶跃函数和sigmoid 函数还有其他共同点就是两者均为非线性函数。sigmoid 函数是一条曲线阶跃函数是一条像阶梯一样的折线两者都属于非线性的函数。在介绍激活函数时经常会看到“非线性函数”和“线性函数”等术语。函数本来是输入某个值后会返回一个值的转换器。向这个转换器输入某个值后输出值是输入值的常数倍的函数称为线性函数用数学式表示为h(x) cx。c 为常数。因此线性函数是一条笔直的直线。而非线性函数顾名思义指的是不像线性函数那样呈现出一条直线的函数。神经网络的激活函数必须使用非线性函数。换句话说激活函数不能使用线性函数。为什么不能使用线性函数呢因为使用线性函数的话加深神经网络的层数就没有意义了。线性函数的问题在于不管如何加深层数总是存在与之等效的“无隐藏层的神经网络”。为了具体地稍微直观地理解这一点我们来思考下面这个简单的例子。这里我们考虑把线性函数 $h(x) cx $ 作为激活函数把 $ y(x) h(h(h(x))$ 的运算对应 3 层神经网络。这个运算法则进行 $ y(x) c \times c \times c \times x $ 的乘法运算但是同样的处理可以由 $ y(x) ax注意注意注意a c^3 $这一次乘法运算即没有隐藏层的神经网络来表示。如本例所示使用线性函数时无法发挥多层网络带来的优势。因此为了发挥叠加层所带来的优势激活函数必须使用非线性函数。ReLU函数到目前为止我们介绍了作为激活函数的阶跃函数和sigmoid 函数。在神经网络发展的历史上sigmoid 函数很早就开始被使用了而最近则主要使用ReLURectified Linear Unit函数。ReLU函数在输入大于0 时直接输出该值在输入小于等于0 时输出0图3-9。ReLU函数可以表示为下面的式(3.7)。h(x){x(x0)0(x⩽0) h(x) \begin{cases} x (x 0) \\ 0 (x \leqslant 0) \end{cases}h(x){x0(x0)(x⩽0)如图3-9 和式3.7所示ReLU 函数是一个非常简单的函数。因此ReLU函数的实现也很简单可以写成如下形式。defrelu(x):returnnp.maximum(0,x)这里使用了NumPy的maximum函数。maximum函数会从输入的数值中选择较大的那个值进行输出。本章剩余部分的内容仍将使用sigmoid 函数作为激活函数但在本书的后半部分则将主要使用ReLU函数。