كيفية استخدام تعلم النقل والضبط في Keras و Tensorflow لإنشاء نظام للتعرف على الصور وتصنيف (تقريبًا) أي كائن

أمثلة على الصور من مجموعة بيانات CompCars (163 سيارة ، 1713 سيارة نماذج)
انتقل مباشرة إلى الكود على جيثب هنا!

في المنشور الأخير ، قمت بتغطية كيفية استخدام Keras للتعرف على أي من فئات الكائنات 1000 في تحدي التعرف المرئي ImageNet. لكن في أغلب الأحيان ، فإن الفئات التي نرغب في التنبؤ بها ليست في تلك القائمة.

فماذا نفعل إذا كنت تريد التصنيف بين الطرز المختلفة من النظارات الشمسية؟ أو الأحذية؟ أو تعبيرات الوجه؟ أو نماذج مختلفة من السيارات؟ أو أنواع مختلفة من أمراض الرئة في صور الأشعة السينية؟

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

  1. قم ببناء نظام للتعرف على الصور لفئة 1000 كائن يومي (ImageNet ILSVRC) باستخدام Keras و TensorFlow
  2. أنشئ نظامًا للتعرف على الصور لأي فئات كائنات قابلة للتخصيص باستخدام تعلم النقل والضبط في Keras و TensorFlow (هذه المشاركة)
  3. أنشئ نظامًا لكشف كائنات الصندوق المحيط في الوقت الفعلي لمئات فئات الكائنات اليومية (PASCAL VOC، COCO)
  4. أنشئ خدمة ويب لأي نظام للتعرف على الصور أو نظام الكشف عن الأشياء

لماذا استخدام نقل التعلم / صقل؟

من المعروف أن الشبكات التلافيفية تتطلب كميات كبيرة من البيانات والموارد لتدريبها. على سبيل المثال ، تم تدريب نموذج ImageNet ILSVRC على 1.2 مليون صورة خلال فترة 2-3 أسابيع عبر وحدات معالجة الرسومات المتعددة.

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

ويفعل جيدا بشكل مذهل! أظهر Razavian et al (2014) أنه ببساطة عن طريق استخدام الميزات المستخرجة باستخدام الأوزان من نموذج تم تدريبه من ImageNet ILSVRC ، حققوا أحدث أداء أو بالقرب من أحدث طراز على مجموعة كبيرة ومتنوعة من رؤية الكمبيوتر مهام.

هناك طريقتان يمكننا اتباعهما:

  1. نقل التعلم: خذ ConvNet الذي تم تدريبه مسبقًا على ImageNet ، وأزل آخر طبقة متصلة بشكل كامل ، ثم تعامل مع بقية ConvNet كمستخرج للميزات لمجموعة البيانات الجديدة. بمجرد استخراج الميزات لجميع الصور ، قم بتدريب المصنف لمجموعة البيانات الجديدة.
  2. الضبط الدقيق: استبدل المصنف وأعيد تدريبه أعلى ConvNet ، وكذلك صقل أوزان الشبكة المدربة مسبقًا عبر backpropagation.

أي لاستخدام؟

هناك عاملان رئيسيان سيؤثران على اختيارك للنهج:

  1. حجم مجموعة البيانات الخاصة بك
  2. تشابه مجموعة البيانات الخاصة بك مع مجموعة البيانات المدربة مسبقًا (عادةً ImageNet)
مأخوذة من http://cs231n.github.io/

* يجب عليك أيضًا تجربة التدريب من نقطة الصفر أيضًا.

يصف الشكل أعلاه والرموز أدناه بعض النصائح العامة لمعرفة متى يتم اختيار الطريقة.

  • مجموعة بيانات متشابهة وصغيرة: تجنّب التجهيز الزائد عن طريق عدم ضبط الأوزان على مجموعة بيانات صغيرة ، واستخدم ميزات مستخرجة من أعلى المستويات في ConvNet لزيادة تشابه مجموعة البيانات.
  • مجموعة بيانات مختلفة وصغيرة: تجنّب التجهيز الزائد عن طريق عدم ضبط الأوزان على مجموعة بيانات صغيرة ، واستخدم ميزات مستخرجة من مستويات أقل في ConvNet وأكثر تعميماً.
  • مجموعة البيانات المتشابهة والكبيرة: باستخدام مجموعة البيانات الكبيرة ، يمكننا ضبط الأوزان بأقل فرصة لتجاوز بيانات التدريب.
  • مجموعة بيانات مختلفة وكبيرة: باستخدام مجموعة بيانات كبيرة ، يمكننا مرة أخرى ضبط الأوزان بأقل فرصة للتلبيس.

