لایه عادی سازی دسته ای Keras، هوش داده PlatoBlockchain شکسته شده است. جستجوی عمودی Ai.

لایه عادی سازی دسته ای Keras شکسته شده است

به روز رسانی: متأسفانه درخواست کشش من به Keras که رفتار لایه عادی سازی دسته ای را تغییر داد، پذیرفته نشد. می توانید جزئیات را بخوانید اینجا کلیک نمایید. برای کسانی از شما که به اندازه کافی شجاع هستند که با پیاده سازی های سفارشی سر و کله بزنند، می توانید کد را در آن پیدا کنید شاخه من. ممکن است آن را حفظ کنم و با آخرین نسخه پایدار Keras ادغام کنم (2.1.6, 2.2.2 و 2.2.4) تا زمانی که از آن استفاده می کنم اما قولی نمی دهم.

اکثر افرادی که در یادگیری عمیق کار می کنند یا استفاده کرده اند یا شنیده اند کراس. برای کسانی از شما که این کار را نکرده‌اید، این یک کتابخانه عالی است که چارچوب‌های یادگیری عمیق مانند TensorFlow، Theano و CNTK را خلاصه می‌کند و یک API سطح بالا برای آموزش ANN ها استفاده از آن آسان است، نمونه سازی سریع را امکان پذیر می کند و دارای یک جامعه فعال دوستانه است. مدتی است که به شدت از آن استفاده می‌کنم و به صورت دوره‌ای در پروژه مشارکت می‌کنم و قطعاً آن را به هر کسی که می‌خواهد روی یادگیری عمیق کار کند توصیه می‌کنم.

با وجود اینکه Keras زندگی من را آسان‌تر کرد، بارها رفتارهای عجیب لایه Normalization دسته‌ای را گاز گرفتم. رفتار پیش‌فرض آن در طول زمان تغییر کرده است، با این وجود هنوز برای بسیاری از کاربران مشکلاتی ایجاد می‌کند و در نتیجه چندین مورد مرتبط با آن وجود دارد مسائل باز در Github. در این پست وبلاگ، من سعی خواهم کرد یک مورد برای اینکه چرا لایه BatchNormalization Keras با Transfer Learning خوب بازی نمی کند، بسازم، کدی را ارائه خواهم کرد که مشکل را برطرف می کند و نمونه هایی را با نتایج حاصل از آن ارائه خواهم کرد. وصله.

در بخش‌های فرعی زیر، مقدمه‌ای در مورد نحوه استفاده از Transfer Learning در یادگیری عمیق، لایه Normalization دسته‌ای، نحوه عملکرد Learnining_phase و چگونه Keras رفتار BN را در طول زمان تغییر داد، ارائه می‌دهم. اگر از قبل اینها را می‌دانید، می‌توانید با خیال راحت مستقیماً به بخش 2 بروید.

1.1 استفاده از آموزش انتقالی برای یادگیری عمیق بسیار مهم است

یکی از دلایلی که Deep Learning در گذشته مورد انتقاد قرار گرفت این است که به داده های بیش از حد نیاز دارد. این همیشه درست نیست. چندین تکنیک برای رفع این محدودیت وجود دارد که یکی از آنها آموزش انتقالی است.

فرض کنید که روی یک برنامه Computer Vision کار می کنید و می خواهید طبقه بندی کننده ای بسازید که Cats را از Dogs متمایز کند. در واقع برای آموزش مدل به میلیون ها تصویر گربه/سگ نیاز ندارید. در عوض می‌توانید از یک طبقه‌بندی‌کننده از پیش آموزش‌دیده استفاده کنید و کانولوشن‌های برتر را با داده‌های کمتر تنظیم کنید. ایده پشت آن این است که از آنجایی که مدل از قبل آموزش‌دیده شده بر روی تصاویر مناسب است، کانولوشن‌های پایین می‌توانند ویژگی‌هایی مانند خطوط، لبه‌ها و دیگر الگوهای مفید را تشخیص دهند، به این معنی که می‌توانید از وزن‌های آن به عنوان مقادیر اولیه‌سازی خوب استفاده کنید یا تا حدی شبکه را با داده‌های خود دوباره آموزش دهید. .
لایه عادی سازی دسته ای Keras، هوش داده PlatoBlockchain شکسته شده است. جستجوی عمودی Ai.
Keras با چندین مدل از پیش آموزش دیده و نمونه های کاربردی آسان در مورد نحوه تنظیم دقیق مدل ها ارائه می شود. می توانید در ادامه مطلب بخوانید مستندات.

