Lapisan Normalisasi Batch Keras merusak Intelegensi Data PlatoBlockchain. Pencarian Vertikal. Ai.

Lapisan Normalisasi Batch Keras rusak

UPDATE: Sayangnya Permintaan Tarik saya untuk Keras yang mengubah perilaku lapisan Normalisasi Batch tidak diterima. Anda dapat membaca detailnya di sini. Bagi Anda yang cukup berani untuk mengotak-atik implementasi kustom, Anda dapat menemukan kodenya cabang saya. Saya mungkin mempertahankannya dan menggabungkannya dengan versi stabil terbaru Keras (2.1.6, 2.2.2 dan 2.2.4) selama saya menggunakannya tetapi tidak ada janji.

Kebanyakan orang yang bekerja di Deep Learning telah menggunakan atau mendengar Keras. Bagi Anda yang belum, itu adalah perpustakaan yang bagus yang mengabstraksi kerangka Deep Learning yang mendasarinya seperti TensorFlow, Theano dan CNTK dan menyediakan API tingkat tinggi untuk pelatihan JST. Mudah digunakan, memungkinkan pembuatan prototipe cepat dan memiliki komunitas aktif yang ramah. Saya sudah sering menggunakannya dan berkontribusi pada proyek secara berkala selama beberapa waktu dan saya merekomendasikannya kepada siapa saja yang ingin mengerjakan Deep Learning.

Meskipun Keras membuat hidup saya lebih mudah, beberapa kali saya digigit oleh perilaku aneh lapisan Normalisasi Batch. Perilaku standarnya telah berubah dari waktu ke waktu, namun tetap menyebabkan masalah bagi banyak pengguna dan akibatnya ada beberapa yang terkait masalah terbuka pada Github. Dalam posting blog ini, saya akan mencoba membuat kasus untuk mengapa lapisan Keras 'BatchNormalisasi tidak bermain bagus dengan Transfer Learning, saya akan memberikan kode yang memperbaiki masalah dan saya akan memberikan contoh dengan hasil dari tambalan.

Pada subbagian di bawah ini, saya memberikan pengantar tentang bagaimana Transfer Learning digunakan dalam Deep Learning, apa itu layer Normalisasi Batch, cara kerja learningining_phase dan bagaimana Keras mengubah perilaku BN dari waktu ke waktu. Jika Anda sudah tahu ini, Anda bisa langsung melompat ke bagian 2 dengan aman.

1.1 Menggunakan Transfer Belajar sangat penting untuk Pembelajaran Jauh

Salah satu alasan mengapa Deep Learning dikritik di masa lalu adalah karena itu membutuhkan terlalu banyak data. Ini tidak selalu benar; ada beberapa teknik untuk mengatasi keterbatasan ini, salah satunya adalah Transfer Belajar.

Asumsikan bahwa Anda sedang mengerjakan aplikasi Penglihatan Komputer dan Anda ingin membuat classifier yang membedakan Kucing dari Anjing. Anda sebenarnya tidak membutuhkan jutaan gambar kucing / anjing untuk melatih modelnya. Sebagai gantinya, Anda dapat menggunakan pengklasifikasi pra-terlatih dan menyempurnakan konvolusi teratas dengan lebih sedikit data. Gagasan di balik itu adalah bahwa karena model pra-terlatih cocok pada gambar, konvolusi bawah dapat mengenali fitur seperti garis, tepi dan pola berguna lainnya yang berarti Anda dapat menggunakan bobotnya baik sebagai nilai inisialisasi yang baik atau sebagian melatih ulang jaringan dengan data Anda .
Lapisan Normalisasi Batch Keras merusak Intelegensi Data PlatoBlockchain. Pencarian Vertikal. Ai.
Keras hadir dengan beberapa model yang sudah dilatih sebelumnya dan contoh-contoh yang mudah digunakan tentang cara menyempurnakan model. Anda dapat membaca lebih lanjut di dokumentasi.

1.2 Apa lapisan Normalisasi Batch?