زيادة البيانات

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

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

زيادة البيانات عن طريق التقليب الأفقي والمحصول العشوائي

مثال على التحولات: غضب لون البكسل ، الدوران ، القص ، الاقتصاص العشوائي ، التقليب الأفقي ، التمدد ، تصحيح العدسة.

نقل التعلم وصقل التنفيذ

انتقل مباشرة إلى الكود على جيثب هنا!

إعداد البيانات

عينات من الصور من Kaggle’s Cat vs Dog dataset

سنستخدم مجموعة بيانات Kaggle’s Dogs vs Cats كمثال لدينا ، ونعد بياناتنا بدليل تدريب ودليل للتحقق من الصحة بهذه الطريقة:

train_dir /
  الكلب/
  قط/
val_dir /
  الكلب/
  قط/

التنفيذ

لنبدأ بإعداد مولدات البيانات لدينا:

train_datagen = ImageDataGenerator (
    preprocessing_function = preprocess_input،
    rotation_range = 30،
    width_shift_range = 0.2،
    height_shift_range = 0.2،
    shear_range = 0.2،
    zoom_range = 0.2،
    horizontal_flip = صحيح
)
test_datagen = ImageDataGenerator (
    preprocessing_function = preprocess_input،
    rotation_range = 30،
    width_shift_range = 0.2،
    height_shift_range = 0.2،
    shear_range = 0.2،
    zoom_range = 0.2،
    horizontal_flip = صحيح
)
train_generator = train_datagen.flow_from_directory (
  args.train_dir،
  target_size = (IM_WIDTH ، IM_HEIGHT) ،
  batch_size = batch_size،
)
validation_generator = test_datagen.flow_from_directory (
  args.val_dir،
  target_size = (IM_WIDTH ، IM_HEIGHT) ،
  batch_size = batch_size،
)

استرجع من مدوّنتنا السابقة على التعرف على الصور أهمية خطوة المعالجة المسبقة. يتم تعيين هذا بواسطة preprocessing_function = preprocess_input حيث يكون preprocess_input من الوحدة النمطية keras.applications.inception_v3.

نطاقات التدوير ، والتحول ، والقص ، والتكبير / التقليب ، وتتراوح إشارة لتحولات زيادة البيانات الخاصة بهم.

بعد ذلك ، سننشئ شبكة InceptionV3 من وحدة keras.applications.

base_model = InceptionV3 (الأوزان = 'imagenet' ، include_top = False)

نستخدم العلامة include_top = False لاستبعاد أوزان آخر طبقة متصلة بشكل كامل نظرًا لأن ذلك خاص بمسابقة ImageNet ، التي تم تدريب الأوزان عليها سابقًا. سنقوم بإضافة طبقة أخيرة جديدة وتهيئتها:

def add_new_last_layer (base_model، nb_classes):
  "" "إضافة الطبقة الأخيرة إلى convnet
  وسائط:
    base_model: نموذج keras باستثناء الجزء العلوي
    nb_classes: # من الفئات
  عائدات:
    نموذج keras جديد مع الطبقة الأخيرة
  "" "
  س = base_model.output
  x = GlobalA AveragePooling2D () (x)
  x = الكثافة (FC_SIZE ، التنشيط = "relu") (x)
  التنبؤات = كثيفة (nb_classes ، التنشيط = "softmax") (x)
  نموذج = نموذج (مدخلات = base_model.input ، مخرجات = تنبؤات)
  نموذج العودة

يحول GlobalAmediatePooling2D مخرجات الموتر MxNxC إلى موتر 1xC حيث C هي # القنوات.

ثم نضيف طبقة كثيفة متصلة تمامًا بحجم 1024 ، ووظيفة softmax في الإخراج لضغط القيم بين [0،1].

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

  1. نقل التعلم: قم بتجميد كل شيء ما عدا الطبقة قبل الأخيرة وإعادة تدريب آخر طبقة كثيفة
  2. صقل: إلغاء تجميد الطبقات التلافيفية السفلية وإعادة تدريب طبقات أخرى

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

نقل التعلم

def setup_to_transfer_learn (نموذج ، base_model):
  "" "تجميد جميع الطبقات وتجميع النموذج" ""
  للطبقة في base_model.layers:
    layer.trainable = خطأ
  model.compile (محسن = 'rmsprop،
                فقدان = 'categorical_crossentropy،
                مقاييس = [ 'دقة'])

ضبط دقيق

