مساعدة في حماية الحاجز المرجاني العظيم مع TensorFlow على Kaggle تاريخ التحدي

overfit و underfit

عرض على TensorFlow.org تشغيل في Google Colab عرض المصدر على جيثب تحميل دفتر

كما هو الحال دائما، فإن التعليمات البرمجية في هذا المثال استخدام tf.keras API، والتي يمكنك معرفة المزيد عنها في TensorFlow دليل Keras .

في كل من examples- السابق نص تصنيفها و توقع الكفاءة في استهلاك الوقود - رأينا أن دقة نموذجنا على التحقق من صحة البيانات سوف يصل إلى ذروته بعد التدريب لعدد من العهود، وعندئذ ركود أو يبدأ في التناقص.

وبعبارة أخرى، فإن نموذجنا overfit إلى بيانات التدريب. تعلم كيفية التعامل مع فرط التجهيز مهم. على الرغم من أنه من الممكن في كثير من الأحيان لتحقيق دقة عالية على مجموعة التدريب، ما نريده حقا هو لتطوير النماذج التي التعميم أيضا إلى مجموعة الاختبار (أو البيانات التي لم تشاهد من قبل).

على العكس من overfitting وunderfitting. يحدث النقص في الملاءمة عندما لا يزال هناك مجال لتحسين بيانات القطار. يمكن أن يحدث هذا لعدد من الأسباب: إذا لم يكن النموذج قويًا بما يكفي ، أو مفرط التنظيم ، أو ببساطة لم يتم تدريبه لفترة كافية. هذا يعني أن الشبكة لم تتعلم الأنماط ذات الصلة في بيانات التدريب.

إذا كنت تتدرب لفترة طويلة جدًا ، فسيبدأ النموذج في التجهيز الزائد ويتعلم أنماطًا من بيانات التدريب التي لا يتم تعميمها على بيانات الاختبار. نحن بحاجة إلى تحقيق التوازن. يعد فهم كيفية التدريب لعدد مناسب من الحقب كما سنستكشف أدناه مهارة مفيدة.

لمنع فرط التخصيص ، فإن أفضل حل هو استخدام بيانات تدريب أكثر اكتمالاً. يجب أن تغطي مجموعة البيانات النطاق الكامل للمدخلات التي من المتوقع أن يتعامل معها النموذج. قد تكون البيانات الإضافية مفيدة فقط إذا كانت تغطي حالات جديدة ومثيرة للاهتمام.

النموذج الذي يتم تدريبه على بيانات أكثر اكتمالاً سيعمم بشكل أفضل بشكل طبيعي. عندما لم يعد ذلك ممكنًا ، فإن أفضل حل تالي هو استخدام تقنيات مثل التنظيم. تضع هذه القيود قيودًا على كمية ونوع المعلومات التي يمكن أن يخزنها نموذجك. إذا كانت الشبكة تستطيع فقط حفظ عدد صغير من الأنماط ، فإن عملية التحسين ستجبرها على التركيز على الأنماط الأكثر بروزًا ، والتي لديها فرصة أفضل للتعميم بشكل جيد.

في هذا الكمبيوتر الدفتري ، سوف نستكشف العديد من تقنيات التنظيم الشائعة ، ونستخدمها لتحسين نموذج التصنيف.

اقامة

قبل البدء ، قم باستيراد الحزم الضرورية:

import tensorflow as tf

from tensorflow.keras import layers
from tensorflow.keras import regularizers

print(tf.__version__)
2.5.0
!pip install git+https://github.com/tensorflow/docs

import tensorflow_docs as tfdocs
import tensorflow_docs.modeling
import tensorflow_docs.plots
from  IPython import display
from matplotlib import pyplot as plt

import numpy as np

import pathlib
import shutil
import tempfile
logdir = pathlib.Path(tempfile.mkdtemp())/"tensorboard_logs"
shutil.rmtree(logdir, ignore_errors=True)

مجموعة بيانات هيجز

الهدف من هذا البرنامج التعليمي ليس القيام بفيزياء الجسيمات ، لذلك لا تسهب في تفاصيل مجموعة البيانات. يحتوي على 11000000 مثال ، لكل منها 28 ميزة ، وتسمية فئة ثنائية.

gz = tf.keras.utils.get_file('HIGGS.csv.gz', 'http://mlphysics.ics.uci.edu/data/higgs/HIGGS.csv.gz')
Downloading data from http://mlphysics.ics.uci.edu/data/higgs/HIGGS.csv.gz
2816409600/2816407858 [==============================] - 148s 0us/step
FEATURES = 28

و tf.data.experimental.CsvDataset الفئة يمكن أن تستخدم لقراءة سجلات CSV مباشرة من ملف غزيب مع أي خطوة الضغط وسيطة.

ds = tf.data.experimental.CsvDataset(gz,[float(),]*(FEATURES+1), compression_type="GZIP")

تقوم فئة قارئ csv هذه بإرجاع قائمة بالمقاسات لكل سجل. تعيد الوظيفة التالية حزم قائمة الحجميات تلك في زوج (feature_vector ، label).

def pack_row(*row):
  label = row[0]
  features = tf.stack(row[1:],1)
  return features, label

TensorFlow هو الأكثر كفاءة عند العمل على دفعات كبيرة من البيانات.

وذلك بدلا من إعادة تعبئة كل صف جعل فردي جديد Dataset أن يأخذ دفعات من 10000 الأمثلة، وينطبق الشيء pack_row وظيفة لكل دفعة، ثم يقسم دفعات احتياطيا في السجلات الفردية:

packed_ds = ds.batch(10000).map(pack_row).unbatch()

إلقاء نظرة على بعض السجلات من هذا الجديد packed_ds .