Lapisan Normalisasi Batch diperkenalkan pada tahun 2014 oleh Ioffe dan Szegedy. Ini mengatasi masalah gradien menghilang dengan standarisasi output dari lapisan sebelumnya, itu mempercepat pelatihan dengan mengurangi jumlah iterasi yang diperlukan dan memungkinkan pelatihan jaringan saraf yang lebih dalam. Menjelaskan dengan tepat cara kerjanya berada di luar cakupan posting ini tetapi saya sangat menyarankan Anda untuk membaca kertas asli. Penjelasan yang terlalu disederhanakan adalah bahwa ia meningkatkan input dengan mengurangi rata-rata dan dengan membagi dengan standar deviasi; itu juga dapat belajar untuk membatalkan transformasi jika perlu.
Lapisan Normalisasi Batch Keras merusak Intelegensi Data PlatoBlockchain. Pencarian Vertikal. Ai.

1.3 Apa learning_phase dalam Keras?

Beberapa lapisan beroperasi secara berbeda selama mode pelatihan dan inferensi. Contoh yang paling menonjol adalah Normalisasi Batch dan lapisan Dropout. Dalam kasus BN, selama pelatihan kami menggunakan mean dan varians dari batch mini untuk mengubah skala input. Di sisi lain, selama inferensi kami menggunakan moving average dan varians yang diperkirakan selama pelatihan.

Keras tahu dalam mode mana untuk menjalankan karena memiliki mekanisme built-in yang disebut fase_belajar. Fase pembelajaran mengontrol apakah jaringan dalam mode kereta atau tes. Jika tidak diatur secara manual oleh pengguna, selama fit () jaringan berjalan dengan learning_phase = 1 (mode kereta). Saat menghasilkan prediksi (misalnya saat kita memanggil metode predict () & evalu () atau pada langkah validasi fit ()), jaringan berjalan dengan learning_phase = 0 (mode pengujian). Meskipun tidak disarankan, pengguna juga dapat mengubah learning_phase secara statis ke nilai tertentu, tetapi hal ini perlu dilakukan sebelum model atau tensor apa pun ditambahkan ke grafik. Jika learning_phase disetel secara statis, Keras akan dikunci ke mode mana pun yang dipilih pengguna.

1.4 Bagaimana Keras menerapkan Normalisasi Batch dari waktu ke waktu?

Keras telah mengubah perilaku Normalisasi Batch beberapa kali tetapi pembaruan signifikan terbaru terjadi di Keras 2.1.3. Sebelum v2.1.3 ketika layer BN dibekukan (trainable = False) ia terus memperbarui statistik batch-nya, sesuatu yang menyebabkan sakit kepala epik bagi para penggunanya.

Ini bukan hanya kebijakan aneh, itu sebenarnya salah. Bayangkan ada lapisan BN di antara konvolusi; jika layer dibekukan tidak ada perubahan yang terjadi padanya. Jika kami memperbarui sebagian bobotnya dan lapisan berikutnya juga dibekukan, mereka tidak akan pernah mendapatkan kesempatan untuk menyesuaikan diri dengan pembaruan statistik mini-batch yang mengarah ke kesalahan yang lebih tinggi. Untungnya mulai dari versi 2.1.3, ketika layer BN dibekukan, tidak lagi memperbarui statistiknya. Tetapi apakah itu cukup? Tidak jika Anda menggunakan Transfer Learning.

Di bawah ini saya jelaskan apa masalahnya dan saya membuat sketsa implementasi teknis untuk menyelesaikannya. Saya juga memberikan beberapa contoh untuk menunjukkan efek pada akurasi model sebelum dan sesudah tambalan diterapkan.

2.1 Deskripsi teknis masalah

Masalah dengan implementasi Keras saat ini adalah ketika layer BN dibekukan, ia terus menggunakan statistik mini-batch selama pelatihan. Saya percaya pendekatan yang lebih baik ketika BN dibekukan adalah dengan menggunakan mean dan varian yang dipelajari selama pelatihan. Mengapa? Untuk alasan yang sama mengapa statistik mini-batch tidak boleh diperbarui ketika lapisan dibekukan: itu dapat menyebabkan hasil yang buruk karena lapisan berikutnya tidak dilatih dengan benar.