1.2 لایه عادی سازی دسته ای چیست؟

لایه عادی سازی دسته ای در سال 2014 توسط Ioffe و Szegedy معرفی شد. این مشکل گرادیان ناپدید شدن را با استانداردسازی خروجی لایه قبلی برطرف می‌کند، با کاهش تعداد تکرارهای مورد نیاز، آموزش را سرعت می‌بخشد و آموزش شبکه‌های عصبی عمیق‌تر را امکان‌پذیر می‌کند. توضیح اینکه دقیقاً چگونه کار می کند از حوصله این پست خارج است، اما شدیداً شما را به خواندن آن توصیه می کنم مقاله اصلی. توضیح بیش از حد ساده شده این است که ورودی را با تفریق میانگین آن و با تقسیم بر انحراف معیار آن، مجدداً مقیاس می‌دهد. همچنین می تواند در صورت لزوم خنثی سازی تبدیل را بیاموزد.
لایه عادی سازی دسته ای Keras، هوش داده PlatoBlockchain شکسته شده است. جستجوی عمودی Ai.

1.3 فاز یادگیری در کراس چیست؟

برخی از لایه ها در طول آموزش و حالت استنتاج متفاوت عمل می کنند. قابل توجه ترین نمونه ها عبارتند از Normalization دسته ای و لایه های Dropout. در مورد BN، در طول آموزش از میانگین و واریانس مینی بچ برای تغییر مقیاس ورودی استفاده می کنیم. از طرف دیگر، در حین استنتاج از میانگین متحرک و واریانسی که در طول تمرین تخمین زده شد استفاده می کنیم.

Keras می داند در چه حالتی باید اجرا شود زیرا مکانیزم داخلی به نام دارد مرحله یادگیری. مرحله یادگیری کنترل می کند که آیا شبکه در حالت قطار یا آزمایش است. اگر به صورت دستی توسط کاربر تنظیم نشده باشد، در طول fit() شبکه با Learn_phase=1 (حالت قطار) اجرا می شود. در حین تولید پیش‌بینی‌ها (مثلاً وقتی متدهای predict() و ارزیابی() را فراخوانی می‌کنیم یا در مرحله اعتبارسنجی fit()) شبکه با Learning_phase=0 (حالت تست) اجرا می‌شود. اگرچه توصیه نمی‌شود، کاربر همچنین می‌تواند به صورت استاتیکی فاز learning_phase را به یک مقدار خاص تغییر دهد، اما این باید قبل از اضافه شدن هر مدل یا تانسوری در نمودار اتفاق بیفتد. اگر Learn_phase به صورت ایستا تنظیم شود، Keras به هر حالتی که کاربر انتخاب کرده است قفل می شود.

1.4 Keras چگونه نرمال سازی دسته ای را در طول زمان پیاده سازی کرد؟

Keras چندین بار رفتار عادی سازی دسته ای را تغییر داده است، اما مهم ترین به روز رسانی اخیر در Keras 2.1.3 اتفاق افتاده است. قبل از نسخه 2.1.3 که لایه BN منجمد شد (قابل آموزش = نادرست) آمار دسته ای خود را به روز می کرد، چیزی که باعث سردرد حماسی برای کاربرانش شد.

این فقط یک سیاست عجیب و غریب نبود، در واقع اشتباه بود. تصور کنید که یک لایه BN بین کانولوشن ها وجود دارد. اگر لایه یخ زده باشد، هیچ تغییری نباید در آن اتفاق بیفتد. اگر وزن‌های آن را تا حدی به‌روزرسانی کنیم و لایه‌های بعدی نیز منجمد شوند، هرگز این شانس را نخواهند داشت که با به‌روزرسانی‌های آمار دسته‌ای کوچک که منجر به خطای بالاتر می‌شود، تنظیم شوند. خوشبختانه با شروع نسخه 2.1.3، زمانی که یک لایه BN منجمد می شود، دیگر آمار خود را به روز نمی کند. اما آیا این کافی است؟ اگر از Transfer Learning استفاده می کنید نه.

در زیر دقیقاً توضیح می دهم که مشکل چیست و پیاده سازی فنی برای حل آن را ترسیم می کنم. من همچنین چند مثال برای نشان دادن تأثیرات بر دقت مدل قبل و بعد از آن ارائه می کنم وصله اعمال می شود.