لم يتم تطبيع الميزات تمامًا ، لكن هذا يكفي لهذا البرنامج التعليمي.

for features,label in packed_ds.batch(1000).take(1):
  print(features[0])
  plt.hist(features.numpy().flatten(), bins = 101)
tf.Tensor(
[ 0.8692932  -0.6350818   0.22569026  0.32747006 -0.6899932   0.75420225
 -0.24857314 -1.0920639   0.          1.3749921  -0.6536742   0.9303491
  1.1074361   1.1389043  -1.5781983  -1.0469854   0.          0.65792954
 -0.01045457 -0.04576717  3.1019614   1.35376     0.9795631   0.97807616
  0.92000484  0.72165745  0.98875093  0.87667835], shape=(28,), dtype=float32)

بي إن جي

للحفاظ على هذا البرنامج التعليمي قصيرًا نسبيًا ، استخدم فقط أول 1000 عينة للتحقق من صحتها ، و 10000 عينة التالية للتدريب:

N_VALIDATION = int(1e3)
N_TRAIN = int(1e4)
BUFFER_SIZE = int(1e4)
BATCH_SIZE = 500
STEPS_PER_EPOCH = N_TRAIN//BATCH_SIZE

و Dataset.skip و Dataset.take طرق تجعل هذا سهلا.

في نفس الوقت، استخدم Dataset.cache طريقة للتأكد من أن محمل لا تحتاج إلى إعادة قراءة البيانات من ملف في كل عصر:

validate_ds = packed_ds.take(N_VALIDATION).cache()
train_ds = packed_ds.skip(N_VALIDATION).take(N_TRAIN).cache()
train_ds
<CacheDataset shapes: ((28,), ()), types: (tf.float32, tf.float32)>

مجموعات البيانات هذه تعرض أمثلة فردية. استخدام .batch الطريقة لإنشاء دفعات ذات حجم مناسب للتدريب. قبل الجرعات أيضا تذكر أن .shuffle و .repeat مجموعة التدريب.

validate_ds = validate_ds.batch(BATCH_SIZE)
train_ds = train_ds.shuffle(BUFFER_SIZE).repeat().batch(BATCH_SIZE)

أظهر التجهيز الزائد

إن أبسط طريقة لمنع فرط التخصيص هي البدء بنموذج صغير: نموذج يحتوي على عدد صغير من المعلمات القابلة للتعلم (والتي يتم تحديدها من خلال عدد الطبقات وعدد الوحدات لكل طبقة). في التعلم العميق ، غالبًا ما يشار إلى عدد المعلمات القابلة للتعلم في النموذج باسم "قدرة" النموذج.

حدسيًا ، سيكون للنموذج الذي يحتوي على المزيد من المعلمات "قدرة حفظ" أكبر وبالتالي سيكون قادرًا على تعلم رسم خرائط مثالي يشبه القاموس بين عينات التدريب وأهدافها ، ورسم خرائط بدون أي قوة تعميم ، ولكن هذا سيكون عديم الفائدة عند عمل التنبؤات على بيانات غير مرئية من قبل.

ضع هذا في اعتبارك دائمًا: تميل نماذج التعلم العميق إلى أن تكون جيدة في ملاءمة بيانات التدريب ، لكن التحدي الحقيقي هو التعميم وليس الملاءمة.

من ناحية أخرى ، إذا كانت الشبكة لديها موارد حفظ محدودة ، فلن تكون قادرة على تعلم التعيين بسهولة. لتقليل فقدها ، سيتعين عليها تعلم التمثيلات المضغوطة التي تتمتع بقدرة أكبر على التنبؤ. في الوقت نفسه ، إذا جعلت نموذجك صغيرًا جدًا ، فسيكون من الصعب ملاءمته لبيانات التدريب. هناك توازن بين "سعة كبيرة" و "سعة غير كافية".

لسوء الحظ ، لا توجد صيغة سحرية لتحديد الحجم أو البنية المناسبة للنموذج الخاص بك (من حيث عدد الطبقات ، أو الحجم المناسب لكل طبقة). سيكون عليك تجربة استخدام سلسلة من البنى المختلفة.

للعثور على حجم نموذج مناسب ، من الأفضل البدء بعدد قليل نسبيًا من الطبقات والمعلمات ، ثم البدء في زيادة حجم الطبقات أو إضافة طبقات جديدة حتى ترى عوائد متناقصة على فقدان التحقق من الصحة.

تبدأ مع نموذج بسيط فقط باستخدام layers.Dense كأساس، ثم إنشاء نسخ أكبر، ومقارنتها.

إجراءات التدريب

تتدرب العديد من النماذج بشكل أفضل إذا قمت بتقليل معدل التعلم تدريجيًا أثناء التدريب. استخدام optimizers.schedules للحد من معدل التعلم على مر الزمن:

lr_schedule = tf.keras.optimizers.schedules.InverseTimeDecay(
  0.001,
  decay_steps=STEPS_PER_EPOCH*1000,
  decay_rate=1,
  staircase=False)

def get_optimizer():
  return tf.keras.optimizers.Adam(lr_schedule)

رمز أعلاه مجموعات ل schedules.InverseTimeDecay إلى انخفاض hyperbolically معدل التعلم إلى 1/2 من المعدل الأساسي في 1000 العهود، 1/3 في العهود 2000 وهلم جرا.

step = np.linspace(0,100000)
lr = lr_schedule(step)
plt.figure(figsize = (8,6))
plt.plot(step/STEPS_PER_EPOCH, lr)
plt.ylim([0,max(plt.ylim())])
plt.xlabel('Epoch')
_ = plt.ylabel('Learning Rate')

