jor*_*nkg 4 python numpy neural-network softmax
我正在尝试为Numpy编写的神经网络实现softmax函数.设h是给定信号i的softmax值.
我一直在努力实现softmax激活函数的偏导数.
我目前陷入困境,随着训练的进行,所有偏导数都接近0.我用这个优秀的答案交叉引用了我的数学,但我的数学似乎没有成功.
import numpy as np
def softmax_function( signal, derivative=False ):
# Calculate activation signal
e_x = np.exp( signal )
signal = e_x / np.sum( e_x, axis = 1, keepdims = True )
if derivative:
# Return the partial derivation of the activation function
return np.multiply( signal, 1 - signal ) + sum(
# handle the off-diagonal values
- signal * np.roll( signal, i, axis = 1 )
for i in xrange(1, signal.shape[1] )
)
else:
# Return the activation signal
return signal
#end activation function
Run Code Online (Sandbox Code Playgroud)
该signal参数包含发送到激活函数的输入信号,并具有形状(n_samples,n_features).
# sample signal (3 samples, 3 features)
signal = [[0.3394572666491664, 0.3089068053925853, 0.3516359279582483], [0.33932706934615525, 0.3094755563319447, 0.3511973743219001], [0.3394407172182317, 0.30889042266755573, 0.35166886011421256]]
Run Code Online (Sandbox Code Playgroud)
以下代码剪切是一个完全正常工作的激活函数,仅作为参考和证明(主要是我自己)包含概念性想法实际工作.
from scipy.special import expit
import numpy as np
def sigmoid_function( signal, derivative=False ):
# Prevent overflow.
signal = np.clip( signal, -500, 500 )
# Calculate activation signal
signal = expit( signal )
if derivative:
# Return the partial derivation of the activation function
return np.multiply(signal, 1 - signal)
else:
# Return the activation signal
return signal
#end activation function
Run Code Online (Sandbox Code Playgroud)
这是如何以更加矢量化的numpy方式计算softmax函数的导数的答案.然而,偏导数逼近零的事实可能不是数学问题,并且只是学习率或复杂深度神经网络的已知死亡权重问题.像ReLU这样的图层有助于防止后一问题.
首先,我使用了以下信号(只是复制了你的上一个条目),4 samples x 3 features以便更容易看到尺寸发生了什么.
>>> signal = [[0.3394572666491664, 0.3089068053925853, 0.3516359279582483], [0.33932706934615525, 0.3094755563319447, 0.3511973743219001], [0.3394407172182317, 0.30889042266755573, 0.35166886011421256], [0.3394407172182317, 0.30889042266755573, 0.35166886011421256]]
>>> signal.shape
(4, 3)
Run Code Online (Sandbox Code Playgroud)
接下来,您要计算softmax函数的雅可比矩阵.根据引用的页面,它定义-hi * hj为非对角线条目(矩阵的大部分n_features > 2),所以让我们从那里开始.在numpy中,您可以使用广播有效地计算雅可比矩阵:
>>> J = - signal[..., None] * signal[:, None, :]
>>> J.shape
(4, 3, 3)
Run Code Online (Sandbox Code Playgroud)
第一个signal[..., None](相当于signal[:, :, None])重塑信号,(4, 3, 1)而第二个signal[:, None, :]重塑信号(4, 1, 3).然后,*只是将两个矩阵相乘.Numpy的内部广播重复两个矩阵,形成n_features x n_features每个样本的矩阵.
然后,我们需要修复对角线元素:
>>> iy, ix = np.diag_indices_from(J[0])
>>> J[:, iy, ix] = signal * (1. - signal)
Run Code Online (Sandbox Code Playgroud)
上述线提取n_features x n_features矩阵的对角线指数.它等同于做iy = np.arange(n_features); ix = np.arange(n_features).然后,用你的defitinion替换对角线条目hi * (1 - hi).
最后,根据链接的源,您需要对每个样本的行进行求和.这可以做到:
>>> J = J.sum(axis=1)
>>> J.shape
(4, 3)
Run Code Online (Sandbox Code Playgroud)
查找以下摘要版本:
if derivative:
J = - signal[..., None] * signal[:, None, :] # off-diagonal Jacobian
iy, ix = np.diag_indices_from(J[0])
J[:, iy, ix] = signal * (1. - signal) # diagonal
return J.sum(axis=1) # sum across-rows for each sample
Run Code Online (Sandbox Code Playgroud)
衍生物的比较:
>>> signal = [[0.3394572666491664, 0.3089068053925853, 0.3516359279582483], [0.33932706934615525, 0.3094755563319447, 0.3511973743219001], [0.3394407172182317, 0.30889042266755573, 0.35166886011421256], [0.3394407172182317, 0.30889042266755573, 0.35166886011421256]]
>>> e_x = np.exp( signal )
>>> signal = e_x / np.sum( e_x, axis = 1, keepdims = True )
Run Code Online (Sandbox Code Playgroud)
你:
>>> np.multiply( signal, 1 - signal ) + sum(
# handle the off-diagonal values
- signal * np.roll( signal, i, axis = 1 )
for i in xrange(1, signal.shape[1] )
)
array([[ 2.77555756e-17, -2.77555756e-17, 0.00000000e+00],
[ -2.77555756e-17, -2.77555756e-17, -2.77555756e-17],
[ 2.77555756e-17, 0.00000000e+00, 2.77555756e-17],
[ 2.77555756e-17, 0.00000000e+00, 2.77555756e-17]])
Run Code Online (Sandbox Code Playgroud)
矿:
>>> J = signal[..., None] * signal[:, None, :]
>>> iy, ix = np.diag_indices_from(J[0])
>>> J[:, iy, ix] = signal * (1. - signal)
>>> J.sum(axis=1)
array([[ 4.16333634e-17, -1.38777878e-17, 0.00000000e+00],
[ -2.77555756e-17, -2.77555756e-17, -2.77555756e-17],
[ 2.77555756e-17, 1.38777878e-17, 2.77555756e-17],
[ 2.77555756e-17, 1.38777878e-17, 2.77555756e-17]])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3141 次 |
| 最近记录: |