2.1 شرح فنی مشکل

مشکل اجرای فعلی Keras این است که وقتی یک لایه BN منجمد می شود، همچنان از آمار mini-batch در طول آموزش استفاده می کند. من معتقدم وقتی BN منجمد می شود یک رویکرد بهتر استفاده از میانگین متحرک و واریانسی است که در طول آموزش آموخته است. چرا؟ به همان دلایلی که چرا وقتی لایه فریز می‌شود، آمار دسته‌ای کوچک نباید به‌روزرسانی شود: می‌تواند منجر به نتایج ضعیف شود زیرا لایه‌های بعدی به درستی آموزش داده نمی‌شوند.

فرض کنید که در حال ساخت یک مدل Computer Vision هستید اما داده های کافی ندارید، بنابراین تصمیم می گیرید از یکی از CNN های از پیش آموزش دیده Keras استفاده کنید و آن را تنظیم کنید. متأسفانه، با انجام این کار، هیچ تضمینی دریافت نمی‌کنید که میانگین و واریانس مجموعه داده جدید شما در لایه‌های BN مشابه با داده‌های اصلی باشد. به یاد داشته باشید که در حال حاضر، در طول آموزش، شبکه شما همیشه از آمار mini-batch استفاده می کند، چه لایه BN منجمد است یا خیر. همچنین در طول استنتاج، از آمارهای آموخته شده قبلی از لایه های BN منجمد استفاده خواهید کرد. در نتیجه، اگر لایه های بالایی را به دقت تنظیم کنید، وزن آنها با میانگین/واریانس تنظیم می شود. جدید مجموعه داده با این وجود، در طول استنتاج، داده هایی را دریافت خواهند کرد که مقیاس بندی شده اند متفاوت است زیرا میانگین/واریانس از اصلی مجموعه داده استفاده خواهد شد.
لایه عادی سازی دسته ای Keras، هوش داده PlatoBlockchain شکسته شده است. جستجوی عمودی Ai.
در بالا یک معماری ساده (و غیر واقعی) برای اهداف نمایشی ارائه می کنم. بیایید فرض کنیم که مدل را از Convolution k+1 به بالا تا بالای شبکه (سمت راست) تنظیم می کنیم و پایین (سمت چپ) را ثابت نگه می داریم. در طول آموزش، تمام لایه های BN از 1 تا k از میانگین / واریانس داده های آموزشی شما استفاده می کنند. اگر میانگین و واریانس در هر BN به آنچه در طول آموزش قبل از آموزش آموخته شده نزدیک نباشد، این تأثیرات منفی روی ReLU های منجمد خواهد داشت. همچنین باعث می‌شود بقیه شبکه (از CONV k+1 و جدیدتر) با ورودی‌هایی که مقیاس‌های متفاوتی در مقایسه با آنچه در طول استنتاج دریافت می‌شود، آموزش ببینند. در طول آموزش، شبکه شما می‌تواند با این تغییرات سازگار شود، با این حال، لحظه‌ای که به حالت پیش‌بینی تغییر می‌کنید، Keras از آمار استانداردسازی متفاوتی استفاده می‌کند، چیزی که توزیع ورودی‌های لایه‌های بعدی را سریع می‌کند و منجر به نتایج ضعیف می‌شود.

2.2 چگونه می توانید تشخیص دهید که تحت تأثیر قرار گرفته اید؟

یکی از راه های تشخیص آن این است که مرحله یادگیری Keras را به صورت ایستا روی 1 (حالت قطار) و روی 0 (حالت تست) تنظیم کنید و مدل خود را در هر مورد ارزیابی کنید. اگر تفاوت قابل توجهی در دقت در همان مجموعه داده وجود داشته باشد، شما تحت تأثیر مشکل قرار گرفته اید. شایان ذکر است که به دلیل نحوه پیاده سازی مکانیزم Learning_phase در Keras، معمولاً توصیه نمی شود که با آن دست و پنجه نرم کنید. تغییرات در فاز یادگیری هیچ تاثیری بر مدل هایی که قبلاً کامپایل و استفاده شده اند نخواهد داشت. همانطور که در مثال‌های زیر بخش‌های بعدی مشاهده می‌کنید، بهترین راه برای انجام این کار این است که با یک جلسه تمیز شروع کنید و قبل از اینکه هر تانسوری در نمودار تعریف شود، فاز learning_phase را تغییر دهید.