بي إن جي

سيستخدم كل نموذج في هذا البرنامج التعليمي نفس تكوين التدريب. لذا قم بإعداد هذه بطريقة قابلة لإعادة الاستخدام ، بدءًا من قائمة عمليات الاسترجاعات.

يمتد التدريب على هذا البرنامج التعليمي لعدة فترات قصيرة. للحد من قطع الأشجار الضوضاء استخدام tfdocs.EpochDots الذي يطبع ببساطة . لكل حقبة ، ومجموعة كاملة من المقاييس كل 100 عصر.

تشمل التالي callbacks.EarlyStopping لتجنب طويلة وغير ضرورية مواعيد التدريب. لاحظ أن يتم تعيين هذا الاستدعاء لمراقبة val_binary_crossentropy ، وليس val_loss . سيكون هذا الاختلاف مهمًا لاحقًا.

استخدام callbacks.TensorBoard لتوليد سجلات TensorBoard للتدريب.

def get_callbacks(name):
  return [
    tfdocs.modeling.EpochDots(),
    tf.keras.callbacks.EarlyStopping(monitor='val_binary_crossentropy', patience=200),
    tf.keras.callbacks.TensorBoard(logdir/name),
  ]

وبالمثل كل نموذج سوف تستخدم نفس Model.compile و Model.fit الإعدادات:

def compile_and_fit(model, name, optimizer=None, max_epochs=10000):
  if optimizer is None:
    optimizer = get_optimizer()
  model.compile(optimizer=optimizer,
                loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
                metrics=[
                  tf.keras.losses.BinaryCrossentropy(
                      from_logits=True, name='binary_crossentropy'),
                  'accuracy'])

  model.summary()

  history = model.fit(
    train_ds,
    steps_per_epoch = STEPS_PER_EPOCH,
    epochs=max_epochs,
    validation_data=validate_ds,
    callbacks=get_callbacks(name),
    verbose=0)
  return history

نموذج صغير

ابدأ بتدريب نموذج:

tiny_model = tf.keras.Sequential([
    layers.Dense(16, activation='elu', input_shape=(FEATURES,)),
    layers.Dense(1)
])
size_histories = {}
size_histories['Tiny'] = compile_and_fit(tiny_model, 'sizes/Tiny')
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense (Dense)                (None, 16)                464       
_________________________________________________________________
dense_1 (Dense)              (None, 1)                 17        
=================================================================
Total params: 481
Trainable params: 481
Non-trainable params: 0
_________________________________________________________________
WARNING:tensorflow:Callback method `on_train_batch_begin` is slow compared to the batch time (batch time: 0.0031s vs `on_train_batch_begin` time: 0.0346s). Check your callbacks.
WARNING:tensorflow:Callback method `on_train_batch_end` is slow compared to the batch time (batch time: 0.0031s vs `on_train_batch_end` time: 0.0125s). Check your callbacks.

Epoch: 0, accuracy:0.5093,  binary_crossentropy:0.7681,  loss:0.7681,  val_accuracy:0.5000,  val_binary_crossentropy:0.7207,  val_loss:0.7207,  
....................................................................................................
Epoch: 100, accuracy:0.6058,  binary_crossentropy:0.6244,  loss:0.6244,  val_accuracy:0.5700,  val_binary_crossentropy:0.6322,  val_loss:0.6322,  
....................................................................................................
Epoch: 200, accuracy:0.6220,  binary_crossentropy:0.6124,  loss:0.6124,  val_accuracy:0.5990,  val_binary_crossentropy:0.6202,  val_loss:0.6202,  
....................................................................................................
Epoch: 300, accuracy:0.6388,  binary_crossentropy:0.6045,  loss:0.6045,  val_accuracy:0.6150,  val_binary_crossentropy:0.6114,  val_loss:0.6114,  
....................................................................................................
Epoch: 400, accuracy:0.6475,  binary_crossentropy:0.5976,  loss:0.5976,  val_accuracy:0.6270,  val_binary_crossentropy:0.6012,  val_loss:0.6012,  
....................................................................................................
Epoch: 500, accuracy:0.6579,  binary_crossentropy:0.5917,  loss:0.5917,  val_accuracy:0.6390,  val_binary_crossentropy:0.5929,  val_loss:0.5929,  
....................................................................................................
Epoch: 600, accuracy:0.6662,  binary_crossentropy:0.5878,  loss:0.5878,  val_accuracy:0.6410,  val_binary_crossentropy:0.5890,  val_loss:0.5890,  
....................................................................................................
Epoch: 700, accuracy:0.6664,  binary_crossentropy:0.5847,  loss:0.5847,  val_accuracy:0.6670,  val_binary_crossentropy:0.5865,  val_loss:0.5865,  
....................................................................................................
Epoch: 800, accuracy:0.6709,  binary_crossentropy:0.5822,  loss:0.5822,  val_accuracy:0.6460,  val_binary_crossentropy:0.5896,  val_loss:0.5896,  
....................................................................................................
Epoch: 900, accuracy:0.6772,  binary_crossentropy:0.5793,  loss:0.5793,  val_accuracy:0.6540,  val_binary_crossentropy:0.5880,  val_loss:0.5880,  
...................

تحقق الآن من كيفية عمل النموذج:

plotter = tfdocs.plots.HistoryPlotter(metric = 'binary_crossentropy', smoothing_std=10)
plotter.plot(size_histories)
plt.ylim([0.5, 0.7])
(0.5, 0.7)

بي إن جي

نموذج صغير

لمعرفة ما إذا كان بإمكانك التغلب على أداء النموذج الصغير ، تدرب تدريجيًا على بعض الطرز الأكبر حجمًا.

