Gradient Clipping

مشکل محوشدگی و انفجار گرادیان

 

محوشدگی گرادیان

 

در مقاله “آشنایی با شبکه عصبی بازگشتی” با تعریف شبکه‌های عصبی مکرر (RNN) آشنا شدیم. دانستیم که مشکل محوشدگی گرادیان ریشه در این موضوع دارد که برای به‌روزرسانی پارامترهای وزن از روش گرادیان استفاده می‌کنیم.

به‌طور شهودی می‌توان گفت مشکل محوشدگی گرادیان زمانی اتفاق میفتد که بهینه‌سازی در یک نقطه مشخص، به دلیل شیب بسیارکم گیر کند. به وضوح این مطلب در تصویر  مشهود است.

 

 

انفجار گرادیان

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

 

بررسی Gradient Clipping

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

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

تصویر زیر به خوبی نشان می‌دهد که وضعیت و مقدار گرادیان‌ها با اعمال روش gradient clipping چه تغییری می‌کند.

پیاده‌سازی

اگر مقدار شیب کمتر از یک آستانه منفی یا بیشتر از آستانه مثبت باشد، Gradient Clipping، شیب نمودار (مشتقات تابع loss) را به یک مقدار معین می‌رساند. به‌عنوان‌مثال می‌توانیم یک آستانه با مقدار 0.5 مشخص کنیم ، به این معنی که اگر یک مقدار شیب کمتر از 0.5- باشد، روی 0.5- تنظیم می‌شود و اگر بیشتر از 0.5 باشد، آن را بر روی 0.5 قرار می‌دهیم. این می‌تواند در Keras با مشخص کردن آرگومان “clipvalue” در مورد بهینه‌ساز استفاده شود.

opt=SGD(lr=0.01, momentum=0.9, clipvalue=0.5)

 

MLP با Gradient Clipping

در این بخش با کمک Gradient Clipping در MLP مشکل انفجار گرادیان را حل می‌کنیم، که از بزرگ شدن بسیار زیاد و کم شدن بی‌حد شیب جلوگیری می‌کند. با اضافه کردن آرگومان “clipvalue” به تنظیمات الگوریتم بهینه‌سازی، می‌توانیم آموزش MLP را برای استفاده از Gradient Clipping به‌روز کنیم. به‌عنوان‌مثال: کد زیر، شیب را بین [-5 تا 5] قرار می‌دهد:

# compile model
opt = SGD(lr=0.01, momentum=0.9, clipvalue=5.0)
model.compile(loss='mean_squared_error', optimizer=opt)




from sklearn.datasets import make_regression
from keras.layers import Dense
from keras.models import Sequential
from keras.optimizers import SGD
from matplotlib import pyplot
# generate regression dataset
X, y = make_regression(n_samples=1000, n_features=20, noise=0.1, random_state=1)
# split into train and test
n_train = 500
trainX, testX = X[:n_train, :], X[n_train:, :]
trainy, testy = y[:n_train], y[n_train:]
# define model
model = Sequential()
model.add(Dense(25, input_dim=20, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(1, activation='linear'))
# compile model
opt = SGD(lr=0.01, momentum=0.9, clipvalue=5.0)
model.compile(loss='mean_squared_error', optimizer=opt)
# fit model
history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=100, verbose=0)
# evaluate the model
train_mse = model.evaluate(trainX, trainy, verbose=0)
test_mse = model.evaluate(testX, testy, verbose=0)
print('Train: %.3f, Test: %.3f' % (train_mse, test_mse))
# plot loss during training
pyplot.title('Mean Squared Error')
pyplot.plot(history.history['loss'], label='train')
pyplot.plot(history.history['val_loss'], label='test')
pyplot.legend()
pyplot.show()

نمودار بالا نشان می‌دهد که مدل مسئله را سریع می‌آموزد، و تنها در طی چند دوره آموزش، به یک خطای کمتر از ۱۰۰  می‌رسد.

 

ارسال یک پاسخ

آدرس ایمیل شما منتشر نخواهد شد.