Asumsikan Anda sedang membangun model Visi Komputer tetapi Anda tidak memiliki cukup data, jadi Anda memutuskan untuk menggunakan salah satu CNN Keras yang telah dilatih sebelumnya dan menyempurnakannya. Sayangnya, dengan melakukan itu Anda tidak mendapatkan jaminan bahwa rata-rata dan varian dari dataset baru Anda di dalam layer BN akan serupa dengan yang ada pada dataset asli. Ingatlah bahwa saat ini, selama pelatihan jaringan Anda akan selalu menggunakan statistik mini-batch baik layer BN dibekukan atau tidak; juga selama inferensi Anda akan menggunakan statistik yang dipelajari sebelumnya dari lapisan BN beku. Akibatnya, jika Anda menyempurnakan lapisan atas, bobotnya akan disesuaikan dengan rata-rata / varian yang baru Himpunan data. Namun demikian, selama inferensi mereka akan menerima data yang diskalakan berbeda karena mean / varians dari asli dataset akan digunakan.
Lapisan Normalisasi Batch Keras merusak Intelegensi Data PlatoBlockchain. Pencarian Vertikal. Ai.
Di atas saya memberikan arsitektur sederhana (dan tidak realistis) untuk tujuan demonstrasi. Mari kita asumsikan bahwa kita menyempurnakan model dari Konvolusi k + 1 hingga bagian atas jaringan (sisi kanan) dan kami tetap membekukan bagian bawah (sisi kiri). Selama pelatihan, semua layer BN dari 1 hingga k akan menggunakan mean / varians dari data pelatihan Anda. Ini akan memiliki efek negatif pada ReLU beku jika rata-rata dan varians pada masing-masing BN tidak mendekati yang dipelajari selama pra-pelatihan. Ini juga akan menyebabkan sisa jaringan (dari CONV k + 1 dan yang lebih baru) dilatih dengan input yang memiliki skala berbeda dibandingkan dengan apa yang akan diterima selama inferensi. Selama pelatihan jaringan Anda dapat beradaptasi dengan perubahan-perubahan ini, namun begitu Anda beralih ke mode prediksi, Keras akan menggunakan statistik standardisasi yang berbeda, sesuatu yang akan mempercepat distribusi input dari lapisan berikutnya yang mengarah ke hasil yang buruk.

2.2 Bagaimana Anda bisa mendeteksi jika Anda terpengaruh?

Salah satu cara untuk mendeteksinya adalah dengan mengatur secara statis fase belajar Keras ke 1 (mode kereta) dan ke 0 (mode uji) dan mengevaluasi model Anda di setiap kasus. Jika ada perbedaan signifikan dalam akurasi pada dataset yang sama, Anda dipengaruhi oleh masalah tersebut. Perlu ditunjukkan bahwa, karena cara mekanisme learning_phase diimplementasikan dalam Keras, biasanya tidak disarankan untuk mengacaukannya. Perubahan pada learning_phase tidak akan berpengaruh pada model yang sudah dikompilasi dan digunakan; seperti yang Anda lihat pada contoh pada subbagian berikutnya, cara terbaik untuk melakukan ini adalah mulai dengan sesi bersih dan ubah fase learning_ sebelum tensor didefinisikan dalam grafik.

Cara lain untuk mendeteksi masalah saat bekerja dengan pengklasifikasi biner adalah untuk memeriksa keakuratan dan AUC. Jika akurasinya mendekati 50% tetapi AUC mendekati 1 (dan juga Anda mengamati perbedaan antara mode kereta / tes pada dataset yang sama), bisa jadi probabilitasnya di luar skala karena statistik BN. Demikian pula, untuk regresi Anda dapat menggunakan korelasi MSE dan Spearman untuk mendeteksinya.

2.3 Bagaimana cara memperbaikinya?

Saya percaya bahwa masalahnya dapat diperbaiki jika lapisan BN beku sebenarnya hanya itu: terkunci secara permanen dalam mode uji. Dari segi implementasi, bendera yang dapat dilatih harus menjadi bagian dari grafik komputasi dan perilaku BN perlu bergantung tidak hanya pada fase learning_ tetapi juga pada nilai properti yang bisa dilatih. Anda dapat menemukan detail implementasi saya di Github.