جرب طبقتين مخفيتين كل منهما 16 وحدة:

small_model = tf.keras.Sequential([
    # `input_shape` is only required here so that `.summary` works.
    layers.Dense(16, activation='elu', input_shape=(FEATURES,)),
    layers.Dense(16, activation='elu'),
    layers.Dense(1)
])
size_histories['Small'] = compile_and_fit(small_model, 'sizes/Small')
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_2 (Dense)              (None, 16)                464       
_________________________________________________________________
dense_3 (Dense)              (None, 16)                272       
_________________________________________________________________
dense_4 (Dense)              (None, 1)                 17        
=================================================================
Total params: 753
Trainable params: 753
Non-trainable params: 0
_________________________________________________________________
WARNING:tensorflow:Callback method `on_train_batch_begin` is slow compared to the batch time (batch time: 0.0030s vs `on_train_batch_begin` time: 0.0258s). Check your callbacks.
WARNING:tensorflow:Callback method `on_train_batch_end` is slow compared to the batch time (batch time: 0.0030s vs `on_train_batch_end` time: 0.0176s). Check your callbacks.

Epoch: 0, accuracy:0.4757,  binary_crossentropy:0.7130,  loss:0.7130,  val_accuracy:0.4630,  val_binary_crossentropy:0.7012,  val_loss:0.7012,  
....................................................................................................
Epoch: 100, accuracy:0.6295,  binary_crossentropy:0.6092,  loss:0.6092,  val_accuracy:0.6120,  val_binary_crossentropy:0.6145,  val_loss:0.6145,  
....................................................................................................
Epoch: 200, accuracy:0.6575,  binary_crossentropy:0.5879,  loss:0.5879,  val_accuracy:0.6520,  val_binary_crossentropy:0.5976,  val_loss:0.5976,  
....................................................................................................
Epoch: 300, accuracy:0.6758,  binary_crossentropy:0.5774,  loss:0.5774,  val_accuracy:0.6610,  val_binary_crossentropy:0.5958,  val_loss:0.5958,  
....................................................................................................
Epoch: 400, accuracy:0.6830,  binary_crossentropy:0.5698,  loss:0.5698,  val_accuracy:0.6690,  val_binary_crossentropy:0.5949,  val_loss:0.5949,  
....................................................................................................
Epoch: 500, accuracy:0.6873,  binary_crossentropy:0.5650,  loss:0.5650,  val_accuracy:0.6720,  val_binary_crossentropy:0.5930,  val_loss:0.5930,  
....................................................................................................
Epoch: 600, accuracy:0.6923,  binary_crossentropy:0.5600,  loss:0.5600,  val_accuracy:0.6570,  val_binary_crossentropy:0.5946,  val_loss:0.5946,  
......................................................

نموذج متوسط

جرب الآن 3 طبقات مخفية تحتوي كل منها على 64 وحدة:

medium_model = tf.keras.Sequential([
    layers.Dense(64, activation='elu', input_shape=(FEATURES,)),
    layers.Dense(64, activation='elu'),
    layers.Dense(64, activation='elu'),
    layers.Dense(1)
])

وقم بتدريب النموذج باستخدام نفس البيانات:

size_histories['Medium']  = compile_and_fit(medium_model, "sizes/Medium")
Model: "sequential_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_5 (Dense)              (None, 64)                1856      
_________________________________________________________________
dense_6 (Dense)              (None, 64)                4160      
_________________________________________________________________
dense_7 (Dense)              (None, 64)                4160      
_________________________________________________________________
dense_8 (Dense)              (None, 1)                 65        
=================================================================
Total params: 10,241
Trainable params: 10,241
Non-trainable params: 0
_________________________________________________________________
WARNING:tensorflow:Callback method `on_train_batch_begin` is slow compared to the batch time (batch time: 0.0033s vs `on_train_batch_begin` time: 0.0251s). Check your callbacks.
WARNING:tensorflow:Callback method `on_train_batch_end` is slow compared to the batch time (batch time: 0.0033s vs `on_train_batch_end` time: 0.0189s). Check your callbacks.

Epoch: 0, accuracy:0.5026,  binary_crossentropy:0.6944,  loss:0.6944,  val_accuracy:0.4740,  val_binary_crossentropy:0.6830,  val_loss:0.6830,  
....................................................................................................
Epoch: 100, accuracy:0.7164,  binary_crossentropy:0.5242,  loss:0.5242,  val_accuracy:0.6490,  val_binary_crossentropy:0.6316,  val_loss:0.6316,  
....................................................................................................
Epoch: 200, accuracy:0.7919,  binary_crossentropy:0.4224,  loss:0.4224,  val_accuracy:0.6480,  val_binary_crossentropy:0.7022,  val_loss:0.7022,  
.......................................

نموذج كبير

كتمرين ، يمكنك إنشاء نموذج أكبر ، ومعرفة مدى سرعة بدء التجهيز. بعد ذلك ، دعنا نضيف إلى هذا المعيار شبكة تتمتع بسعة أكبر بكثير مما قد تضمنه المشكلة:

large_model = tf.keras.Sequential([
    layers.Dense(512, activation='elu', input_shape=(FEATURES,)),
    layers.Dense(512, activation='elu'),
    layers.Dense(512, activation='elu'),
    layers.Dense(512, activation='elu'),
    layers.Dense(1)
])

ومرة أخرى ، قم بتدريب النموذج باستخدام نفس البيانات:

