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

في هذه المقالة سأخبرك بكيفية استخدام طريقة نقل التعلم باستخدام مثال التعرف على الصور مع الطعام. سأتحدث عن أدوات التعلم الآلي الأخرى في ورشة عمل
التعلم الآلي والشبكات العصبية للمطورين .
إذا واجهتنا مهمة التعرف على الصور ، فيمكنك استخدام الخدمة الجاهزة. ومع ذلك ، إذا كنت بحاجة إلى تدريب النموذج على مجموعة البيانات الخاصة بك ، فسيتعين عليك القيام بذلك بنفسك.
بالنسبة لمهام نموذجية مثل تصنيف الصور ، يمكنك استخدام البنية الجاهزة (AlexNet و VGG و Inception و ResNet وما إلى ذلك) وتدريب الشبكة العصبية على بياناتك. توجد بالفعل تطبيقات لهذه الشبكات باستخدام أطر مختلفة ، لذلك في هذه المرحلة يمكنك استخدام أحدها كمربع أسود ، دون الخوض في مبدأ عملها بعمق.
ومع ذلك ، تطالب الشبكات العصبية العميقة بكميات كبيرة من البيانات لتقارب التعلم. وغالبًا ما تكون مهمتنا الخاصة لا توجد بيانات كافية لتدريب جميع طبقات الشبكة العصبية بشكل صحيح. نقل التعلم يحل هذه المشكلة.
نقل التعلم لتصنيف الصور
عادة ما تحتوي الشبكات العصبية المستخدمة في التصنيف على الخلايا العصبية الناتجة من
N
في الطبقة الأخيرة ، حيث
N
هي عدد الفئات. يتم التعامل مع ناقلات المخرجات هذه كمجموعة من احتمالات الانتماء إلى فئة. في مهمتنا للتعرف على صور الطعام ، قد يختلف عدد الفصول عن ذلك الموجود في مجموعة البيانات الأصلية. في هذه الحالة ، سيتعين علينا التخلص تمامًا من هذه الطبقة الأخيرة ووضع طبقة جديدة ، مع العدد الصحيح من الخلايا العصبية الناتجة

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

في مثالنا ، سآخذ المكونات (1) و (2) و (3) من
المستودع الخاص بي ، والذي يحتوي على الكود الأكثر خفة - يمكنك اكتشافه بسهولة إذا كنت ترغب في ذلك. سيتم تنفيذ
مثالنا على إطار
TensorFlow الشهير. يمكن العثور على أوزان متدربة مسبقًا (4) مناسبة للإطار المحدد إذا كانت تتوافق مع إحدى البنيات الكلاسيكية. كمجموعة بيانات (5) للمظاهرة سوف أتناول
Food-101 .
نموذج
كنموذج ، نستخدم الشبكة العصبية
VGG الكلاسيكية (بتعبير أدق ،
VGG19 ). على الرغم من بعض العيوب ، يوضح هذا النموذج جودة عالية إلى حد ما. بالإضافة إلى ذلك ، من السهل تحليلها. في TensorFlow Slim ، يبدو وصف النموذج مضغوطًا تمامًا:
import tensorflow as tf import tensorflow.contrib.slim as slim def vgg_19(inputs, num_classes, is_training, scope='vgg_19', weight_decay=0.0005): with slim.arg_scope([slim.conv2d], activation_fn=tf.nn.relu, weights_regularizer=slim.l2_regularizer(weight_decay), biases_initializer=tf.zeros_initializer(), padding='SAME'): with tf.variable_scope(scope, 'vgg_19', [inputs]): net = slim.repeat(inputs, 2, slim.conv2d, 64, [3, 3], scope='conv1') net = slim.max_pool2d(net, [2, 2], scope='pool1') net = slim.repeat(net, 2, slim.conv2d, 128, [3, 3], scope='conv2') net = slim.max_pool2d(net, [2, 2], scope='pool2') net = slim.repeat(net, 4, slim.conv2d, 256, [3, 3], scope='conv3') net = slim.max_pool2d(net, [2, 2], scope='pool3') net = slim.repeat(net, 4, slim.conv2d, 512, [3, 3], scope='conv4') net = slim.max_pool2d(net, [2, 2], scope='pool4') net = slim.repeat(net, 4, slim.conv2d, 512, [3, 3], scope='conv5') net = slim.max_pool2d(net, [2, 2], scope='pool5')
يتم تنزيل أوزان VGG19 ، المدربة على ImageNet ومتوافقة مع TensorFlow ، من المستودع على GitHub من قسم
النماذج المدربة مسبقًا .
mkdir data && cd data wget http://download.tensorflow.org/models/vgg_19_2016_08_28.tar.gz tar -xzf vgg_19_2016_08_28.tar.gz
مجموعة البيانات
كعينة تدريب واعتماد ، سنستخدم مجموعة بيانات
الغذاء 101 العامة ، والتي تحتوي على أكثر من 100 ألف صورة غذائية مقسمة إلى 101 فئة.

