クロスサンプリングまたはデータセットから数千分の1を絞り出す方法

この記事は写真と分類についてです。 MNISTの肖像画へのタッチなど、プロパティの小さな研究です(まあ、他の同様の問題を解決するためのヒント)。



特定の神経ネットワークの解釈と、学習に対する特定のポイントの重要性と貢献について、ネットワーク上に多くの出版物があります。ウィスカー、テール、その他のパーツの検索とそれらの重要性と重要性については多くの作品があります。今、私は図書館員を置き換えてリストを作成しません。私の実験についてお話しします。



それはすべて、優れたビデオレポート「ロボットの考え方」から始まりました。 MLモデルの解釈」は、1人の賢い人のアドバイスに基づいてレビューされ、他の賢明なビジネスと同様に、多くの疑問を投げかけました。例:-データセットの重要なポイントはどれくらいユニークですか?



または別の質問:-画像の1​​つのポイントを変更すると、ネットワークの予測が大幅に歪む可能性があることについて、ネットワーク上に多くの記事があります。この記事では、分類の問題のみを検討することを思い出してください。この陰湿な点はどれほどユニークですか? MNISTの自然なシーケンスにそのようなポイントがあり、それらが見つかって破棄された場合、ニューラルネットワークのトレーニング精度は高くなりますか?



著者は、不要なものをすべて取り除くという彼の伝統的な方法に従って、束に干渉しないことを決定し、提起さ



れた質問を研究するためのシンプルで信頼性が高く効果的な方法を選択しました:実験的な問題、準備の例として、おなじみのMNIST(yann.lecun.com/exdb/mnist)とその分類。



実験ネットワークとして、私は初心者にお勧め、古典を選んだ、KERASチームの典型的なネットワーク

github.com/keras-team/keras/blob/master/examples/mnist_cnn.py



そして、私は非常に単純な研究そのものを実施することを決定しました。



テストシーケンスの精度が向上しないなどの停止基準を使用して、KERASからネットワークをトレーニングしてみましょう。test_accuracyがvalidation_accuracyよりも大幅に大きくなり、validation_accuracyが15エポックの間改善されなくなるまで、ネットワークに教えます。言い換えれば、ネットワークは学習を停止し、再トレーニングが開始されました。



MNISTデータセットから、ポイントのグループを破棄して324個の新しいデータセットを作成し、同じ初期重みでまったく同じ条件で同じネットワークを教えます。



始めましょう。最初の行から最後の行まで、すべてのコードをレイアウトするのは正しいと思います。読者が彼に会ったとしても、明らかに何度も。



ライブラリをロードし、mnistデータセットがまだロードされていない場合は、ロードします。



次に、それを「float32」形式に変換し、範囲0に正規化します。-1。



準備は終わりました。



'''Trains a simple convnet on the MNIST dataset.
Gets to 99.25% test accuracy after 12 epochs
(there is still a lot of margin for parameter tuning).
16 seconds per epoch on a GRID K520 GPU.
'''

from __future__ import print_function
import keras
from keras.datasets import mnist
from keras.models import Sequential, load_model
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K
from keras.optimizers import *
from keras.callbacks import EarlyStopping

import numpy as np
import os

num_classes = 10

# input image dimensions
img_rows, img_cols = 28, 28

# the data, shuffled and split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()

if K.image_data_format() == 'channels_first':
    x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
    x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
    input_shape = (1, img_rows, img_cols)
else:
    x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
    x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
    input_shape = (img_rows, img_cols, 1)

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= np.max(x_train)
x_test /= np.max(x_test)

XX_test = np.copy(x_test)
XX_train = np.copy(x_train)
YY_test = np.copy(y_test)
YY_train = np.copy(y_train)


print('x_train shape:', XX_train.shape)
print('x_test shape:', XX_test.shape)




モデルファイルの名前と重み、およびネットワークの精度と損失を変数に覚えておきましょう。これはソースコードにはありませんが、実験には必要です。



f_model = "./data/mnist_cnn_model.h5"
f_weights = "./data/mnist_cnn_weights.h5"
accu_f = 'accuracy'
loss_f = 'binary_crossentropy'


ネットワーク自体は、

github.com / keras-team / keras / blob / master / examples /mnist_cnn.pyとまったく同じです



ネットワークを保存し、ディスクにスケーリングします。すべてのトレーニング試行を同じ初期ウェイトで実行します。



y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

model = Sequential()

model.add(Conv2D(32, kernel_size=(3, 3),
                 activation='relu',
                 input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))

model.compile(loss=[loss_f], optimizer=Adam(lr=1e-4), metrics=[accu_f])
model.summary()

model.save_weights(f_weights)
model.save(f_model)


Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 26, 26, 32)        320       
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 24, 24, 64)        18496     
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 12, 12, 64)        0         
_________________________________________________________________
dropout (Dropout)            (None, 12, 12, 64)        0         
_________________________________________________________________
flatten (Flatten)            (None, 9216)              0         
_________________________________________________________________
dense (Dense)                (None, 128)               1179776   
_________________________________________________________________
dropout_1 (Dropout)          (None, 128)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 10)                1290      
=================================================================
Total params: 1,199,882
Trainable params: 1,199,882
Non-trainable params: 0
_________________________________________________________________