size_histories['large'] = compile_and_fit(large_model, "sizes/large")
Model: "sequential_3"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_9 (Dense)              (None, 512)               14848     
_________________________________________________________________
dense_10 (Dense)             (None, 512)               262656    
_________________________________________________________________
dense_11 (Dense)             (None, 512)               262656    
_________________________________________________________________
dense_12 (Dense)             (None, 512)               262656    
_________________________________________________________________
dense_13 (Dense)             (None, 1)                 513       
=================================================================
Total params: 803,329
Trainable params: 803,329
Non-trainable params: 0
_________________________________________________________________
WARNING:tensorflow:Callback method `on_train_batch_begin` is slow compared to the batch time (batch time: 0.0033s vs `on_train_batch_begin` time: 0.0237s). Check your callbacks.
WARNING:tensorflow:Callback method `on_train_batch_end` is slow compared to the batch time (batch time: 0.0033s vs `on_train_batch_end` time: 0.0182s). Check your callbacks.

Epoch: 0, accuracy:0.5116,  binary_crossentropy:0.7680,  loss:0.7680,  val_accuracy:0.5440,  val_binary_crossentropy:0.6753,  val_loss:0.6753,  
....................................................................................................
Epoch: 100, accuracy:1.0000,  binary_crossentropy:0.0021,  loss:0.0021,  val_accuracy:0.6610,  val_binary_crossentropy:1.8058,  val_loss:1.8058,  
....................................................................................................
Epoch: 200, accuracy:1.0000,  binary_crossentropy:0.0001,  loss:0.0001,  val_accuracy:0.6500,  val_binary_crossentropy:2.4712,  val_loss:2.4712,  
.........................

ارسم خسائر التدريب والتحقق من الصحة

تُظهر الخطوط الصلبة خسارة التدريب ، وتُظهر الخطوط المتقطعة فقدان التحقق من الصحة (تذكر: خسارة التحقق الأقل تشير إلى نموذج أفضل).

أثناء بناء نموذج أكبر يمنحه مزيدًا من القوة ، إذا لم تكن هذه القوة مقيدة بطريقة ما ، فيمكن بسهولة أن تتناسب مع مجموعة التدريب.

في هذا المثال، عادة، إلا أن "Tiny" نموذج يدير لتجنب overfitting تماما، ولكل نموذج من نماذج أكبر overfit البيانات بسرعة أكبر. هذا يصبح شديد جدا ل "large" نموذج التي تحتاج إلى تبديل مؤامرة على نطاق سجل لأرى ما يحدث.

هذا واضح إذا قمت برسم ومقارنة مقاييس التحقق من الصحة بمقاييس التدريب.

  • من الطبيعي أن يكون هناك فرق بسيط.
  • إذا كان كلا المقياسين يتحركان في نفس الاتجاه ، فكل شيء على ما يرام.
  • إذا بدأ مقياس التحقق من الصحة في الركود بينما يستمر مقياس التدريب في التحسن ، فمن المحتمل أنك على وشك الإفراط في التجهيز.
  • إذا كان مقياس التحقق من الصحة يسير في الاتجاه الخاطئ ، فمن الواضح أن النموذج زائد.
plotter.plot(size_histories)
a = plt.xscale('log')
plt.xlim([5, max(plt.xlim())])
plt.ylim([0.5, 0.7])
plt.xlabel("Epochs [Log Scale]")
Text(0.5, 0, 'Epochs [Log Scale]')

بي إن جي

عرض في TensorBoard

كل هذه النماذج كتبت سجلات TensorBoard أثناء التدريب.

افتح عارض لوحة TensorBoard المضمّن داخل دفتر ملاحظات:


# Load the TensorBoard notebook extension
%load_ext tensorboard

# Open an embedded TensorBoard viewer
%tensorboard --logdir {logdir}/sizes

يمكنك عرض نتائج شوط السابق من هذا الكمبيوتر الدفتري على TensorBoard.dev .

TensorBoard.dev هي تجربة مُدارة لاستضافة وتتبع ومشاركة تجارب ML مع الجميع.

هو مدرج أيضا في <iframe> للراحة:

display.IFrame(
    src="https://tensorboard.dev/experiment/vW7jmmF9TmKmy3rbheMQpw/#scalars&_smoothingWeight=0.97",
    width="100%", height="800px")

إذا كنت ترغب في مشاركة TensorBoard النتائج التي يمكن تحميل السجلات ل TensorBoard.dev عن طريق نسخ يلي في خلايا التعليمات البرمجية.

tensorboard dev upload --logdir  {logdir}/sizes

استراتيجيات لمنع فرط التجهيز

وقبل الخوض في مضمون هذا القسم نسخ سجلات التدريب من "Tiny" النموذج أعلاه، لاستخدامه كقاعدة أساسية للمقارنة.

shutil.rmtree(logdir/'regularizers/Tiny', ignore_errors=True)
shutil.copytree(logdir/'sizes/Tiny', logdir/'regularizers/Tiny')
PosixPath('/tmp/tmp_tm13yei/tensorboard_logs/regularizers/Tiny')
regularizer_histories = {}
regularizer_histories['Tiny'] = size_histories['Tiny']

أضف الوزن المنتظم

قد تكون على دراية بمبدأ أوكام Razor: بالنظر إلى تفسيران لشيء ما ، فإن التفسير الأكثر احتمالية أن يكون صحيحًا هو "الأبسط" ، التفسير الذي يقدم أقل قدر من الافتراضات. ينطبق هذا أيضًا على النماذج التي تعلمتها الشبكات العصبية: بالنظر إلى بعض بيانات التدريب وبنية الشبكة ، هناك مجموعات متعددة من قيم الأوزان (نماذج متعددة) التي يمكن أن تشرح البيانات ، والنماذج الأبسط أقل احتمالًا للتغلب عليها من النماذج المعقدة.