def setup_to_finetune (نموذج):
   "" "قم بتجميد الجزء السفلي NB_IV3_LAYERS وإعادة ترتيب الجزء العلوي المتبقي
      طبقات.
   ملاحظة: NB_IV3_LAYERS يتوافق مع أهم كتبي بداية في
         الهندسة المعمارية inceptionv3
   وسائط:
     نموذج: نموذج keras
   "" "
   للطبقة في model.layers [: NB_IV3_LAYERS_TO_FREEZE]:
      layer.trainable = خطأ
   للطبقة في model.layers [NB_IV3_LAYERS_TO_FREEZE:]:
      layer.trainable = صحيح
   model.compile (محسن = SGD (lr = 0.0001 ، قوة دفع = 0.9) ،
                 فقدان = 'categorical_crossentropy')

عند الصقل ، من المهم خفض معدل التعلم الخاص بك مقارنةً بالمعدل الذي تم استخدامه عند التدريب من نقطة الصفر (lr = 0.0001) ، وإلا ، فإن التحسين قد يزعزع الاستقرار ويتباين الفقد.

تدريب

الآن نحن جميعا على استعداد للتدريب. استخدم fit_generator لتعلم النقل والتحسين.

السجل = model.fit_generator (
  train_generator،
  samples_per_epoch = nb_train_samples،
  nb_epoch = nb_epoch،
  validation_data = validation_generator،
  nb_val_samples = nb_val_samples،
  class_weight = 'السيارات'
)
model.save (args.output_model_file)

سنستخدم مثيل Amazon EC2 g2.2xlarge للتدريب. إذا لم تكن معتادًا على AWS ، فراجع هذا البرنامج التعليمي (بدلاً من استخدام AMI الموصوف ، ابحث في مجتمع AMI عن "التعلم العميق" - لهذا المنشور ، استخدمت ami-638c1eo3in US-West-Oregon.

يمكننا رسم دقة التدريب والخسارة باستخدام كائن السجل

def plot_training (التاريخ):
  acc = history.history ['acc']
  val_acc = history.history ['val_acc']
  الخسارة = التاريخ. التاريخ ['الخسارة]]
  val_loss = history.history ['val_loss']
  عصر = المدى (لين (acc))
  
  plt.plot (عهود ، لجنة التنسيق الإدارية ، 'ص.')
  plt.plot (الحقبة ، val_acc ، 'r')
  plt.title ('دقة التدريب والتحقق من الصحة')
  
  plt.figure ()
  plt.plot (عهود ، خسارة ، 'ص.')
  plt.plot (الحقبة ، val_loss ، 'r-')
  plt.title ('التدريب وفقدان التحقق من الصحة')
  plt.show ()

تنبؤ

الآن بعد أن أصبح لدينا keras.model محفوظ ، يمكننا تعديل نفس وظيفة التنبؤ () التي كتبناها في آخر منشور للمدونة للتنبؤ بفئة ملف صورة محلي أو أي ملف عبر عنوان URL على الويب. تحقق من جيثب للبرنامج الكامل.

python Forecast.py --image dog.001.jpg - نموذج dc.model
بيثون Forecast.py - image_url https://goo.gl/Xws7Tp - نموذج dc.model

لقد انتهينا!

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

سجل المقاييس بعد 2 عصر
قم بتنزيل النموذج المدربين هنا *

* نموذج متوافق مع keras == 1.2.2

أمثلة

بيثون Forecast.py - image_url https://goo.gl/Xws7Tp - نموذج dc.model

بيثون Forecast.py --image_url https://goo.gl/6TRUol - نموذج dc.model

ترقبوا المنشور التالي في السلسلة:

  1. قم ببناء نظام للتعرف على الصور لفئة 1000 كائن يومي (ImageNet ILSVRC) باستخدام Keras و TensorFlow
  2. أنشئ نظامًا للتعرف على الصور لأي فئات كائنات قابلة للتخصيص باستخدام تعلم النقل والضبط في Keras و TensorFlow (هذه المشاركة)
  3. أنشئ نظامًا لكشف كائنات الصندوق المحيط في الوقت الفعلي لمئات فئات الكائنات اليومية (PASCAL VOC، COCO)
  4. أنشئ خدمة ويب لأي نظام للتعرف على الصور أو نظام الكشف عن الأشياء

إذا كان لديك أي أسئلة اتصل بي على greg.ht.chu@gmail.com أو أرسل لي رسالة على LinkedIn!

إذا كنت قد استمتعت بهذا ، يرجى الضغط على the