神经网络可以用在分类问题和回归问题上,不过需要根据情况改变输出层的激活函数。一般而言,回归问题用恒等函数,分类问题用softmax函数。
恒等函数代码:
def identity_function(x): return x
简单softmax函数:
def softmax(x): return np.exp(x) / np.sum(np.exp(x))
实现softmax函数时的注意事项:
1.溢出缺陷
计算机处理“数”时,数值必须在4字节或8字节的有限数据宽度内。这意味着数存在有效数位(2^32),也就是说,可以表示的数值范围是有限的。因此,会出现超大值无法表示的问题。这个问题称为溢出。
那么,如果采用上述代码,在softmax函数的运算过程中,需要时时注意x的大小,防止指数函数ex轻易超过有小数位而造成显示异常inf,这显然很不方便。
对此,可以做出如下改进:
def softmax(x): x = x - np.max(x) # 溢出对策 return np.exp(x) / np.sum(np.exp(x))
通过将输入x规整到指数函数的负半轴,这样所有softmax内部运算中,ex的值域就被严格控制在了(0,1]之间,从而避免了运算溢出
2.输入x的维度不规整
在softmax函数中,x实际上是神经网络的输出y,一般情况下,神经网络只有一个输出层,输出层内可以有无数个神经元,其对应shape是(n,),但有时候可能因为表示方法的不同,可能会被表示成(1,n),这种情况下就需要先对输出y做一下转置才能传给softmax计算:
def softmax(x): if x.ndim == 2: x = x.T y = np.exp(x) / np.sum(np.exp(x), axis=0) return y.T return np.exp(x) / np.sum(np.exp(x))
3.softmax输出值相加为1
同样都是平滑曲线和激活函数,sigmoid和softmax最大的不同就在于sigmoid函数仅实现了数据规整,而softmax函数作为输出层的激活函数,除了数据规整外,还将y的总值收敛到1,使得y中的各个值能够直接代表概率值而输出
例如对于同样的输入x=[-0.5, 1.2, -0.1, 2.4]
sigmoid output:[0.33, 0.77, 0.48, 0.99] # sum = 2.53
softmax outpu:[0.04, 0.24, 0.05, 0.70] #sum = 1