【Python】使用numpy进行神经网络激活函数算法描述-三、How

时间:2024-03-06 07:57:59

3.1 准备工作

3.1.1 安装numpy和matplotlib

1、打开偏好设置

2、选择工程文件,选择Project Interpreter,点击+号

3、搜索numpy,点击Install Package

4、稍等片刻,IDE底部会有状态条提示,安装成功后出现如下提示

5、用同样的方式安装matplotlib 

6、然后回到代码中检查是否能import 

import numpy as npimport matplotlib.pyplot as plt

没有标红即正常,as表示给这个库命名,把上面的两个库命名为np和plt是目前通用做法,matplotlib.pyplot主要是用来画图,后面我们会用它来绘制函数的曲线。

3.2 基础数组与画图操作

3.2.1 生成数组

首先我们用numpy生成一个数组,使用arange函数直接生成一维数组,传入一个整数说明数组的长度 

import numpy as np
import matplotlib.pyplot as plt

a1 = np.arange(9)
print(a1)

3.2.2 绘制曲线

我们把这个数组画出来,使用matplotlib.pyplot的plot函数和show函数实现  plot函数用于绘制曲线,当只传入一组数组时,x轴默认为0,1,2……,y轴为传入的值。

import numpy as np
import matplotlib.pyplot as plt

a1 = np.arange(9)
print(a1)

plt.plot(a1)
plt.show()

这样不够直观,我们在plot中增加一个参数 

plt.plot(a1,’k-o’)中的k-o是设置所绘制图形的颜色、线条类型、图形类型,其中k表示黑色,-表示实线,o表示圆点, 这样子9个点都显示出来了。其他线条类型请参考 https://blog.csdn.net/qiurisiyu2016/article/details/80187177

3.3 Sigmoid公式

上面的公式的作用是将任意实数转换为0~1之间的数,方便后续处理,让我们看看它是如何实现的。

3.3.1 fz=-z

我们来一步一步解析,为了使数组更有代表性,我们给arange()函数传入两个参数 ,代表取数的范围从[-5,6),然后在plot()函数中加一个参数,让横坐标使用我们指定的数组:

可以看到,绘制的曲线为一条斜率为-1的直线。

3.3.2 fz=np.exp(-z)

np.exp(z)是以e为底,以输入参数z为指数的指数函数,数学表达式为fz=e^z

可以看到,绘制的曲线为一条递减的曲线,区间为(0,+∞),其中可以看到经典值e^0=1,e^1=2.718……(自然常数),由于小数点后位数较多,自动转换成了科学计数法,e表示10^,第一个数1.4841e+02即1.4841*10^2≈148,可以看到图中的 第一个点就在150附近。

3.3.3 fz=1+np.exp(-z)

这一步非常重要,如果不进行这一步操作,后续在取倒数时,会发现值的区间超出1,比如当np.exp(-z)=0.1时,1/np.exp(-z)=10,这样整个函数的区间还是(0,+∞),对数据范围限制作用就没有了。

3.3.4 fz=1/(1+np.exp(-z))

这个就是神经网络中的激活函数Sigmoid公式的具体实现,我们看一下它的曲线

这个可以说是非常经典的曲线了,可以看到它是区间(0,1)的递增曲线,并且增长趋势是先加速后减速,类似在动画制作中的小车运动曲线。

但是在实际使用过程中,它依然会存在一些问题,比如在深度神经网络中梯度反向传递时导致梯度爆炸和梯度消失、收敛缓慢、幂运算求解耗时等等,具体缺点说明可以参考

https://blog.csdn.net/tyhj_sf/article/details/79932893

中的详细介绍。

3.4 tanh函数

这个函数的取值区间为(-1,1) ,它的输出是0均值(原点左边+原点右边=0) ,一定程度上可以解决收敛缓慢的问题。

tanh(z)=(np.exp(z)-np.exp(-z))/(np.exp(z)+np.exp(-z))

我们还是来慢慢解析它。

3.4.1 fz=np.exp(z)-np.exp(-z)

这个结构看起来复杂,我们拆成两部分

np.exp(z)

即e^z次方,看看指数爆炸一般的增长

然后是np.exp(-z),这个图像我们之前有显示过了,就是曲线图形跟上面对称,递减的函数

那么两个函数相减的图像是什么呢?

可以看到,这个图像跟sigmoid图像的曲线趋势可以说完全相反,它先加速上升,然后中间缓慢,后面又加速上升,有点像我们学习新东西的过程,一开始大量吸收知识点快速上升,到了瓶颈期进展缓慢,过了以后又快速发展。

3.4.2 fz=np.exp(z)+np.exp(-z)

两个函数相加,可以猜到的是,他们会形成一个抛物线(开口朝下)

3.4.3 fz=(np.exp(z)-np.exp(-z))/(np.exp(z)+np.exp(-z))

tanh函数之前介绍过,它是一个区间(-1,1)的函数,由一个递增函数与一个抛物线函数之商所得,它的特点如前所述,取值区间为(-1,1) ,输出是0均值(原点左边+原点右边=0)。

3.5 Relu函数

目前比较流行的一种函数,ReLU虽然简单,但却是近几年的重要成果,有以下几大优点: 1) 解决了gradient vanishing问题 (在正区间) 2)计算速度非常快,只需要判断输入是否大于0 3)收敛速度远快于sigmoid和tanh

公式如下:

Relu=max(0,x)

它是分区间的函数,当z取值大于0时,取z值本身,小于等于0时,取0,函数实现及图像如下:

import numpy as np
import matplotlib.pyplot as plt


z = np.arange(-5, 6)

print(z)
fz = np.arange(11)
for i in range(11):
    if z[i] > 0:
        fz[i] = z[i]
    else:
        fz[i] = 0

print(fz)

plt.plot(z, fz, 'k-o')

plt.show()