机器学习09--神经⽹络的激活函数(ActivationFunction)及
python代码实现
在前⾯的⼀些关于机器案例中使⽤了激活函数,
如 开篇中的 tanh(x)与tanh_deriv(x)两个函数
中在最⼤池化时使⽤的 lu
我们为什么要使⽤激活函数,通常他有如下⼀些性质:
⾮线性: 如果是线性的时候,多层的神经⽹络是⽆意义的
可微性: 做梯度下降,这是不可少的
单调性: 如果是⾮单调的,那么⽆法保证⽹络是凸函数。
全是⾼数的东东,看着晕,相当的感觉⽤处不⼤,如果你数学⾜够好,⾃⼰能创建或写出新的激活函数,
⽴马觉得我这写得太简单,然后⼀块⾖腐把我拍个半死,丫的什么都不懂
如果你数学和我⼀样不太好,那就⽤⽤别⼈常⽤的就好了,所以卵⽤没有,纯粹为了假装很懂,让你不明觉厉
激活函数⽤在什么地⽅
当我们定义好神经⽹络层,并在每两层间做完矩阵乘法计算weight时,即np.dot后,
我们设val=np.dot(w,x),这时我们会再调⽤激活函数,如tanh(val)
当神经⽹络正向计算完后,进⾏反向计算时,
通过 y(实际值)-y(计算值)求出误差error  ,通过error * tanh_deriv() 可以得到我们要调整的值
基中tanh_deriv是tanh的导数,所以激活函数⼀定是成对出现,正向使⽤激活函数,反向使⽤激活函数的导数
⼜是⼀串的⾼等数学,⾼数基本⼲什么不太明⽩?不想深⼊就算了,想深⼊还是翻翻书吧。
再问⼀次,我们为什么要使⽤激活函数
如果上⾯导数的部份理解,那下⾯好理解, 导数不理解的话,就简单记记吧
如果我们不使⽤激活函数,那么正向运算时,val=np.dot(w,x)计算完就结束了,同样反向计算时,计算到 error=y(实际值)-y(计算值)后也结束了
这时,虽然最后也会有效果,但中间层完全没有作⽤,都是直来直去的嘛
数理上也简单,如果不使⽤激活函数,那么可以假设这个激活函数为f(x)=x 同样,导数f'(x)=1,在反向调整误差时,中间层没发⽣变化
所以综合⼀句, 如果不使⽤激活函数,则神经⽹络的效果只相当于只有输⼊层与输出层两层,设置多少层中间层也没卵⽤
先介绍⼏个激活函数,同时后⾯有相应的python代码,同样会绘制出相关的曲线
1、Sigmoid 与 tanh  函数,这两个函数差不多,从下图中就能看得出来,能够把输⼊的连续实际值进⾏压缩。
主要差异在于Sigmoid 把值压到0-1之间,tanh把值压到-1,1之间
仔细看看图再想想也就看得出来了,这两种函数都有⼀个共同的缺点,
当输⼊⾮常⼤或者⾮常⼩的时候,这些神经元的梯度是接近于0的,
也就是说,当初始值没设好,会导致很多值接近于0,⽽在梯度下降时,就会跳过
所以对初始值的设置与调试⾮常重要
同样这两个函数⽐较的话,tanh会更好点,因为Sigmoid 把值压到0-1之间,假设所有x正负值相同时,Sigmoid对应的y值不是零均值,⽽tanh是零均值,因此,在实际应⽤中,tanh 会⽐ sigmoid 更好,
# -*- coding:utf-8 -*-
#tanh 函数
import numpy as np
import matplotlib.pyplot as plt
def tanh(x):
return np.tanh(x)
def tanh_deriv(x):
return 1.0 - np.tanh(x) * np.tanh(x)
x = np.linspace(-6,6,200)
plt.scatter(x,tanh(x),label="tanh")
plt.scatter(x,tanh_deriv(x),label="tanh_deriv") plt.title('tanh Function')
plt.legend(loc = 'upper left')
plt.show()
#Sigmoid
import numpy as np
import matplotlib.pyplot as plt
def sigmoid(z):
return 1.0 / (1.0 + np.exp(-z))
def sigmoid_deriv(z):
return sigmoid(z) * (1 - sigmoid(z))
x = np.linspace(-6,6,200)
plt.scatter(x,sigmoid(x),label="sigmoid")
plt.scatter(x,sigmoid_deriv(x),label="sigmoid_deriv")
plt.title('sigmoid Function')
plt.legend(loc = 'upper left')
plt.show()
2、RELU 与 Leaky RELU函数
2.1 RELU 函数现在好像越来越受欢迎,看了好多关于为什么RELU对神经⽹络最后效果明显的根本原因
但没感觉有哪个有特别的说服⼒,⽆所谓了,⼤家说好了,我也赞⼀下,linspace numpy
这个函数很简单f(x)=max(0,x),⽂字表达就是,x⼩于零时取零,x⼤于零时就是x,更简单的说负数不要
在实操中,如果你的学习率很⼤时,那么很有可能⾮常多的神经元⽆效。
当然,较⼩的学习率,这个问题就不明显,但因为学习率的降低,最后的计算量也就⼤了。
2.2 Leaky RELU 是RELU的⼀个简单变形,就是把x⼩于零的部份乘以⼀个很⼩的值,这样把负值的
部份进⾏等⽐压缩        ⾄于最终的效果好不好我也不清楚,有⼈说好有⼈说不好,反正我没试过,
#RELU
import numpy as np
import matplotlib.pyplot as plt
def RELU(z):
return np.array([x if x > 0 else 0 for x in z])
def RELU_deriv(z):
return np.array([1 if x > 0 else 0 for x in z])
x = np.linspace(-6,6,200)
plt.scatter(x,RELU(x),label="RELU")
plt.scatter(x,RELU_deriv(x),marker='.',label="RELU_deriv",)
plt.title('RELU Function')
plt.legend(loc = 'upper left')
plt.show()
#Leaky RELU
import numpy as np
import matplotlib.pyplot as plt
def LeakyRELU(z,a=0.3):
return np.array([x if x > 0 else a * x for x in z])
def LeakyRELU_deriv(z,a=0.3):
return np.array([1 if x > 0 else a for x in z])
x = np.linspace(-6,6,200)
plt.scatter(x,LeakyRELU(x),label="LeakyRELU")
plt.scatter(x,LeakyRELU_deriv(x),marker='.',label="LeakyRELU_deriv",) plt.title('LeakyRELU_deriv Function')
plt.legend(loc = 'upper left')
plt.show()
以上四种激活函数怎么选择?
我也不知道,...,怎么眼前全是⾖腐,
个⼈感觉,纯属个⼈感觉,使⽤RELU,调整学习率很重要,tanh⽐Sigmoid好⽤⼀点, ⼜是屁话,学习率很重要?初始化、学习率,⽹络层设置哪个不重要?全部都重要好的吧
写了这么多,就⼀句话的意思, 多层神经⽹络要使⽤激活函数
再画⼏个激活函数,有⽤?没⽤?好⽤?难⽤?我也没⽤过,不知道,只想装个X,

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。