"النموذج البسيط" في هذا السياق هو نموذج يكون فيه توزيع قيم المعلمات أقل إنتروبيا (أو نموذج به معلمات أقل تمامًا ، كما رأينا في القسم أعلاه). وبالتالي ، فإن الطريقة الشائعة للتخفيف من فرط التخصيص هي وضع قيود على تعقيد الشبكة عن طريق إجبار أوزانها فقط على أخذ قيم صغيرة ، مما يجعل توزيع قيم الوزن أكثر "انتظامًا". وهذا ما يسمى "تنظيم الوزن" ، ويتم ذلك عن طريق إضافة تكلفة مرتبطة بالحصول على أوزان كبيرة إلى وظيفة الخسارة في الشبكة. تأتي هذه التكلفة في نكهتين:

  • L1 التنظيم ، حيث تكلفة إضافية تتناسب مع القيمة المطلقة للمعاملات الأوزان (أي ما يسمى "القاعدة L1" من الأوزان).

  • L2 التنظيم ، حيث تكلفة إضافية تتناسب مع مربع قيمة معاملات الأوزان (أي ما يسمى المربعة "القاعدة L2" من الأوزان). يُطلق على تنظيم L2 أيضًا اسم انحلال الوزن في سياق الشبكات العصبية. لا تدع اسمًا مختلفًا يربكك: إن تناقص الوزن هو رياضياً هو نفسه بالضبط تنظيم L2.

يدفع تنظيم L1 الأوزان نحو الصفر تمامًا مما يشجع نموذجًا متناثرًا. سيؤدي تنظيم L2 إلى معاقبة معلمات الأوزان دون جعلها متفرقة نظرًا لأن العقوبة تذهب إلى الصفر للأوزان الصغيرة - أحد الأسباب التي تجعل L2 أكثر شيوعًا.

في tf.keras ، يتم إضافة الوزن تسوية عن طريق تمرير حالات الوزن regularizer إلى طبقات كوسائط الكلمات الرئيسية. دعنا نضيف تنظيم وزن L2 الآن.

l2_model = tf.keras.Sequential([
    layers.Dense(512, activation='elu',
                 kernel_regularizer=regularizers.l2(0.001),
                 input_shape=(FEATURES,)),
    layers.Dense(512, activation='elu',
                 kernel_regularizer=regularizers.l2(0.001)),
    layers.Dense(512, activation='elu',
                 kernel_regularizer=regularizers.l2(0.001)),
    layers.Dense(512, activation='elu',
                 kernel_regularizer=regularizers.l2(0.001)),
    layers.Dense(1)
])

regularizer_histories['l2'] = compile_and_fit(l2_model, "regularizers/l2")
Model: "sequential_4"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_14 (Dense)             (None, 512)               14848     
_________________________________________________________________
dense_15 (Dense)             (None, 512)               262656    
_________________________________________________________________
dense_16 (Dense)             (None, 512)               262656    
_________________________________________________________________
dense_17 (Dense)             (None, 512)               262656    
_________________________________________________________________
dense_18 (Dense)             (None, 1)                 513       
=================================================================
Total params: 803,329
Trainable params: 803,329
Non-trainable params: 0
_________________________________________________________________
WARNING:tensorflow:Callback method `on_train_batch_begin` is slow compared to the batch time (batch time: 0.0038s vs `on_train_batch_begin` time: 0.0242s). Check your callbacks.
WARNING:tensorflow:Callback method `on_train_batch_end` is slow compared to the batch time (batch time: 0.0038s vs `on_train_batch_end` time: 0.0199s). Check your callbacks.

Epoch: 0, accuracy:0.5059,  binary_crossentropy:0.7720,  loss:2.2831,  val_accuracy:0.4620,  val_binary_crossentropy:0.7035,  val_loss:2.1321,  
....................................................................................................
Epoch: 100, accuracy:0.6490,  binary_crossentropy:0.5996,  loss:0.6228,  val_accuracy:0.6270,  val_binary_crossentropy:0.5898,  val_loss:0.6131,  
....................................................................................................
Epoch: 200, accuracy:0.6737,  binary_crossentropy:0.5826,  loss:0.6061,  val_accuracy:0.6680,  val_binary_crossentropy:0.5857,  val_loss:0.6096,  
....................................................................................................
Epoch: 300, accuracy:0.6842,  binary_crossentropy:0.5748,  loss:0.5993,  val_accuracy:0.6840,  val_binary_crossentropy:0.5754,  val_loss:0.5998,  
....................................................................................................
Epoch: 400, accuracy:0.6934,  binary_crossentropy:0.5620,  loss:0.5862,  val_accuracy:0.6690,  val_binary_crossentropy:0.5825,  val_loss:0.6066,  
.....................................................................................

l2(0.001) يعني أن كل معامل في المصفوفة وزن طبقة ستضيف 0.001 * weight_coefficient_value**2 إلى فقدان تام للشبكة.

وهذا هو السبب في أننا نراقب binary_crossentropy مباشرة. لأنه لا يحتوي على مكون التنظيم هذا مختلطًا.

، لدرجة أن نفس "Large" نموذج مع L2 ينفذ عقوبة تنظيم أفضل بكثير:

plotter.plot(regularizer_histories)
plt.ylim([0.5, 0.7])
(0.5, 0.7)

بي إن جي

كما ترون، فإن "L2" نموذج النظامية هو الآن أكثر تنافسية مع و "Tiny" نموذج. هذا "L2" النموذج هو أيضا أكثر مقاومة للoverfitting من "Large" نموذج استند على الرغم من وجود نفس العدد من المعلمات.

مزيد من المعلومات

هناك شيئان مهمان يجب ملاحظتهما حول هذا النوع من التنظيم.