Dengan menerapkan perbaikan di atas, ketika lapisan BN dibekukan tidak akan lagi menggunakan statistik mini-batch melainkan menggunakan yang dipelajari selama pelatihan. Akibatnya, tidak akan ada perbedaan antara mode pelatihan dan tes yang mengarah pada peningkatan akurasi. Jelas ketika layer BN tidak dibekukan, itu akan terus menggunakan statistik mini-batch selama pelatihan.

2.4 Menilai efek tambalan

Meskipun saya menulis implementasi di atas baru-baru ini, ide di baliknya sangat diuji pada masalah-masalah dunia nyata menggunakan berbagai solusi yang memiliki efek yang sama. Misalnya, perbedaan antara mode pelatihan dan pengujian dan dapat dihindari dengan memisahkan jaringan menjadi dua bagian (beku dan tidak beku) dan melakukan pelatihan cache (melewati data melalui model beku sekali dan kemudian menggunakannya untuk melatih jaringan yang tidak beku). Namun demikian, karena "percayalah, saya sudah melakukan ini sebelumnya" biasanya tidak berbobot, di bawah ini saya memberikan beberapa contoh yang menunjukkan efek dari implementasi baru dalam praktek.

Berikut ini beberapa poin penting tentang percobaan:

  1. Saya akan menggunakan sejumlah kecil data untuk sengaja overfit model dan saya akan melatih & memvalidasi model pada dataset yang sama. Dengan melakukan itu, saya mengharapkan akurasi yang hampir sempurna dan performa yang identik pada dataset train / validation.
  2. Jika selama validasi saya mendapatkan akurasi yang jauh lebih rendah pada dataset yang sama, saya akan memiliki indikasi yang jelas bahwa kebijakan BN saat ini mempengaruhi secara negatif kinerja model selama inferensi.
  3. Setiap preprocessing akan dilakukan di luar Generator. Ini dilakukan untuk mengatasi bug yang diperkenalkan di v2.1.5 (saat ini diperbaiki pada v2.1.6 mendatang dan master terbaru).
  4. Kami akan memaksa Keras untuk menggunakan fase pembelajaran yang berbeda selama evaluasi. Jika kita menemukan perbedaan antara akurasi yang dilaporkan, kita akan tahu bahwa kita dipengaruhi oleh kebijakan BN saat ini.

Kode percobaan ditunjukkan di bawah ini:

import numpy as np
from keras.datasets import cifar10
from scipy.misc import imresize

from keras.preprocessing.image import ImageDataGenerator
from keras.applications.resnet50 import ResNet50, preprocess_input
from keras.models import Model, load_model
from keras.layers import Dense, Flatten
from keras import backend as K


seed = 42
epochs = 10
records_per_class = 100

# We take only 2 classes from CIFAR10 and a very small sample to intentionally overfit the model.
# We will also use the same data for train/test and expect that Keras will give the same accuracy.
(x, y), _ = cifar10.load_data()

def filter_resize(category):
   # We do the preprocessing here instead in the Generator to get around a bug on Keras 2.1.5.
   return [preprocess_input(imresize(img, (224,224)).astype('float')) for img in x[y.flatten()==category][:records_per_class]]

x = np.stack(filter_resize(3)+filter_resize(5))
records_per_class = x.shape[0] // 2
y = np.array([[1,0]]*records_per_class + [[0,1]]*records_per_class)


