Pembelajaran mesin menjadi lebih mudah diakses, ada lebih banyak peluang untuk menerapkan teknologi ini menggunakan “komponen yang tidak tersedia”. Sebagai contoh, Transfer Learning memungkinkan Anda untuk menggunakan pengalaman yang diperoleh dalam menyelesaikan satu masalah untuk memecahkan masalah lain yang serupa. Jaringan saraf pertama kali dilatih tentang sejumlah besar data, kemudian pada target yang ditetapkan.

Pada artikel ini saya akan memberi tahu Anda cara menggunakan metode Transfer Learning menggunakan contoh pengenalan gambar dengan makanan. Saya akan berbicara tentang alat pembelajaran mesin lainnya di lokakarya
Machine Learning dan Neural Networks for Developers .
Jika kita dihadapkan pada tugas pengenalan gambar, Anda dapat menggunakan layanan yang sudah jadi. Namun, jika Anda perlu melatih model pada set data Anda sendiri, Anda harus melakukannya sendiri.
Untuk tugas-tugas umum seperti klasifikasi gambar, Anda dapat menggunakan arsitektur yang sudah jadi (AlexNet, VGG, Inception, ResNet, dll.) Dan melatih jaringan saraf pada data Anda. Implementasi jaringan seperti itu menggunakan berbagai kerangka kerja yang sudah ada, jadi pada tahap ini Anda dapat menggunakan salah satunya sebagai kotak hitam, tanpa mempelajari prinsip operasinya secara mendalam.
Namun, jaringan saraf yang dalam menuntut data dalam jumlah besar untuk konvergensi pembelajaran. Dan seringkali dalam tugas khusus kita tidak ada cukup data untuk melatih semua lapisan jaringan saraf dengan benar. Transfer Learning memecahkan masalah ini.
Transfer Pembelajaran untuk Klasifikasi Gambar
Jaringan saraf yang digunakan untuk klasifikasi biasanya mengandung neuron keluaran
N
di lapisan terakhir, di mana
N
adalah jumlah kelas. Seperti vektor keluaran diperlakukan sebagai satu set probabilitas milik kelas. Dalam tugas kami mengenali gambar makanan, jumlah kelas mungkin berbeda dari yang ada di dataset asli. Dalam hal ini, kita harus benar-benar membuang lapisan terakhir ini dan memasukkan yang baru, dengan jumlah neuron output yang tepat

Seringkali di akhir jaringan klasifikasi, lapisan yang terhubung sepenuhnya digunakan. Karena kami mengganti lapisan ini, menggunakan bobot yang sudah dilatih sebelumnya untuk itu tidak akan berfungsi. Anda harus melatihnya dari awal, menginisialisasi bobotnya dengan nilai acak. Kami memuat bobot untuk semua lapisan lainnya dari snapshot yang sudah dilatih sebelumnya.
Ada berbagai strategi untuk pelatihan model selanjutnya. Kami akan menggunakan yang berikut ini: kami akan melatih seluruh jaringan dari ujung ke ujung (
ujung ke ujung ), dan kami tidak akan memperbaiki bobot pra-pelatihan untuk memungkinkan mereka menyesuaikan sedikit dan menyesuaikan dengan data kami. Proses ini disebut
fine-tuning .
Komponen struktural
Untuk mengatasi masalah tersebut, kita membutuhkan komponen berikut:
- Deskripsi model jaringan saraf
- Pipa belajar
- Pipa interferensi
- Bobot pra-terlatih untuk model ini
- Data untuk pelatihan dan validasi