أولا: إذا كنت تكتب حلقة التدريب الخاصة بك، فأنت بحاجة للتأكد من أن تطلب من نموذج لخسائر تسوية لها.

result = l2_model(features)
regularization_loss=tf.add_n(l2_model.losses)

ثانيا: هذا التطبيق يعمل بإضافة عقوبات الوزن إلى فقدان النموذج، ومن ثم تطبيق الإجراء الأمثل القياسية بعد ذلك.

هناك طريقة ثانية تقوم بدلاً من ذلك بتشغيل المُحسِّن فقط على الخسارة الأولية ، ثم أثناء تطبيق الخطوة المحسوبة ، يطبق المُحسِّن أيضًا بعض تناقص الوزن. ويعتبر هذا "تنفصل الوزن تسوس" في أبتيميزر مثل optimizers.FTRL و optimizers.AdamW .

أضف التسرب

يعد التسرب من أكثر تقنيات التنظيم فعالية والأكثر استخدامًا للشبكات العصبية ، والتي طورها هينتون وطلابه في جامعة تورنتو.

التفسير البديهي للتسرب هو أنه نظرًا لأن العقد الفردية في الشبكة لا يمكنها الاعتماد على مخرجات الآخرين ، يجب على كل عقدة إخراج ميزات مفيدة بمفردها.

يتكون التسرب ، المطبق على طبقة ، من "إسقاط" عشوائيًا (أي ضبط على الصفر) عدد من ميزات الإخراج للطبقة أثناء التدريب. لنفترض أن طبقة معينة كانت ستعيد عادةً متجهًا [0.2 ، 0.5 ، 1.3 ، 0.8 ، 1.1] لعينة إدخال معينة أثناء التدريب ؛ بعد تطبيق التسرب ، سيكون لهذا المتجه عدد قليل من المدخلات الصفرية موزعة عشوائيًا ، على سبيل المثال [0 ، 0.5 ، 1.3 ، 0 ، 1.1].

"معدل التسرب" هو جزء الميزات التي يتم استبعادها ؛ عادة ما يتم ضبطه بين 0.2 و 0.5. في وقت الاختبار ، لا يتم إسقاط أي وحدات ، وبدلاً من ذلك يتم تقليص قيم مخرجات الطبقة بعامل يساوي معدل التسرب ، وذلك لتحقيق التوازن بين حقيقة أن عدد الوحدات النشطة أكثر من وقت التدريب.

في tf.keras يمكنك إدخال التسرب في الشبكة عن طريق طبقة التسرب الذي يحصل على تطبيقها على إخراج طبقة الحق قبل.

دعنا نضيف طبقتين من Dropout في شبكتنا لنرى مدى نجاحهما في تقليل فرط التخصيص:

dropout_model = tf.keras.Sequential([
    layers.Dense(512, activation='elu', input_shape=(FEATURES,)),
    layers.Dropout(0.5),
    layers.Dense(512, activation='elu'),
    layers.Dropout(0.5),
    layers.Dense(512, activation='elu'),
    layers.Dropout(0.5),
    layers.Dense(512, activation='elu'),
    layers.Dropout(0.5),
    layers.Dense(1)
])

regularizer_histories['dropout'] = compile_and_fit(dropout_model, "regularizers/dropout")
Model: "sequential_5"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_19 (Dense)             (None, 512)               14848     
_________________________________________________________________
dropout (Dropout)            (None, 512)               0         
_________________________________________________________________
dense_20 (Dense)             (None, 512)               262656    
_________________________________________________________________
dropout_1 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_21 (Dense)             (None, 512)               262656    
_________________________________________________________________
dropout_2 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_22 (Dense)             (None, 512)               262656    
_________________________________________________________________
dropout_3 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_23 (Dense)             (None, 1)                 513       
=================================================================
Total params: 803,329
Trainable params: 803,329
Non-trainable params: 0
_________________________________________________________________
WARNING:tensorflow:Callback method `on_train_batch_begin` is slow compared to the batch time (batch time: 0.0040s vs `on_train_batch_begin` time: 0.0241s). Check your callbacks.
WARNING:tensorflow:Callback method `on_train_batch_end` is slow compared to the batch time (batch time: 0.0040s vs `on_train_batch_end` time: 0.0208s). Check your callbacks.

Epoch: 0, accuracy:0.5060,  binary_crossentropy:0.7949,  loss:0.7949,  val_accuracy:0.5140,  val_binary_crossentropy:0.6710,  val_loss:0.6710,  
....................................................................................................
Epoch: 100, accuracy:0.6623,  binary_crossentropy:0.5950,  loss:0.5950,  val_accuracy:0.6840,  val_binary_crossentropy:0.5723,  val_loss:0.5723,  
....................................................................................................
Epoch: 200, accuracy:0.6897,  binary_crossentropy:0.5559,  loss:0.5559,  val_accuracy:0.6800,  val_binary_crossentropy:0.5971,  val_loss:0.5971,  
....................................................................................................
Epoch: 300, accuracy:0.7202,  binary_crossentropy:0.5114,  loss:0.5114,  val_accuracy:0.6800,  val_binary_crossentropy:0.5984,  val_loss:0.5984,  
...............................................
plotter.plot(regularizer_histories)
plt.ylim([0.5, 0.7])
(0.5, 0.7)

بي إن جي

من الواضح من هذه المؤامرة أن كلا من هذه تسوية النهج تحسين سلوك "Large" نموذج. ولكن هذا لا يزال لا يضرب حتى "Tiny" خط الأساس.

بعد ذلك ، جربهما معًا ، واكتشف ما إذا كان ذلك أفضل.

مجمع L2 + التسرب

