Pengambilan sampel silang atau cara memeras seperseribu dari kumpulan data

Artikel ini membahas tentang gambar dan klasifikasi. Sebuah studi kecil tentang properti, seperti sentuhan pada potret MNIST (yah, petunjuk dalam memecahkan masalah serupa lainnya).



Ada banyak publikasi di jaringan tentang interpretasi jaringan saraf tertentu dan signifikansi serta kontribusi poin-poin tertentu untuk pembelajaran. Ada banyak karya tentang pencarian kumis, ekor dan bagian lain serta kepentingan dan signifikansinya. Sekarang saya tidak akan mengganti pustakawan dan membuat daftar. Saya hanya akan berbicara tentang eksperimen saya.



Semuanya dimulai dengan video yang luar biasa. Laporkan β€œBagaimana robot berpikir. Penafsiran model ML ” , ditinjau atas saran dari satu orang pintar dan seperti bisnis yang masuk akal lainnya, menimbulkan banyak pertanyaan. Misalnya: - seberapa unik poin-poin utama dari kumpulan data tersebut?



Atau pertanyaan lain: - Ada banyak artikel di jaringan tentang bagaimana mengubah satu titik gambar dapat secara signifikan merusak prediksi jaringan. Izinkan saya mengingatkan Anda bahwa dalam artikel ini kita hanya akan membahas masalah klasifikasi. Seberapa unik poin berbahaya ini? Apakah ada poin seperti itu dalam urutan natural MNIST dan jika ditemukan dan dibuang, akankah akurasi pelatihan jaringan saraf lebih tinggi?



Penulis, mengikuti metode tradisionalnya untuk menyingkirkan semua yang tidak perlu, memutuskan untuk tidak mengganggu kelompok tersebut dan memilih cara yang sederhana, andal dan efektif untuk mempelajari pertanyaan yang diajukan:



sebagai masalah eksperimental, contoh untuk persiapan, pilih MNIST yang sudah dikenal ( yann.lecun.com/exdb/mnist ) dan klasifikasinya.



Sebagai jaringan eksperimental, saya memilih jaringan klasik, direkomendasikan untuk pemula, jaringan teladan dari tim

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



Dan studi itu sendiri memutuskan untuk menjadi sangat sederhana.



Mari latih jaringan dari KERAS dengan kriteria penghentian seperti tidak adanya peningkatan akurasi pada urutan pengujian, yaitu. ajarkan jaringan sampai test_accuracy menjadi jauh lebih besar dari validation_accuracy dan validation_accuracy tidak meningkat selama 15 epoch. Dengan kata lain, jaringan berhenti belajar dan pelatihan ulang dimulai.



Dari dataset MNIST, kita akan membuat 324 dataset baru dengan membuang kumpulan poin dan akan diajarkan oleh jaringan yang sama dalam kondisi yang sama persis dengan bobot awal yang sama.



Mari kita mulai, saya pikir itu benar dan benar untuk meletakkan semua kode, dari baris pertama hingga terakhir. Bahkan jika para pembaca telah melihatnya, jelas berkali-kali.



Kami memuat pustaka dan memuat set data mnist, jika belum dimuat.



Kemudian kami mengubahnya menjadi format 'float32' dan menormalkannya ke kisaran 0 - 1.



Persiapan sudah selesai.



'''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)




Mari kita ingat dalam variabel nama file dan bobot model, serta keakuratan dan hilangnya jaringan kita. Ini tidak ada dalam kode sumber, tetapi diperlukan untuk eksperimen.



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


Jaringan itu sendiri persis sama dengan di

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



Simpan jaringan dan timbangan ke disk. Kami akan menjalankan semua upaya pelatihan kami dengan bobot awal yang sama:



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
_________________________________________________________________


Mari kita mulai melatih mnist asli untuk mendapatkan tolok ukur, efisiensi dasar.



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  


Sekarang mari kita mulai percobaan utama. Kami mengambil pelatihan dari urutan asli semua 60.000 gambar yang ditandai, dan di dalamnya kami mengatur ulang semuanya kecuali persegi 9x9. Mari kita dapatkan 324 urutan percobaan dan bandingkan hasil pelatihan jaringan padanya dengan pelatihan pada urutan aslinya. Kami melatih jaringan yang sama dengan bobot awal yang sama.



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


Tidak masuk akal untuk memposting semua hasil 324 di sini, jika ada yang tertarik, saya dapat mengirimkannya secara pribadi. Perhitungannya memakan waktu beberapa hari, jika ada yang ingin mengulanginya.



Ternyata, jaringan pada kliping 9x9 dapat belajar lebih buruk, yang jelas, tetapi juga lebih baik, yang sama sekali tidak jelas.



Misalnya:



i = 0 j = 14

akurasi 0.9972333312 kerugian 0.0017946947 langkah 450 val_accu 0.9922000170 val_loss 0.0054322388



i = 18, j = 1

akurasi 0.9973166585 kerugian 0.0019487827 langkah 415 val_accu 0.9922000170 val_loss 0.0053000450



Kami membuang pembelajaran dari gambar dengan angka dan semua tulisan tangan pengakuan meningkat bersama kami!



Jelas juga bahwa ada lebih dari satu area khusus untuk meningkatkan kualitas jaringan. Dan bukan dua, keduanya diberikan sebagai contoh.



Hasil percobaan ini dan kesimpulan awal.



  • Setiap kumpulan data alami, saya tidak berpikir bahwa LeCune sengaja mengubah sesuatu, tidak hanya berisi poin yang penting untuk pembelajaran, tetapi juga poin yang mengganggu pembelajaran. Tugas menemukan poin-poin yang "berbahaya" menjadi mendesak, poin-poin itu ada di sana, bahkan jika tidak terlihat.
  • Anda dapat menumpuk dan memadukan tidak hanya di sepanjang kumpulan data, memilih gambar dalam kelompok, tetapi juga di seluruh, memilih area gambar untuk dipisahkan dan kemudian seperti biasa. Dalam hal ini, pendekatan ini meningkatkan kualitas pelatihan, dan ada harapan bahwa dalam tugas serupa, penggunaan penumpukan semacam itu akan menambah kualitas. Dan di kaggle.com yang sama, terkadang beberapa seperseribu (hampir selalu) memungkinkan Anda untuk meningkatkan otoritas dan peringkat Anda secara signifikan.


Terima kasih atas perhatian Anda.



All Articles