تنزيل مجموعة البيانات وتفريغها:
cd data wget http://data.vision.ee.ethz.ch/cvl/food-101.tar.gz tar -xzf food-101.tar.gz
تم تصميم خط البيانات في تدريبنا بحيث نحتاج من مجموعة البيانات إلى تحليل ما يلي:
- قائمة الفئات (الفئات)
- البرنامج التعليمي: قائمة مسارات الصور وقائمة بالإجابات الصحيحة
- مجموعة التحقق من الصحة: قائمة مسارات الصور وقائمة الإجابات الصحيحة
إذا كانت مجموعة البيانات الخاصة بك ، فأنت بحاجة إلى كسر المجموعات بنفسك من أجل
التدريب والتحقق من الصحة . يحتوي Food-101 بالفعل على مثل هذا القسم ، ويتم تخزين هذه المعلومات في دليل التعريف.
DATASET_ROOT = 'data/food-101/' train_data, val_data, classes = data.food101(DATASET_ROOT) num_classes = len(classes)
يتم نقل جميع الوظائف الإضافية المسؤولة عن معالجة البيانات إلى ملف
data.py
منفصل:
data.py from os.path import join as opj import tensorflow as tf def parse_ds_subset(img_root, list_fpath, classes): ''' Parse a meta file with image paths and labels -> img_root: path to the root of image folders -> list_fpath: path to the file with the list (eg train.txt) -> classes: list of class names <- (list_of_img_paths, integer_labels) ''' fpaths = [] labels = [] with open(list_fpath, 'r') as f: for line in f: class_name, image_id = line.strip().split('/') fpaths.append(opj(img_root, class_name, image_id+'.jpg')) labels.append(classes.index(class_name)) return fpaths, labels def food101(dataset_root): ''' Get lists of train and validation examples for Food-101 dataset -> dataset_root: root of the Food-101 dataset <- ((train_fpaths, train_labels), (val_fpaths, val_labels), classes) ''' img_root = opj(dataset_root, 'images') train_list_fpath = opj(dataset_root, 'meta', 'train.txt') test_list_fpath = opj(dataset_root, 'meta', 'test.txt') classes_list_fpath = opj(dataset_root, 'meta', 'classes.txt') with open(classes_list_fpath, 'r') as f: classes = [line.strip() for line in f] train_data = parse_ds_subset(img_root, train_list_fpath, classes) val_data = parse_ds_subset(img_root, test_list_fpath, classes) return train_data, val_data, classes def imread_and_crop(fpath, inp_size, margin=0, random_crop=False): ''' Construct TF graph for image preparation: Read the file, crop and resize -> fpath: path to the JPEG image file (TF node) -> inp_size: size of the network input (eg 224) -> margin: cropping margin -> random_crop: perform random crop or central crop <- prepared image (TF node) ''' data = tf.read_file(fpath) img = tf.image.decode_jpeg(data, channels=3) img = tf.image.convert_image_dtype(img, dtype=tf.float32) shape = tf.shape(img) crop_size = tf.minimum(shape[0], shape[1]) - 2 * margin if random_crop: img = tf.random_crop(img, (crop_size, crop_size, 3)) else:
تدريب نموذجي
يتكون رمز التدريب النموذجي من الخطوات التالية:
- بناء خطوط بيانات قطار / التحقق من الصحة
- بناء الرسوم البيانية للقطارات / التحقق (الشبكات)
- إرفاق دالة تصنيف الخسائر ( خسارة الإنتروبيا ) عبر الرسم البياني للقطار
- الكود المطلوب لحساب دقة التنبؤات على عينة التحقق أثناء التدريب
- منطق لتحميل جداول تم تدريبها مسبقًا من لقطة
- إنشاء هياكل مختلفة للتدريب
- دورة التعلم نفسها (التحسين التكراري)
يتم إنشاء الطبقة الأخيرة من الرسم البياني بالعدد المطلوب من الخلايا العصبية ويتم استبعادها من قائمة المعلمات التي تم تحميلها من لقطة تم تدريبها مسبقًا.
كود التدريب النموذجي import numpy as np import tensorflow as tf import tensorflow.contrib.slim as slim tf.logging.set_verbosity(tf.logging.INFO) import model import data
بعد بدء التدريب ، يمكنك إلقاء نظرة على تقدمه باستخدام أداة TensorBoard ، التي تأتي مجمعة مع TensorFlow وتعمل على تصور المقاييس المختلفة والمعلمات الأخرى.
tensorboard --logdir checkpoints/
في نهاية التدريب في TensorBoard ، نرى صورة مثالية تقريبًا: انخفاض في
فقدان القطار وزيادة في
دقة التحقق
ونتيجة لذلك ، نحصل على اللقطة المحفوظة في
checkpoints/vgg19_food
، والتي
checkpoints/vgg19_food
أثناء اختبار نموذجنا (
الاستدلال ).
اختبار النموذج
اختبار نموذجنا الآن. للقيام بذلك:
- نقوم ببناء رسم بياني جديد مصمم خصيصًا للاستدلال (
is_training=False
) - قم بتحميل أوزان مدربة من لقطة
- قم بتنزيل صورة اختبار الإدخال ومعالجتها مسبقًا.
- دعنا نقود الصورة من خلال الشبكة العصبية ونحصل على التنبؤ
inference.py import sys import numpy as np import imageio from skimage.transform import resize import tensorflow as tf import model

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