Dalam contoh kita, saya akan mengambil komponen (1), (2) dan (3) dari
repositori saya sendiri , yang berisi kode paling ringan - Anda dapat dengan mudah mengetahuinya jika Anda mau. Contoh kami akan diimplementasikan pada kerangka kerja
TensorFlow yang populer. Bobot pra-terlatih (4) yang cocok untuk kerangka kerja yang dipilih dapat ditemukan jika sesuai dengan salah satu arsitektur klasik. Sebagai dataset (5) untuk demonstrasi saya akan mengambil
Food-101 .
Model
Sebagai model, kami menggunakan jaringan saraf
VGG klasik (lebih tepatnya,
VGG19 ). Meskipun ada beberapa kelemahan, model ini menunjukkan kualitas yang cukup tinggi. Selain itu, mudah untuk dianalisis. Pada TensorFlow Slim, deskripsi model terlihat cukup ringkas:
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')
Bobot untuk VGG19, dilatih di ImageNet dan kompatibel dengan TensorFlow, diunduh dari repositori di GitHub dari bagian
Model Pra-terlatih .
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
Datacet
Sebagai sampel pelatihan dan validasi, kami akan menggunakan dataset
Food-101 publik, yang berisi lebih dari 100 ribu gambar makanan, dibagi menjadi 101 kategori.

Unduh dan buka paket dataset:
cd data wget http://data.vision.ee.ethz.ch/cvl/food-101.tar.gz tar -xzf food-101.tar.gz
Pipa data dalam pelatihan kami dirancang sehingga dari dataset kami perlu menguraikan berikut ini:
- Daftar kelas (kategori)
- Tutorial: daftar jalur ke gambar dan daftar jawaban yang benar
- Kumpulan validasi: daftar jalur ke gambar dan daftar jawaban yang benar
Jika dataset Anda, maka untuk
kereta dan
validasi Anda perlu memecahkan set sendiri. Food-101 sudah memiliki partisi seperti itu, dan informasi ini disimpan di direktori
meta
.
DATASET_ROOT = 'data/food-101/' train_data, val_data, classes = data.food101(DATASET_ROOT) num_classes = len(classes)
Semua fungsi tambahan yang bertanggung jawab untuk pemrosesan data dipindahkan ke file
data.py
terpisah:
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:
Pelatihan model
Kode pelatihan model terdiri dari langkah-langkah berikut:
- Membangun jalur data kereta / validasi
- Membangun kereta / grafik validasi (jaringan)
- Lampiran fungsi klasifikasi kerugian ( cross entropy loss ) di atas grafik kereta
- Kode diperlukan untuk menghitung keakuratan prediksi pada sampel validasi selama pelatihan
- Logika untuk memuat skala pra-terlatih dari snapshot
- Membuat berbagai struktur untuk pembelajaran
- Siklus pembelajaran itu sendiri (optimasi berulang)
Lapisan terakhir grafik dikonstruksi dengan jumlah neuron yang diperlukan dan dikeluarkan dari daftar parameter yang dimuat dari snapshot pra-terlatih.
Kode Pelatihan Model 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
Setelah memulai pelatihan, Anda dapat melihat progresnya menggunakan utilitas TensorBoard, yang dilengkapi dengan TensorFlow dan berfungsi untuk memvisualisasikan berbagai metrik dan parameter lainnya.
tensorboard --logdir checkpoints/
Pada akhir pelatihan di TensorBoard, kami melihat gambaran yang hampir sempurna: penurunan
kehilangan kereta dan peningkatan
Akurasi Validasi
Hasilnya, kami mendapatkan snapshot yang disimpan di
checkpoints/vgg19_food
, yang akan kami gunakan selama pengujian model kami (
inferensi ).
Pengujian model
Sekarang uji model kami. Untuk melakukan ini:
- Kami membuat grafik baru yang dirancang khusus untuk inferensi (
is_training=False
) - Memuat bobot terlatih dari foto
- Unduh dan preprocess gambar uji input.
- Mari kita mengarahkan gambar melalui jaringan saraf dan mendapatkan prediksi
inference.py import sys import numpy as np import imageio from skimage.transform import resize import tensorflow as tf import model

Semua kode, termasuk sumber daya untuk membangun dan menjalankan wadah Docker dengan semua versi perpustakaan yang diperlukan, ada di
repositori ini - pada saat membaca artikel, kode dalam repositori mungkin memiliki pembaruan.
Pada lokakarya
"Pembelajaran Mesin dan Jaringan Saraf Tiruan untuk Pengembang" Saya akan menganalisis tugas pembelajaran mesin lainnya, dan siswa akan mempresentasikan proyek mereka pada akhir sesi intensif.