# We will use a pre-trained model and finetune the top layers.
np.random.seed(seed)
base_model = ResNet50(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
l = Flatten()(base_model.output)
predictions = Dense(2, activation='softmax')(l)
model = Model(inputs=base_model.input, outputs=predictions)

for layer in model.layers[:140]:
   layer.trainable = False

for layer in model.layers[140:]:
   layer.trainable = True

model.compile(optimizer='sgd', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit_generator(ImageDataGenerator().flow(x, y, seed=42), epochs=epochs, validation_data=ImageDataGenerator().flow(x, y, seed=42))

# Store the model on disk
model.save('tmp.h5')


# In every test we will clear the session and reload the model to force Learning_Phase values to change.
print('DYNAMIC LEARNING_PHASE')
K.clear_session()
model = load_model('tmp.h5')
# This accuracy should match exactly the one of the validation set on the last iteration.
print(model.evaluate_generator(ImageDataGenerator().flow(x, y, seed=42)))


print('STATIC LEARNING_PHASE = 0')
K.clear_session()
K.set_learning_phase(0)
model = load_model('tmp.h5')
# Again the accuracy should match the above.
print(model.evaluate_generator(ImageDataGenerator().flow(x, y, seed=42)))


print('STATIC LEARNING_PHASE = 1')
K.clear_session()
K.set_learning_phase(1)
model = load_model('tmp.h5')
# The accuracy will be close to the one of the training set on the last iteration.
print(model.evaluate_generator(ImageDataGenerator().flow(x, y, seed=42)))

Mari kita periksa hasilnya di Keras v2.1.5:

Epoch 1/10
1/7 [===>..........................] - ETA: 25s - loss: 0.8751 - acc: 0.5312
2/7 [=======>......................] - ETA: 11s - loss: 0.8594 - acc: 0.4531
3/7 [===========>..................] - ETA: 7s - loss: 0.8398 - acc: 0.4688 
4/7 [================>.............] - ETA: 4s - loss: 0.8467 - acc: 0.4844
5/7 [====================>.........] - ETA: 2s - loss: 0.7904 - acc: 0.5437
6/7 [========================>.....] - ETA: 1s - loss: 0.7593 - acc: 0.5625
7/7 [==============================] - 12s 2s/step - loss: 0.7536 - acc: 0.5744 - val_loss: 0.6526 - val_acc: 0.6650

Epoch 2/10
1/7 [===>..........................] - ETA: 4s - loss: 0.3881 - acc: 0.8125
2/7 [=======>......................] - ETA: 3s - loss: 0.3945 - acc: 0.7812
3/7 [===========>..................] - ETA: 2s - loss: 0.3956 - acc: 0.8229
4/7 [================>.............] - ETA: 1s - loss: 0.4223 - acc: 0.8047
5/7 [====================>.........] - ETA: 1s - loss: 0.4483 - acc: 0.7812
6/7 [========================>.....] - ETA: 0s - loss: 0.4325 - acc: 0.7917
7/7 [==============================] - 8s 1s/step - loss: 0.4095 - acc: 0.8089 - val_loss: 0.4722 - val_acc: 0.7700

Epoch 3/10
1/7 [===>..........................] - ETA: 4s - loss: 0.2246 - acc: 0.9375
2/7 [=======>......................] - ETA: 3s - loss: 0.2167 - acc: 0.9375
3/7 [===========>..................] - ETA: 2s - loss: 0.2260 - acc: 0.9479
4/7 [================>.............] - ETA: 2s - loss: 0.2179 - acc: 0.9375
5/7 [====================>.........] - ETA: 1s - loss: 0.2356 - acc: 0.9313
6/7 [========================>.....] - ETA: 0s - loss: 0.2392 - acc: 0.9427
7/7 [==============================] - 8s 1s/step - loss: 0.2288 - acc: 0.9456 - val_loss: 0.4282 - val_acc: 0.7800

Epoch 4/10
1/7 [===>..........................] - ETA: 4s - loss: 0.2183 - acc: 0.9688
2/7 [=======>......................] - ETA: 3s - loss: 0.1899 - acc: 0.9844
3/7 [===========>..................] - ETA: 2s - loss: 0.1887 - acc: 0.9792
4/7 [================>.............] - ETA: 1s - loss: 0.1995 - acc: 0.9531
5/7 [====================>.........] - ETA: 1s - loss: 0.1932 - acc: 0.9625
6/7 [========================>.....] - ETA: 0s - loss: 0.1819 - acc: 0.9688
7/7 [==============================] - 8s 1s/step - loss: 0.1743 - acc: 0.9747 - val_loss: 0.3778 - val_acc: 0.8400

Epoch 5/10
1/7 [===>..........................] - ETA: 3s - loss: 0.0973 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0828 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0851 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0897 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0928 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0936 - acc: 1.0000
7/7 [==============================] - 8s 1s/step - loss: 0.1337 - acc: 0.9838 - val_loss: 0.3916 - val_acc: 0.8100

Epoch 6/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0747 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0852 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0812 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0831 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0779 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0766 - acc: 1.0000
7/7 [==============================] - 8s 1s/step - loss: 0.0813 - acc: 1.0000 - val_loss: 0.3637 - val_acc: 0.8550

Epoch 7/10
1/7 [===>..........................] - ETA: 1s - loss: 0.2478 - acc: 0.8750
2/7 [=======>......................] - ETA: 2s - loss: 0.1966 - acc: 0.9375
3/7 [===========>..................] - ETA: 2s - loss: 0.1528 - acc: 0.9583
4/7 [================>.............] - ETA: 1s - loss: 0.1300 - acc: 0.9688
5/7 [====================>.........] - ETA: 1s - loss: 0.1193 - acc: 0.9750
6/7 [========================>.....] - ETA: 0s - loss: 0.1196 - acc: 0.9792
7/7 [==============================] - 8s 1s/step - loss: 0.1084 - acc: 0.9838 - val_loss: 0.3546 - val_acc: 0.8600

Epoch 8/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0539 - acc: 1.0000
2/7 [=======>......................] - ETA: 2s - loss: 0.0900 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0815 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0740 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0700 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0701 - acc: 1.0000
7/7 [==============================] - 8s 1s/step - loss: 0.0695 - acc: 1.0000 - val_loss: 0.3269 - val_acc: 0.8600

Epoch 9/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0306 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0377 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0898 - acc: 0.9583
4/7 [================>.............] - ETA: 1s - loss: 0.0773 - acc: 0.9688
5/7 [====================>.........] - ETA: 1s - loss: 0.0742 - acc: 0.9750
6/7 [========================>.....] - ETA: 0s - loss: 0.0708 - acc: 0.9792
7/7 [==============================] - 8s 1s/step - loss: 0.0659 - acc: 0.9838 - val_loss: 0.3604 - val_acc: 0.8600

Epoch 10/10
1/7 [===>..........................] - ETA: 3s - loss: 0.0354 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0381 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0354 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0828 - acc: 0.9688
5/7 [====================>.........] - ETA: 1s - loss: 0.0791 - acc: 0.9750
6/7 [========================>.....] - ETA: 0s - loss: 0.0794 - acc: 0.9792
7/7 [==============================] - 8s 1s/step - loss: 0.0704 - acc: 0.9838 - val_loss: 0.3615 - val_acc: 0.8600

DYNAMIC LEARNING_PHASE
[0.3614931714534759, 0.86]

STATIC LEARNING_PHASE = 0
[0.3614931714534759, 0.86]

STATIC LEARNING_PHASE = 1
[0.025861846953630446, 1.0]

Seperti yang dapat kita lihat di atas, selama pelatihan model ini mempelajari data dengan sangat baik dan mencapai ketepatan pelatihan yang hampir sempurna. Masih di akhir setiap iterasi, saat mengevaluasi model pada dataset yang sama, kami mendapatkan perbedaan yang signifikan dalam hal kehilangan dan akurasi. Perhatikan bahwa kita seharusnya tidak mendapatkan ini; kami telah melengkapi secara sengaja model pada dataset tertentu dan dataset pelatihan / validasi identik.

Setelah pelatihan selesai, kami mengevaluasi model menggunakan 3 konfigurasi fase_belajar yang berbeda: Dinamis, Statis = 0 (mode pengujian) dan Statis = 1 (mode pelatihan). Seperti yang dapat kita lihat, dua konfigurasi pertama akan memberikan hasil yang identik dalam hal kerugian dan akurasi dan nilainya sesuai dengan akurasi model yang dilaporkan pada set validasi pada iterasi terakhir. Namun demikian, begitu kami beralih ke mode pelatihan, kami mengamati perbedaan besar (peningkatan). Kenapa begitu? Seperti yang kami katakan sebelumnya, bobot jaringan disetel dengan harapan menerima data yang diskalakan dengan mean / varian dari data pelatihan. Sayangnya, statistik tersebut berbeda dari yang disimpan di lapisan BN. Sejak lapisan BN dibekukan, statistik ini tidak pernah diperbarui. Perbedaan antara nilai statistik BN ini menyebabkan penurunan akurasi selama inferensi.

Mari kita lihat apa yang terjadi setelah kita menerapkan tambalan:

Epoch 1/10
1/7 [===>..........................] - ETA: 26s - loss: 0.9992 - acc: 0.4375
2/7 [=======>......................] - ETA: 12s - loss: 1.0534 - acc: 0.4375
3/7 [===========>..................] - ETA: 7s - loss: 1.0592 - acc: 0.4479 
4/7 [================>.............] - ETA: 4s - loss: 0.9618 - acc: 0.5000
5/7 [====================>.........] - ETA: 2s - loss: 0.8933 - acc: 0.5250
6/7 [========================>.....] - ETA: 1s - loss: 0.8638 - acc: 0.5417
7/7 [==============================] - 13s 2s/step - loss: 0.8357 - acc: 0.5570 - val_loss: 0.2414 - val_acc: 0.9450

Epoch 2/10
1/7 [===>..........................] - ETA: 4s - loss: 0.2331 - acc: 0.9688
2/7 [=======>......................] - ETA: 2s - loss: 0.3308 - acc: 0.8594
3/7 [===========>..................] - ETA: 2s - loss: 0.3986 - acc: 0.8125
4/7 [================>.............] - ETA: 1s - loss: 0.3721 - acc: 0.8281
5/7 [====================>.........] - ETA: 1s - loss: 0.3449 - acc: 0.8438
6/7 [========================>.....] - ETA: 0s - loss: 0.3168 - acc: 0.8646
7/7 [==============================] - 9s 1s/step - loss: 0.3165 - acc: 0.8633 - val_loss: 0.1167 - val_acc: 0.9950

Epoch 3/10
1/7 [===>..........................] - ETA: 1s - loss: 0.2457 - acc: 1.0000
2/7 [=======>......................] - ETA: 2s - loss: 0.2592 - acc: 0.9688
3/7 [===========>..................] - ETA: 2s - loss: 0.2173 - acc: 0.9688
4/7 [================>.............] - ETA: 1s - loss: 0.2122 - acc: 0.9688
5/7 [====================>.........] - ETA: 1s - loss: 0.2003 - acc: 0.9688
6/7 [========================>.....] - ETA: 0s - loss: 0.1896 - acc: 0.9740
7/7 [==============================] - 9s 1s/step - loss: 0.1835 - acc: 0.9773 - val_loss: 0.0678 - val_acc: 1.0000

Epoch 4/10
1/7 [===>..........................] - ETA: 1s - loss: 0.2051 - acc: 1.0000
2/7 [=======>......................] - ETA: 2s - loss: 0.1652 - acc: 0.9844
3/7 [===========>..................] - ETA: 2s - loss: 0.1423 - acc: 0.9896
4/7 [================>.............] - ETA: 1s - loss: 0.1289 - acc: 0.9922
5/7 [====================>.........] - ETA: 1s - loss: 0.1225 - acc: 0.9938
6/7 [========================>.....] - ETA: 0s - loss: 0.1149 - acc: 0.9948
7/7 [==============================] - 9s 1s/step - loss: 0.1060 - acc: 0.9955 - val_loss: 0.0455 - val_acc: 1.0000

Epoch 5/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0769 - acc: 1.0000
2/7 [=======>......................] - ETA: 2s - loss: 0.0846 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0797 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0736 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0914 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0858 - acc: 1.0000
7/7 [==============================] - 9s 1s/step - loss: 0.0808 - acc: 1.0000 - val_loss: 0.0346 - val_acc: 1.0000

Epoch 6/10
1/7 [===>..........................] - ETA: 1s - loss: 0.1267 - acc: 1.0000
2/7 [=======>......................] - ETA: 2s - loss: 0.1039 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0893 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0780 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0758 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0789 - acc: 1.0000
7/7 [==============================] - 9s 1s/step - loss: 0.0738 - acc: 1.0000 - val_loss: 0.0248 - val_acc: 1.0000

Epoch 7/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0344 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0385 - acc: 1.0000
3/7 [===========>..................] - ETA: 3s - loss: 0.0467 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0445 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0446 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0429 - acc: 1.0000
7/7 [==============================] - 9s 1s/step - loss: 0.0421 - acc: 1.0000 - val_loss: 0.0202 - val_acc: 1.0000

Epoch 8/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0319 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0300 - acc: 1.0000
3/7 [===========>..................] - ETA: 3s - loss: 0.0320 - acc: 1.0000
4/7 [================>.............] - ETA: 2s - loss: 0.0307 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0303 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0291 - acc: 1.0000
7/7 [==============================] - 9s 1s/step - loss: 0.0358 - acc: 1.0000 - val_loss: 0.0167 - val_acc: 1.0000

Epoch 9/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0246 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0255 - acc: 1.0000
3/7 [===========>..................] - ETA: 3s - loss: 0.0258 - acc: 1.0000
4/7 [================>.............] - ETA: 2s - loss: 0.0250 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0252 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0260 - acc: 1.0000
7/7 [==============================] - 9s 1s/step - loss: 0.0327 - acc: 1.0000 - val_loss: 0.0143 - val_acc: 1.0000

Epoch 10/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0251 - acc: 1.0000
2/7 [=======>......................] - ETA: 2s - loss: 0.0228 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0217 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0249 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0244 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0239 - acc: 1.0000
7/7 [==============================] - 9s 1s/step - loss: 0.0290 - acc: 1.0000 - val_loss: 0.0127 - val_acc: 1.0000

DYNAMIC LEARNING_PHASE
[0.012697912137955427, 1.0]

STATIC LEARNING_PHASE = 0
[0.012697912137955427, 1.0]

STATIC LEARNING_PHASE = 1
[0.01744014158844948, 1.0]

Pertama-tama, kami mengamati bahwa jaringan menyatu secara signifikan lebih cepat dan mencapai akurasi sempurna. Kami juga melihat bahwa tidak ada lagi perbedaan dalam hal akurasi ketika kami beralih di antara nilai learning_phase yang berbeda.

2.5 Bagaimana kinerja patch pada dataset nyata?

Jadi bagaimana kinerja patch pada percobaan yang lebih realistis? Mari kita gunakan Keras 'ResNet50 pra-terlatih (awalnya pas di imagenet), hapus lapisan klasifikasi atas dan sempurnakan dengan dan tanpa tambalan dan bandingkan hasilnya. Untuk data, kami akan menggunakan CIFAR10 (kereta standar / test split yang disediakan oleh Keras) dan kami akan mengubah ukuran gambar menjadi 224 × 224 untuk membuatnya kompatibel dengan ukuran input ResNet50.

Kami akan melakukan 10 zaman untuk melatih lapisan klasifikasi teratas menggunakan RSMprop dan kemudian kami akan melakukan 5 lainnya untuk menyempurnakan semuanya setelah lapisan ke-139 menggunakan SGD (lr = 1e-4, momentum = 0.9). Tanpa tambalan, model kami mencapai akurasi 87.44%. Menggunakan tambalan, kami mendapatkan akurasi 92.36%, hampir 5 poin lebih tinggi.

2.6 Haruskah kita menerapkan perbaikan yang sama ke lapisan lain seperti Dropout?

Normalisasi Batch bukan satu-satunya lapisan yang beroperasi secara berbeda antara mode kereta dan mode uji. Putus sekolah dan variannya juga memiliki efek yang sama. Haruskah kita menerapkan kebijakan yang sama untuk semua lapisan ini? Saya percaya tidak (meskipun saya ingin mendengar pendapat Anda tentang ini). Alasannya adalah bahwa Dropout digunakan untuk menghindari overfitting, sehingga menguncinya secara permanen ke mode prediksi selama pelatihan akan mengalahkan tujuannya. Bagaimana menurut anda?

Saya sangat percaya bahwa perbedaan ini harus diselesaikan dalam Keras. Saya telah melihat efek yang lebih mendalam (dari akurasi 100% hingga 50%) dalam aplikasi dunia nyata yang disebabkan oleh masalah ini. saya berencana mengirim sudah mengirim a PR ke Keras dengan perbaikan dan mudah-mudahan itu akan diterima.

Jika Anda menyukai posting blog ini, silakan luangkan waktu untuk membagikannya di Facebook atau Twitter. 🙂

Stempel Waktu:

Lebih dari kotak data