zuminote

個人的な勉強記録

PythonとKerasによるディープラーニング 第3章(2)多クラス分類

ロイターデータセットを使った、記事の多クラス分類を行う。

ここでの学び:

  • 分類タスクで使う損失関数「交差エントロピー」は、学習モデルにによって出力される確率分布と、ラベルの真の確率分布の距離を表すものである。

  • ディープラーニングの肝は中間層での特徴抽出なので、中間層のユニット数は、最終出力よりも多くしておく必要がある。

github.com

one-hot化

基本的にIMDbと同様の手順だが、今回はラベルが46種類の多クラス分類なので、ラベルもone-hotにする必要がある。 Kerasだとto_categorical一発でいける。

from tensorflow.keras.utils import to_categorical

y_train = to_categorical(train_labels)
y_test = to_categorical(test_labels)

IMDbのデータ変換同様、真面目に書くとこういうやり方になる。

def to_one_hot(labels, dimension=46):
    # (データ数, 次元数(=クラス数))のベクトル
    results = np.zeros((len(labels), dimension))
    # 各行で、該当するラベルの列に1を格納してone-hot化
    for i, label in enumerate(labels):
        results[i, label] = 1.
    return results

y_train = to_one_hot(train_labels)
y_test = to_one_hot(test_labels)

ネットワーク

model = keras.Sequential([
    layers.Dense(64, activation="relu"),
    layers.Dense(64, activation="relu"),
    layers.Dense(46, activation="softmax")
])

最終出力は、合計すると1になる46個の確率値を格納した、46次元ベクトルとなる。

二値分類(最終出力1次元)では中間層のユニット数は16だったが、今回は最終出力を46次元にするので、もっと途中では大きな次元数にしないと情報を拾いきれない。

このネットワークだとval_accuracyがだいたい79%〜81%程度になるのだが、試しに中間層の1つをユニット数4にしてしまうと、val_accuracyは71%程度で止まる。これは、大量の情報を小さな中間層に詰め込もうとして取りこぼしたためといえる。

model.compile(optimizer="rmsprop",
              loss="categorical_crossentropy",
              metrics=["accuracy"])

また、今回は多クラス分類なので、損失関数はcategorical_crossentropyを使う。

この「交差エントロピー」は、学習モデルにによって出力される確率分布と、ラベルの真の確率分布の距離を表すものである。

また、ラベルをone-hot化しないで使う場合は、sparse_categorical_crossentropyを使う。