MNIST手書き数字を座標に変換して

背景

3D点群データの機械学習をしたかったのですが、良いデータセットが見つからなかったので代わりに2Dで自作しました。

MNISTの手書き数字画像を座標に変換しました。

MNISTの画像は黒いピクセルの数が約30~250/784pixelと幅広いため、座標の点数を揃えるのに苦労しました。

 

検証1. ピクセル→座標変換方法(座標点数を揃える)

3パターン試しました。

ピクセルの重複なし、全データ使用

・座標点数:30

・データ数:Train=60,000、Test=10,000
30epoch
Train - accuracy: 0.6213
Test - accuracy: 0.4842
500epoch
Train - accuracy: 0.7782
Test - accuracy: 0.4983

ピクセルの重複なし、一部データ削除

・座標点数:50

・データ数:Train=59,932、Test=9,990

30epoch
Train - accuracy: 0.5809
Test - accuracy: 0.3553
500epoch

Train - accuracy: 0.7790
Test - accuracy: 0.3891

ピクセルの重複あり、全データ使用

過学習が起きました。

・座標点数:200

・データ数:Train=60,000、Test=10,000
30epoch
Train - accuracy: 0.8431
Test - accuracy: 0.2675

検証1の結論

①を採用します。

 

検証2. 正規化方法

検証1のとき、入力データ(座標)を(0~1)→(-0.5~0.5)にしたら、なぜかTrain正解率が大幅に改善しました。

そこで正規化方法を以下3つを比較しました(いずれも30epoch)。

①最小値0、最大値1に正規化

Train - accuracy: 0.3138
Test - accuracy: 0.2729

②最小値-0.5、最大値0.5に正規化

Train - accuracy: 0.6149
Test - accuracy: 0.4680

③平均値0、標準偏差1に標準化

Train - accuracy: 0.6029
Test - accuracy: 0.4675

検証2の結論

②③が良い。

①がダメな理由わかる方いたら教えてください・・・

付録

画像を座標に変換するコード例

mnist = tf.keras.datasets.mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()
size=30 #調整する
length=
x_train_choice=

y_train_choice=
x_test_choice=

y_test_choice=[]
for i in range(len(x_train)):
    x = np.where(x_train[i]>0)
    length.append(len(x[0]))
    if len(x[0]) >= size:
        index=np.random.choice(range(len(x[0])), size=size, replace=False) #replace=Falseだと重複なし
        X=np.array(x)[:,index]
        x_train_choice.append(X)
        y_train_choice.append(y_train[i])

x_train_np=np.array(x_train_choice)
y_train_np=np.array(y_train_choice)