روش دیگر برای تشخیص مشکل در حین کار با طبقه‌بندی‌کننده‌های باینری، بررسی دقت و AUC است. اگر دقت نزدیک به 50٪ باشد اما AUC نزدیک به 1 باشد (و همچنین تفاوت‌هایی را بین حالت قطار/آزمایش در همان مجموعه داده مشاهده می‌کنید)، ممکن است به دلیل آمار BN، احتمالات خارج از مقیاس باشند. به طور مشابه، برای رگرسیون می توانید از MSE و همبستگی Spearman برای تشخیص آن استفاده کنید.

2.3 چگونه می توانیم آن را برطرف کنیم؟

من معتقدم که اگر لایه های BN منجمد شده در واقع دقیقاً همینطور باشند، می توان مشکل را برطرف کرد: به طور دائم در حالت تست قفل شده باشند. از نظر پیاده سازی، پرچم قابل آموزش باید بخشی از نمودار محاسباتی باشد و رفتار BN باید نه تنها به فاز یادگیری بلکه به ارزش ویژگی قابل آموزش نیز بستگی داشته باشد. شما می توانید جزئیات اجرای من را در اینجا بیابید گیتهاب.

با اعمال اصلاح بالا، هنگامی که یک لایه BN منجمد می شود، دیگر از آمار دسته ای کوچک استفاده نمی کند، بلکه از مواردی که در طول آموزش آموخته شده است استفاده می کند. در نتیجه، هیچ تناقضی بین حالت تمرین و آزمون وجود نخواهد داشت که منجر به افزایش دقت می شود. بدیهی است که وقتی لایه BN منجمد نشده باشد، در طول آموزش از آمار mini-batch استفاده می کند.

2.4 ارزیابی اثرات پچ

اگرچه من اخیراً اجرای فوق را نوشتم، ایده پشت آن به شدت بر روی مشکلات دنیای واقعی با استفاده از راه‌حل‌های مختلف که تأثیر یکسانی دارند، آزمایش شده است. به عنوان مثال، با تقسیم شبکه به دو قسمت (یخ زده و منجمد نشده) و انجام آموزش کش (یک بار عبور داده ها از مدل فریز شده و سپس استفاده از آنها برای آموزش شبکه unfrozen) از تناقض بین حالت های آموزشی و آزمایشی جلوگیری می شود. با این وجود، از آنجا که «به من اعتماد کن که قبلاً این کار را انجام داده‌ام» معمولاً وزنی ندارد، در زیر چند مثال ارائه می‌دهم که تأثیرات اجرای جدید را در عمل نشان می‌دهد.

در اینجا چند نکته مهم در مورد آزمایش وجود دارد:

  1. من از مقدار کمی از داده ها استفاده خواهم کرد تا عمداً مدل را بیش از حد برازش دهم و مدل را روی همان مجموعه داده آموزش و تأیید خواهم کرد. با انجام این کار، من انتظار دارم که دقت تقریباً کامل و عملکرد یکسانی در مجموعه داده قطار/ اعتبارسنجی داشته باشد.
  2. اگر در حین اعتبارسنجی، دقت قابل توجهی کمتری روی همان مجموعه داده داشته باشم، نشانه واضحی خواهم داشت که خط مشی BN فعلی بر عملکرد مدل در طول استنتاج تأثیر منفی می گذارد.
  3. هرگونه پیش پردازش خارج از ژنراتورها انجام خواهد شد. این کار برای رفع اشکالی انجام می‌شود که در نسخه 2.1.5 معرفی شده بود (در حال حاضر در نسخه 2.1.6 و آخرین Master رفع شده است).
  4. ما کراس را مجبور خواهیم کرد که از مراحل مختلف یادگیری در طول ارزشیابی استفاده کند. اگر تفاوت‌هایی را بین دقت گزارش‌شده تشخیص دهیم، متوجه می‌شویم که تحت تأثیر خط‌مشی فعلی BN هستیم.

کد آزمایش در زیر نشان داده شده است:

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

بیایید نتایج 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]

همانطور که در بالا می بینیم، در طول آموزش مدل به خوبی داده ها را یاد می گیرد و در مجموعه آموزشی به دقت تقریباً کاملی دست می یابد. هنوز در پایان هر تکرار، در حالی که مدل را بر روی همان مجموعه داده ارزیابی می کنیم، تفاوت های قابل توجهی در از دست دادن و دقت دریافت می کنیم. توجه داشته باشید که ما نباید این را دریافت کنیم. ما عمداً مدل را روی مجموعه داده خاص بیش از حد برازش داده‌ایم و مجموعه داده‌های آموزشی/ اعتبارسنجی یکسان هستند.