ベンチマークである基本的な効率を得るために、元のmnistのトレーニングを開始しましょう。



x_test = np.copy(XX_test)
x_train = np.copy(XX_train)
s0 = 0

if os.path.isfile(f_model):
    model = load_model(f_model)
    model.load_weights(f_weights, by_name=False)

    step = 0
    while True:
        
        fit = model.fit(x_train, y_train,
                  batch_size=batch_size,
                  epochs=1,
                  verbose=0,
                  validation_data=(x_test, y_test)
                )
        
        current_accu = fit.history[accu_f][0]
        current_loss = fit.history['loss'][0]
        val_accu = fit.history['val_'+accu_f][0]
        val_loss = fit.history['val_loss'][0]
        print("\x1b[2K","accuracy {0:12.10f} loss {1:12.10f} step {2:5d} val_accu {3:12.10f} val_loss {4:12.10f}  ".\
                          format(current_accu, current_loss, step, val_accu, val_loss), end="\r")
    
        step += 1
        if val_accu > max_accu:
            s0 = 0
            max_accu = val_accu
        else:
            s0 += 1
        if current_accu * 0.995 > val_accu and s0 > 15:
            break
else:
    print("model not found ")

accuracy 0.9967333078 loss 0.0019656278 step   405 val_accu 0.9916999936 val_loss 0.0054226643  


それでは、メインの実験を始めましょう。元のシーケンスから60,000枚のマークアップされたすべての写真をトレーニングし、9x9の正方形を除くすべてをリセットします。324の実験シーケンスを取得し、それらのネットワークトレーニングの結果を元のシーケンスのトレーニングと比較してみましょう。同じネットワークを同じ初期重みでトレーニングします。



batch_size = 5000
s0 = 0
max_accu = 0.

for i in range(28 - 9):
    for j in range(28 - 9):
        print("\ni= ", i, "  j= ",j)
        x_test = np.copy(XX_test)
        x_train = np.copy(XX_train)

        x_train[:,:i,:j,:] = 0.
        x_test [:,:i,:j,:] = 0.

        x_train[:,i+9:,j+9:,:] = 0.
        x_test [:,i+9:,j+9:,:] = 0.

        if os.path.isfile(f_model):
            model = load_model(f_model)
            model.load_weights(f_weights, by_name=False)
        else:
            print("model not found ")
            break

        step = 0
        while True:
            
            fit = model.fit(x_train, y_train,
                      batch_size=batch_size,
                      epochs=1,
                      verbose=0,
                      validation_data=(x_test, y_test)
                    )
            
            current_accu = fit.history[accu_f][0]
            current_loss = fit.history['loss'][0]
            val_accu = fit.history['val_'+accu_f][0]
            val_loss = fit.history['val_loss'][0]
            print("\x1b[2K","accuracy {0:12.10f} loss {1:12.10f} step {2:5d} val_accu {3:12.10f} val_loss {4:12.10f}  ".\
   format(current_accu, current_loss, step, val_accu, val_loss), end="\r")
        
            step += 1
            if val_accu > max_accu:
                s0 = 0
                max_accu = val_accu
            else:
                s0 += 1
            if current_accu * 0.995 > val_accu and s0 > 15:
                break


ここに324件すべての結果を投稿するのは意味がありません。興味があれば、個人的に送信できます。誰かがそれを繰り返したい場合、計算には数日かかります。



結局のところ、9x9クリッピングのネットワークは、明らかに悪いことを学習する可能性がありますが、まったく明らかではないこともあります。



例:



i = 0 j = 14

精度0.9972333312損失0.0017946947ステップ450val_accu 0.9922000170 val_loss 0.0054322388



i = 18 j = 1

精度0.9973166585損失0.0019487827ステップ415val_accu 0.9922000170 val_loss 0.0053000450



写真から品質を捨て、手書きの9ですべてを学習します認知度は向上しています!



ネットワーク品質を改善するためのそのような特別な領域が複数あることも明らかです。 2つではなく、これら2つを例として示します。



この実験の結果と予備的な結論。



  • LeCuneが意図的に何かを歪めたとは思わない自然なデータセットには、学習に不可欠なポイントだけでなく、学習を妨げるポイントも含まれています。「有害な」ポイントを見つける作業は緊急になり、たとえ見えなくても存在します。
  • データセットに沿ってスタックしてブレンドするだけでなく、グループで画像を選択するだけでなく、分割する画像の領域を選択して、通常どおりに画像を選択することもできます。この場合、そのようなアプローチはトレーニングの質を向上させ、同様のタスクでそのような積み重ねを使用することで質が向上することが期待されます。また、同じkaggle.comで、数万分の1が(ほとんどの場合)権限と評価を大幅に上げることができる場合があります。


清聴ありがとうございました。



All Articles