活性化関数というのは各層での重み掛けバイアス足しのあとに適用する非線形の関数。 これはカーネル法のように空間を変換して線形分離できないデータを線形分離できるようにするはたらきをする。 線形な関数を使うと層を重ねても結局線形のままで、空間もそのまま伸縮するだけなので目的を果たさない。
バックプロバゲーション(誤差逆伝播法)するために微分できる必要がある。
MLPと誤差逆伝搬法(Backpropagation) - sambaiz-net
Tensorflowでは以下の活性化関数が用意されている。
sigmoid
値域は(0,1)でシグマの語末系ςに似たS字を描く。 微分係数がそれほど大きくないので何層もこの関数を適用すると、バックプロバゲーションで微分係数を掛けていった結果、勾配が消失する問題がありあまり使われない。値域が(-1,1)で似たグラフを描くtanh(Hyperbolic tangent)もある。
softsign
tanhと比べて漸近線に近づく速度が遅くなっている。 それほど性能は変わらないが、初期化においてロバストになるはたらきがあるようだ。
softplus
ReLUに続く。
ReLU(Rectified Linear Unit)
単純だが最有力。勾配消失も起きにくい。x=0で微分できないが0か1として扱われる。
def deriv_relu(x):
return np.where(x > 0, 1, 0)
softplusと比べてexpやlogを含まない分高速に計算できるので、 膨大で複雑なデータセットに対して多くの層を用いることができる。
0以下は等しく0になるため、学習中に落ちてしまうとニューロンが死んでしまう。 これを避けるため0以下のとき y = exp(x) - 1 にするELU(Exponential Linear Unit) というのもある。
比較的起きにくいとはいえ、層を深くすると勾配消失する可能性は高まる。 活性化関数ごとに異なる重みの初期値によってこれを緩和でき、ReLUでは入力次元数によるHe Initializationというのが提案されている。
rng = np.random.RandomState(1234)
n_in = 10 # 入力次元数
rng.uniform(
low=-np.sqrt(6/n_in),
high=+np.sqrt(6/n_in),
size=5
) # He Initialization
参考
Activation functions and it’s types-Which is better?
Understanding the difficulty of training deep feedforward neural networks