پس از اتمام آموزش، مدل را با استفاده از 3 پیکربندی فاز یادگیری مختلف ارزیابی می‌کنیم: پویا، استاتیک = 0 (حالت تست) و استاتیک = 1 (حالت آموزش). همانطور که می بینیم دو پیکربندی اول نتایج یکسانی را از نظر از دست دادن و دقت ارائه می دهند و مقدار آنها با دقت گزارش شده مدل در مجموعه اعتبار سنجی در آخرین تکرار مطابقت دارد. با این وجود، هنگامی که به حالت تمرین تغییر می کنیم، یک اختلاف (بهبود) عظیم را مشاهده می کنیم. چرا اینطوری؟ همانطور که قبلاً گفتیم، وزن‌های شبکه با انتظار دریافت داده‌های مقیاس‌بندی شده با میانگین/واریانس داده‌های آموزشی تنظیم می‌شوند. متأسفانه، آن آمار با آمارهای ذخیره شده در لایه های BN متفاوت است. از آنجایی که لایه های BN منجمد شده بودند، این آمار هرگز به روز نشد. این اختلاف بین مقادیر آمار BN منجر به بدتر شدن دقت در طول استنتاج می شود.

بیایید ببینیم پس از اعمال چه اتفاقی می افتد وصله:

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]

اول از همه، مشاهده می کنیم که شبکه به طور قابل توجهی سریعتر همگرا می شود و به دقت کامل می رسد. همچنین می‌بینیم که وقتی بین مقادیر مختلف Learning_phase جابجا می‌شویم، دیگر اختلافی از نظر دقت وجود ندارد.

2.5 وصله در یک مجموعه داده واقعی چگونه عمل می کند؟

پس چگونه پچ در آزمایش واقعی تر عمل می کند؟ بیایید از ResNet50 از پیش آموزش‌دیده Keras استفاده کنیم (در ابتدا بر روی imagenet قرار می‌گیرد)، لایه طبقه‌بندی بالایی را حذف کرده و آن را با و بدون پچ تنظیم کنیم و نتایج را با هم مقایسه کنیم. برای داده‌ها، از CIFAR10 (تقسیم استاندارد قطار/آزمایش ارائه شده توسط Keras) استفاده می‌کنیم و اندازه تصاویر را به 224×224 تغییر می‌دهیم تا با اندازه ورودی ResNet50 سازگار شوند.

ما 10 دوره را برای آموزش لایه طبقه بندی بالا با استفاده از RSMprop انجام می دهیم و سپس 5 دوره دیگر را برای تنظیم دقیق همه چیز بعد از لایه 139 با استفاده از SGD (lr=1e-4، تکانه = 0.9) انجام می دهیم. بدون پچ مدل ما به دقت 87.44 درصد دست می یابد. با استفاده از پچ، دقت 92.36% تقریباً 5 امتیاز بالاتر را بدست می آوریم.

2.6 آیا باید همان اصلاح را برای لایه های دیگر مانند Dropout اعمال کنیم؟

نرمال سازی دسته ای تنها لایه ای نیست که بین حالت های قطار و آزمایش متفاوت عمل می کند. ترک تحصیل و انواع آن نیز همین تأثیر را دارند. آیا باید سیاست یکسانی را برای همه این لایه ها اعمال کنیم؟ من باور نمی کنم (حتی اگر دوست دارم نظر شما را در این مورد بشنوم). دلیل آن این است که Dropout برای جلوگیری از تطبیق بیش از حد استفاده می شود، بنابراین قفل کردن دائمی آن در حالت پیش بینی در طول تمرین، هدف آن را شکست می دهد. شما چی فکر میکنید؟

من به شدت معتقدم که این اختلاف باید در کراس حل شود. من حتی اثرات عمیق تری (از 100٪ تا 50٪ دقت) در برنامه های کاربردی دنیای واقعی ناشی از این مشکل دیده ام. من برنامه ریزی برای ارسال قبلا ارسال شده است PR به Keras با رفع مشکل و امیدوارم مورد قبول واقع شود.

اگر این وبلاگ را دوست داشتید، لطفاً چند لحظه آن را در فیس بوک یا توییتر به اشتراک بگذارید. 🙂

تمبر زمان:

بیشتر از Datumbox