combined_model = tf.keras.Sequential([
    layers.Dense(512, kernel_regularizer=regularizers.l2(0.0001),
                 activation='elu', input_shape=(FEATURES,)),
    layers.Dropout(0.5),
    layers.Dense(512, kernel_regularizer=regularizers.l2(0.0001),
                 activation='elu'),
    layers.Dropout(0.5),
    layers.Dense(512, kernel_regularizer=regularizers.l2(0.0001),
                 activation='elu'),
    layers.Dropout(0.5),
    layers.Dense(512, kernel_regularizer=regularizers.l2(0.0001),
                 activation='elu'),
    layers.Dropout(0.5),
    layers.Dense(1)
])

regularizer_histories['combined'] = compile_and_fit(combined_model, "regularizers/combined")
Model: "sequential_6"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_24 (Dense)             (None, 512)               14848     
_________________________________________________________________
dropout_4 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_25 (Dense)             (None, 512)               262656    
_________________________________________________________________
dropout_5 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_26 (Dense)             (None, 512)               262656    
_________________________________________________________________
dropout_6 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_27 (Dense)             (None, 512)               262656    
_________________________________________________________________
dropout_7 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_28 (Dense)             (None, 1)                 513       
=================================================================
Total params: 803,329
Trainable params: 803,329
Non-trainable params: 0
_________________________________________________________________
WARNING:tensorflow:Callback method `on_train_batch_begin` is slow compared to the batch time (batch time: 0.0040s vs `on_train_batch_begin` time: 0.0245s). Check your callbacks.
WARNING:tensorflow:Callback method `on_train_batch_end` is slow compared to the batch time (batch time: 0.0040s vs `on_train_batch_end` time: 0.0214s). Check your callbacks.

Epoch: 0, accuracy:0.5056,  binary_crossentropy:0.8201,  loss:0.9784,  val_accuracy:0.5130,  val_binary_crossentropy:0.6691,  val_loss:0.8269,  
....................................................................................................
Epoch: 100, accuracy:0.6409,  binary_crossentropy:0.6052,  loss:0.6362,  val_accuracy:0.6670,  val_binary_crossentropy:0.5831,  val_loss:0.6139,  
....................................................................................................
Epoch: 200, accuracy:0.6673,  binary_crossentropy:0.5893,  loss:0.6147,  val_accuracy:0.6880,  val_binary_crossentropy:0.5666,  val_loss:0.5920,  
....................................................................................................
Epoch: 300, accuracy:0.6724,  binary_crossentropy:0.5814,  loss:0.6092,  val_accuracy:0.6850,  val_binary_crossentropy:0.5638,  val_loss:0.5916,  
....................................................................................................
Epoch: 400, accuracy:0.6791,  binary_crossentropy:0.5764,  loss:0.6061,  val_accuracy:0.6960,  val_binary_crossentropy:0.5536,  val_loss:0.5832,  
....................................................................................................
Epoch: 500, accuracy:0.6750,  binary_crossentropy:0.5722,  loss:0.6037,  val_accuracy:0.6760,  val_binary_crossentropy:0.5583,  val_loss:0.5899,  
....................................................................................................
Epoch: 600, accuracy:0.6818,  binary_crossentropy:0.5651,  loss:0.5989,  val_accuracy:0.6940,  val_binary_crossentropy:0.5422,  val_loss:0.5761,  
....................................................................................................
Epoch: 700, accuracy:0.6882,  binary_crossentropy:0.5594,  loss:0.5943,  val_accuracy:0.6880,  val_binary_crossentropy:0.5436,  val_loss:0.5786,  
....................................................................................................
Epoch: 800, accuracy:0.6886,  binary_crossentropy:0.5567,  loss:0.5927,  val_accuracy:0.6960,  val_binary_crossentropy:0.5446,  val_loss:0.5807,  
....................................................................................................
Epoch: 900, accuracy:0.6994,  binary_crossentropy:0.5535,  loss:0.5907,  val_accuracy:0.6900,  val_binary_crossentropy:0.5463,  val_loss:0.5835,  
................................................
plotter.plot(regularizer_histories)
plt.ylim([0.5, 0.7])
(0.5, 0.7)

بي إن جي

هذا النموذج مع "Combined" التنظيم ومن الواضح أن أفضل واحد حتى الآن.

عرض في TensorBoard

سجلت هذه النماذج أيضًا سجلات TensorBoard.

لفتح عارض tensorboard مضمن داخل دفتر ملاحظات ، انسخ ما يلي في خلية التعليمات البرمجية:

%tensorboard --logdir {logdir}/regularizers

يمكنك عرض نتائج شوط السابق من هذا الكمبيوتر الدفتري على TensorDoard.dev .

هو مدرج أيضا في <iframe> للراحة:

display.IFrame(
    src="https://tensorboard.dev/experiment/fGInKDo8TXes1z7HQku9mw/#scalars&_smoothingWeight=0.97",
    width = "100%",
    height="800px")

تم تحميل هذا مع:

tensorboard dev upload --logdir  {logdir}/regularizers

الاستنتاجات

للتلخيص: فيما يلي أكثر الطرق شيوعًا لمنع فرط التخصيص في الشبكات العصبية:

  • احصل على المزيد من بيانات التدريب.
  • تقليل سعة الشبكة.
  • أضف الوزن المنتظم.
  • أضف التسرب.

نهجان مهمان لم يتم تناولهما في هذا الدليل هما:

  • زيادة البيانات
  • تطبيع الدفعة

تذكر أن كل طريقة يمكن أن تساعد من تلقاء نفسها ، ولكن غالبًا ما يكون الجمع بينها أكثر فعالية.

# MIT License
#
# Copyright (c) 2017 François Chollet
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.