2018年4月10日火曜日

Deep Learningで素子の寄与度を調べる

Random Forestでは特徴量の寄与度を簡単に算出できる (参考: PythonR) ので重宝していたのですが、Deep Learningでも似たような事が一応できます。

Deep Learningで特徴量の重要度を (なんとなく) 算出してみたい場合は、入力素子の結合強度を見ると良いでしょう。 強度が強いほど重要と言えるはずです。Kerasでは以下のように書ける。
weights = model.get_weights()
importances = list(map(lambda n:numpy.sum(np.abs(n)), weights[0]))
indices = np.argsort(importances)
# 重要度順に表示
for index in indices:
    print('%d: %.8f' % (index, importances[index]))
# 素子順に表示
for i in range(0, len(importances)):
    print('%d: %.8f' % (i, importances[i]))
model.get_weights() の一列目は入力素子への重みなのでこれを利用しています。 model.get_weights() で取得できる構造は ここ を参照してみてください。 他のライブラリでも同じ事はできるでしょう。

もう少し正確に算出するには中間層の重みも考慮したほうが良いかも知れませんが、 重要度が高くても過学習の原因になる事もあり絶対的な指標ではないので、適当めの算出でも良いかと。 特徴選択の参考にする程度なら結構有用かも知れません。


他にも特定の素子が精度に与える影響なども以下で確認できたりします。

入力素子 (特徴量) の寄与度

調べたい特徴量を0に置換した場合と、しない場合の精度の差分で寄与度を確認できます。 例えば前方16個の素子の寄与度を調べたい場合、Kerasでは以下のように書ける。
def mask(features):
    features[:16].fill(0.0)
    return features

x_test = numpy.array(list(map(lambda n:mask(n), x_test)))
model.evaluate(x_test, y_test)

先に述べたように model.get_weights() の一列目は入力素子への重みなので、そちらを0置換しても良いです。 その場合は以下に述べる方法で可能。

中間層の素子の寄与度

調べたい中間層の素子の重みを0に置換した場合と、しない場合の精度の差分で寄与度を確認できます。 例えば第2中間層の前方16個の寄与度を調べたい場合、Kerasでは以下のように書ける。
weights = model.get_weights()
weightsl[2][:16].fill(0.0)
model.set_weights(weights)
model.evaluate(x_test, y_test)

素子の重みを0置換して評価すると、過学習の起因となる素子を調査できるので便利です。

0 件のコメント: