神经网络中使用的激活函数
转换器,进行信号的转换,转换后的信号传送给下一个神经元。
阶跃函数的实现:
def step_function(x): # 输入NumPy数组
y = x > 0 # 对NumPy数组进行不等号运算,生成一个布尔型数组
return y.astype(np.int) # 把数组y的元素类型从布尔型转换为int型
用图来表示阶跃函数:
import numpy as np
import matplotlib.pylab as plt
def step_function(x):
return np.array(x>0,dtype=np.int) # 以数组形式返回结果
x = np.arange(-5.0,5.0,0.1)
y = step_function(x)
plt.plot(x, y)
plt.ylim(-0.1, 1.1) # 指定y轴范围
plt.show()
sigmoid函数的实现:
h ( x ) = 1 1 + e x p ( − x ) h(x)=\frac{1}{1+exp(-x)} h(x)=1+exp(−x)1
def sigmoid(x):
return 1 / (1 + np.exp(-x))
该函数能支持NumPy数组。(NumPy的广播功能)
sigmoid的平滑性对神经网络的学习具有重要意义。
感知机中流动的是0或1的二元信号,而神经网络中流动的是连续的实值信号。
输出层的设计
神经网络可以用在分类和回归问题上,不过需要根据情况改变输出层的激活函数。
一般而言,回归问题用恒等函数,分类问题用softmax函数。
softmax函数可以用下面的式子表示:
y
k
=
e
x
p
(
a
k
)
∑
i
=
1
n
e
x
p
(
a
i
)
y_k=\frac{exp(a_k)}{\sum_{i=1}^{n}exp(a_i) }
yk=∑i=1nexp(ai)exp(ak)
假设输出层共有
n
n
n个神经元,计算第
k
k
k个神经元的输出
y
k
y_k
yk。
softmax函数的分子是输入信号
a
k
a_k
ak的指数函数,分母是所有输入信号的指数函数的和。
def softmax(a):
exp_a = np.exp(a) # 指数函数
sum_exp_a = np.sum(exp_a)
y = exp_a / sum_exp_a
return y
实现softmax函数时的注意事项:
上文的实现存在缺陷,溢出问题。
可以这样进行改进:
y
k
=
e
x
p
(
a
k
)
∑
i
=
1
n
e
x
p
(
a
i
)
=
C
e
x
p
(
a
k
)
C
∑
i
=
1
n
e
x
p
(
a
i
)
=
e
x
p
(
a
k
+
log
C
)
∑
i
=
1
n
e
x
p
(
a
i
+
log
C
)
=
e
x
p
(
a
k
+
C
′
)
∑
i
=
1
n
e
x
p
(
a
i
+
C
′
)
y_k=\frac{exp(a_k)}{\sum_{i=1}^{n}exp(a_i) } =\frac{Cexp(a_k)}{C\sum_{i=1}^{n}exp(a_i) } =\frac{exp(a_k+\log_{}{C} )}{\sum_{i=1}^{n}exp(a_i+\log_{}{C}) } =\frac{exp(a_k+C' )}{\sum_{i=1}^{n}exp(a_i+C') }
yk=∑i=1nexp(ai)exp(ak)=C∑i=1nexp(ai)Cexp(ak)=∑i=1nexp(ai+logC)exp(ak+logC)=∑i=1nexp(ai+C′)exp(ak+C′)
该式说明,在进行softmax的指数函数的运算时,加上(或者减去某个常数不会改变运算的结果)。
可以通过减去输入信号的最大值来实现:
def softmax(a):
c = np.max(a)
exp_a = np.exp(a-c) # 溢出对策
sum_exp_a = np.sum(exp_a)
y = exp_a / sum_exp_a
return y
一般而言,神经网络只把输出值最大的神经元所对应的类别作为识别结果。并且,即便使用softmax函数,输出值最大的神经元的位置也不会变。
因此,推理阶段输出层的softmax函数可以省略。
在输出层使用softmax函数是因为它和神经网络的学习有关系。
输出层的神经元数量:
对于分类问题,输出层的神经元数量一般设定为类别的数量。