1. Ringkasan
Di lab ini, Anda akan mempelajari arsitektur konvolusional modern dan menggunakan pengetahuan Anda untuk menerapkan konvnet sederhana namun efektif yang disebut "squeezenet".
Lab ini mencakup penjelasan teoretis yang diperlukan tentang jaringan saraf konvolusi dan merupakan titik awal yang baik bagi developer yang mempelajari deep learning.
Lab ini adalah Bagian 4 dari seri "Keras di TPU". Anda dapat melakukannya dalam urutan berikut atau secara terpisah.
- Pipeline data berkecepatan TPU: tf.data.Dataset dan TFRecords
- Model Keras pertama Anda, dengan transfer learning
- Jaringan neural konvolusional, dengan Keras dan TPU
- [LAB INI] ConvNets, SqueezeNet, Xception modern, dengan Keras dan TPU
Yang akan Anda pelajari
- Untuk menguasai gaya fungsional Keras
- Untuk membangun model menggunakan arsitektur squeezenet
- Untuk menggunakan TPU agar dapat melatih dengan cepat dan melakukan iterasi pada arsitektur Anda
- Untuk menerapkan augmentasi data dengan tf.data.dataset
- Untuk meningkatkan kualitas model besar (Xception) yang telah dilatih sebelumnya di TPU
Masukan
Jika Anda melihat ada yang tidak beres dalam codelab ini, beri tahu kami. Masukan dapat diberikan melalui masalah GitHub [link masukan].
2. Mulai cepat Google Colaboratory
Lab ini menggunakan Google Colaboratory dan tidak memerlukan penyiapan di pihak Anda. Colaboratory adalah platform notebook online untuk tujuan pendidikan. Layanan ini menawarkan pelatihan CPU, GPU, dan TPU gratis.
Anda dapat membuka notebook contoh ini dan menjalankan beberapa sel untuk memahami Colaboratory.
Memilih backend TPU
Di menu Colab, pilih Runtime > Ubah jenis runtime, lalu pilih TPU. Di codelab ini, Anda akan menggunakan TPU (Tensor Processing Unit) canggih yang didukung untuk pelatihan akselerasi hardware. Koneksi ke runtime akan terjadi secara otomatis pada eksekusi pertama, atau Anda dapat menggunakan tombol "Hubungkan" di pojok kanan atas.
Eksekusi notebook
Jalankan sel satu per satu dengan mengklik sel dan menggunakan Shift-ENTER. Anda juga dapat menjalankan seluruh notebook dengan Runtime > Run all
Daftar isi
Semua notebook memiliki daftar isi. Anda dapat membukanya menggunakan panah hitam di sebelah kiri.
Sel tersembunyi
Beberapa sel hanya akan menampilkan judulnya. Fitur ini adalah fitur notebook khusus Colab. Anda dapat mengkliknya dua kali untuk melihat kode di dalamnya, tetapi biasanya ini tidak terlalu menarik. Biasanya mendukung atau fungsi visualisasi. Anda masih perlu menjalankan sel ini agar fungsi di dalamnya dapat ditentukan.
Autentikasi
Colab dapat mengakses bucket Google Cloud Storage pribadi Anda asalkan Anda mengautentikasi dengan akun yang diotorisasi. Cuplikan kode di atas akan memicu proses autentikasi.
3. [INFO] Apa itu Tensor Processing Unit (TPU)?
Ringkasan
Kode untuk melatih model di TPU di Keras (dan kembali ke GPU atau CPU jika TPU tidak tersedia):
try: # detect TPUs
tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect()
strategy = tf.distribute.TPUStrategy(tpu)
except ValueError: # detect GPUs
strategy = tf.distribute.MirroredStrategy() # for CPU/GPU or multi-GPU machines
# use TPUStrategy scope to define model
with strategy.scope():
model = tf.keras.Sequential( ... )
model.compile( ... )
# train model normally on a tf.data.Dataset
model.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=...)
Hari ini kita akan menggunakan TPU untuk membuat dan mengoptimalkan pengklasifikasi bunga dengan kecepatan interaktif (menit per pelatihan yang dijalankan).
Mengapa TPU?
GPU modern diatur berdasarkan "inti" yang dapat diprogram, yaitu arsitektur yang sangat fleksibel yang memungkinkannya menangani berbagai tugas seperti rendering 3D, deep learning, simulasi fisik, dll. Di sisi lain, TPU memasangkan pemroses vektor klasik dengan unit pengali matriks khusus dan unggul dalam tugas apa pun yang mendominasi perkalian matriks besar, seperti jaringan neural.
Ilustrasi: lapisan jaringan saraf yang padat sebagai perkalian matriks, dengan batch delapan gambar yang diproses melalui jaringan saraf sekaligus. Jalankan perkalian satu baris x kolom untuk memverifikasi bahwa kode tersebut memang melakukan jumlah berbobot dari semua nilai piksel gambar. Lapisan konvolusi juga dapat direpresentasikan sebagai perkalian matriks meskipun sedikit lebih rumit ( penjelasan di sini, di bagian 1).
Hardware
MXU dan VPU
Core TPU v2 terbuat dari Matrix Multiply Unit (MXU) yang menjalankan perkalian matriks dan Vector Processing Unit (VPU) untuk semua tugas lainnya seperti aktivasi, softmax, dll. VPU menangani komputasi float32 dan int32. Di sisi lain, MXU beroperasi dalam format floating point presisi campuran 16-32 bit.
Floating point presisi campuran dan bfloat16
MXU menghitung perkalian matriks menggunakan input bfloat16 dan output float32. Akumulasi perantara dilakukan dalam presisi float32.
Pelatihan jaringan neural biasanya tahan terhadap noise yang dihasilkan oleh presisi floating point yang lebih rendah. Ada kalanya derau bahkan membantu pengoptimal melakukan konvergensi. Presisi floating point 16-bit secara tradisional digunakan untuk mempercepat komputasi, tetapi format float16 dan float32 memiliki rentang yang sangat berbeda. Mengurangi presisi dari float32 menjadi float16 biasanya menghasilkan overflow dan underflow. Ada solusi, tetapi pekerjaan tambahan biasanya diperlukan agar float16 berfungsi.
Itulah sebabnya Google memperkenalkan format bfloat16 di TPU. bfloat16 adalah float32 yang terpotong dengan bit eksponen dan rentang yang sama persis dengan float32. Hal ini, ditambah dengan fakta bahwa TPU menghitung perkalian matriks dalam presisi campuran dengan input bfloat16, tetapi output float32, berarti bahwa biasanya tidak diperlukan perubahan kode untuk mendapatkan manfaat dari peningkatan performa presisi yang dikurangi.
Array sistolik
MXU mengimplementasikan perkalian matriks dalam hardware menggunakan apa yang disebut arsitektur "array sistolik" di mana elemen data mengalir melalui array unit komputasi hardware. (Dalam kedokteran, "sistolik" mengacu pada kontraksi jantung dan aliran darah, di sini adalah aliran data.)
Elemen dasar perkalian matriks adalah perkalian titik antara garis dari satu matriks dan kolom dari matriks lain (lihat ilustrasi di bagian atas bagian ini). Untuk perkalian matriks Y=X*W, satu elemen hasilnya adalah:
Y[2,0] = X[2,0]*W[0,0] + X[2,1]*W[1,0] + X[2,2]*W[2,0] + ... + X[2,n]*W[n,0]
Di GPU, seseorang akan memprogram perkalian titik ini ke dalam "core" GPU, lalu menjalankannya di sebanyak mungkin "core" yang tersedia secara paralel untuk mencoba dan menghitung setiap nilai matriks yang dihasilkan sekaligus. Jika matriks yang dihasilkan berukuran 128x128, diperlukan 128x128=16K "core" yang biasanya tidak tersedia. GPU terbesar memiliki sekitar 4.000 core. Di sisi lain, TPU menggunakan hardware minimum untuk unit komputasi di MXU: hanya multi-akumulator bfloat16 x bfloat16 => float32
, tidak ada yang lain. Ukurannya sangat kecil sehingga TPU dapat menerapkan 16 ribu di MXU 128x128 dan memproses perkalian matriks ini sekaligus.
Ilustrasi: array sistolik MXU. Elemen komputasinya adalah {i>multi-accumulator<i}. Nilai satu matriks dimuat ke dalam array (titik merah). Nilai matriks lain mengalir melalui array (titik abu-abu). Garis vertikal menyebarkan nilai ke atas. Garis horizontal menyebarkan jumlah parsial. Anda dapat mempraktikkan sendiri untuk memverifikasi bahwa saat data mengalir melalui array, Anda akan mendapatkan hasil perkalian matriks yang keluar dari sisi kanan.
Selain itu, saat produk titik sedang dihitung dalam MXU, jumlah perantara hanya mengalir antara unit komputasi yang berdekatan. Data tersebut tidak perlu disimpan dan diambil ke/dari memori atau bahkan file register. Hasil akhirnya adalah arsitektur array sistolik TPU memiliki kepadatan dan keunggulan daya yang signifikan, serta keunggulan kecepatan yang tidak dapat diabaikan dibandingkan GPU, saat menghitung perkalian matriks.
Cloud TPU
Saat meminta satu "Cloud TPU v2" di Google Cloud Platform, Anda akan mendapatkan virtual machine (VM) yang memiliki board TPU yang terhubung ke PCI. Papan TPU memiliki empat chip TPU dual-core. Setiap inti TPU memiliki VPU (Vector Processing Unit) dan MXU (MatriX dikalikan Unit) 128x128. "Cloud TPU" ini kemudian biasanya terhubung melalui jaringan ke VM yang memintanya. Jadi gambaran lengkapnya terlihat seperti ini:
Ilustrasi: VM Anda dengan akselerator "Cloud TPU" yang terpasang pada jaringan. "Cloud TPU" itu sendiri terbuat dari VM dengan papan TPU yang terpasang PCI dengan empat chip TPU dual-core di dalamnya.
Pod TPU
Di pusat data Google, TPU terhubung ke interkoneksi komputasi berperforma tinggi (HPC) yang dapat membuatnya tampak sebagai satu akselerator yang sangat besar. Google menyebutnya pod dan dapat mencakup hingga 512 core TPU v2 atau 2048 TPU v3 core.
Ilustrasi: pod TPU v3. Papan dan rak TPU yang terhubung melalui interkoneksi HPC.
Selama pelatihan, gradien dipertukarkan antar-core TPU menggunakan algoritma all-reduce ( penjelasan yang baik tentang all-reduce di sini). Model yang sedang dilatih dapat memanfaatkan hardware dengan melakukan pelatihan pada ukuran batch yang besar.
Ilustrasi: sinkronisasi gradien selama pelatihan menggunakan algoritma all-reduce di jaringan HPC mesh toroidal 2D Google TPU.
Software
Pelatihan ukuran batch besar
Ukuran batch yang ideal untuk TPU adalah 128 item data per inti TPU, tetapi hardware sudah dapat menunjukkan pemanfaatan yang baik dari 8 item data per inti TPU. Ingat bahwa satu Cloud TPU memiliki 8 core.
Dalam codelab ini, kita akan menggunakan Keras API. Di Keras, batch yang Anda tentukan adalah ukuran batch global untuk seluruh TPU. Batch Anda akan otomatis dibagi menjadi 8 dan dijalankan di 8 core TPU.
Untuk mendapatkan tips performa tambahan, lihat Panduan Performa TPU. Untuk ukuran tumpukan yang sangat besar, perlakuan khusus pada beberapa model mungkin diperlukan. Lihat LARSOptimizer untuk mengetahui detail selengkapnya.
Di balik layar: XLA
Program TensorFlow menentukan grafik komputasi. TPU ini tidak menjalankan kode Python secara langsung, tetapi menjalankan grafik komputasi yang ditentukan oleh program Tensorflow Anda. Di balik layar, compiler bernama XLA (Accelerated Linear Algebra compiler) mengubah grafik Tensorflow dari node komputasi menjadi kode mesin TPU. Compiler ini juga melakukan banyak pengoptimalan lanjutan pada kode dan tata letak memori Anda. Kompilasi terjadi secara otomatis saat tugas dikirim ke TPU. Anda tidak harus menyertakan XLA dalam rantai build secara eksplisit.
Ilustrasi: untuk dijalankan di TPU, grafik komputasi yang ditentukan oleh program Tensorflow Anda pertama-tama diterjemahkan ke representasi XLA (compiler Linear Algebra yang dipercepat), lalu dikompilasi oleh XLA menjadi kode mesin TPU.
Menggunakan TPU di Keras
TPU didukung melalui Keras API mulai Tensorflow 2.1. Dukungan Keras berfungsi di TPU dan pod TPU. Berikut ini contoh yang berfungsi pada TPU, GPU, dan CPU:
try: # detect TPUs
tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect()
strategy = tf.distribute.TPUStrategy(tpu)
except ValueError: # detect GPUs
strategy = tf.distribute.MirroredStrategy() # for CPU/GPU or multi-GPU machines
# use TPUStrategy scope to define model
with strategy.scope():
model = tf.keras.Sequential( ... )
model.compile( ... )
# train model normally on a tf.data.Dataset
model.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=...)
Dalam cuplikan kode ini:
TPUClusterResolver().connect()
menemukan TPU di jaringan. Cloud Endpoints berfungsi tanpa parameter di sebagian besar sistem Google Cloud (tugas AI Platform, Colaboratory, Kubeflow, Deep Learning VM yang dibuat melalui utilitas 'ctpu up'). Sistem ini dapat mengetahui lokasi TPU mereka berkat variabel lingkungan TPU_NAME. Jika Anda membuat TPU secara manual, setel TPU_NAME env. var. di VM yang Anda gunakan, atau panggilTPUClusterResolver
dengan parameter eksplisit:TPUClusterResolver(tp_uname, zone, project)
TPUStrategy
adalah bagian yang menerapkan distribusi dan algoritma sinkronisasi gradien "all-reduce".- Strategi diterapkan melalui cakupan. Model harus ditentukan dalam cakupan strategi().
- Fungsi
tpu_model.fit
mengharapkan objek tf.data.Dataset untuk input untuk pelatihan TPU.
Tugas transfer TPU umum
- Meskipun ada banyak cara untuk memuat data dalam model TensorFlow, penggunaan
tf.data.Dataset
API diperlukan untuk TPU. - TPU sangat cepat dan menyerap data sering kali menjadi bottleneck saat berjalan di TPU. Ada alat yang dapat Anda gunakan untuk mendeteksi bottleneck data dan tips performa lainnya di Panduan Performa TPU.
- angka int8 atau int16 dianggap sebagai int32. TPU tidak memiliki hardware bilangan bulat yang beroperasi pada kurang dari 32 bit.
- Beberapa operasi Tensorflow tidak didukung. Daftarnya ada di sini. Kabar baiknya adalah batasan ini hanya berlaku untuk kode pelatihan, yaitu penerusan maju dan mundur melalui model Anda. Anda tetap dapat menggunakan semua operasi Tensorflow di pipeline input data karena akan dieksekusi di CPU.
tf.py_func
tidak didukung di TPU.
4. [INFO] Pengklasifikasi jaringan neural 101
Ringkasan
Jika semua istilah yang dicetak tebal di paragraf berikutnya sudah diketahui, Anda dapat melanjutkan ke latihan berikutnya. Jika Anda baru mulai mempelajari deep learning, selamat datang, dan silakan terus membaca.
Untuk model yang dibangun sebagai urutan lapisan Keras menawarkan Sequential API. Misalnya, pengklasifikasi gambar yang menggunakan tiga lapisan rapat dapat ditulis di Keras sebagai:
model = tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=[192, 192, 3]),
tf.keras.layers.Dense(500, activation="relu"),
tf.keras.layers.Dense(50, activation="relu"),
tf.keras.layers.Dense(5, activation='softmax') # classifying into 5 classes
])
# this configures the training of the model. Keras calls it "compiling" the model.
model.compile(
optimizer='adam',
loss= 'categorical_crossentropy',
metrics=['accuracy']) # % of correct answers
# train the model
model.fit(dataset, ... )
Jaringan neural rapat
Ini adalah jaringan neural paling sederhana untuk mengklasifikasikan gambar. Sistem itu terdiri dari "neuron" yang tersusun berlapis. Lapisan pertama memproses data input dan memberikan outputnya ke lapisan lain. Lapisan ini disebut "padat" karena setiap neuron terhubung ke semua neuron di lapisan sebelumnya.
Anda bisa memasukkan gambar ke dalam jaringan seperti itu dengan meratakan nilai RGB dari semua pikselnya menjadi vektor yang panjang dan menggunakannya sebagai input. Ini bukan teknik terbaik untuk pengenalan gambar, tetapi kita akan meningkatkannya nanti.
Neuron, aktivasi, RELU
"Neuron" menghitung jumlah berbobot dari semua inputnya, menambahkan nilai yang disebut "bias", dan memasukkan hasilnya melalui "fungsi aktivasi". Bobot dan bias pada awalnya tidak diketahui. Parameter ini akan diinisialisasi secara acak dan "dipelajari" dengan melatih jaringan neural pada banyak data yang diketahui.
Fungsi aktivasi yang paling populer disebut RELU untuk Unit Linear Terarah. Ini adalah fungsi yang sangat sederhana seperti yang dapat Anda lihat pada grafik di atas.
Aktivasi softmax
Jaringan di atas diakhiri dengan lapisan 5 neuron karena kami mengklasifikasikan bunga menjadi 5 kategori (mawar, tulip, dandelion, daisy, bunga matahari). Neuron di lapisan perantara diaktifkan menggunakan fungsi aktivasi RELU klasik. Pada lapisan terakhir, kita ingin menghitung angka antara 0 dan 1 yang mewakili probabilitas bunga ini adalah mawar, tulip, dan seterusnya. Untuk itu, kita akan menggunakan fungsi aktivasi yang disebut "softmax".
Penerapan softmax pada vektor dilakukan dengan mengambil eksponensial dari setiap elemen, lalu menormalisasi vektor, biasanya menggunakan norma L1 (jumlah nilai absolut) sehingga nilainya berjumlah 1 dan dapat ditafsirkan sebagai probabilitas.
Kerugian entropi silang
Setelah jaringan neural menghasilkan prediksi dari gambar input, kita perlu mengukur seberapa bagusnya prediksi tersebut, yaitu jarak antara apa yang diberitahukan jaringan kepada kita dan jawaban yang benar, yang sering disebut "label". Ingatlah bahwa kita memiliki label yang benar untuk semua gambar dalam {i>dataset<i}.
Semua jarak dapat digunakan, tetapi untuk masalah klasifikasi, yang disebut "jarak entropi silang" adalah yang paling efektif. Kita akan menyebutnya fungsi error atau "loss":
Penurunan gradien
"Melatih" jaringan saraf sebenarnya berarti menggunakan gambar dan label pelatihan untuk menyesuaikan bobot dan bias sehingga meminimalkan fungsi loss cross-entropy. Berikut cara kerjanya.
Cross-entropy adalah fungsi bobot, bias, piksel gambar pelatihan, dan class-nya yang diketahui.
Jika kita menghitung turunan parsial dari entropi silang secara relatif terhadap semua bobot dan semua bias, kita memperoleh "gradien", yang dihitung untuk gambar, label, dan nilai sekarang dari bobot dan bias. Ingatlah bahwa kita dapat memiliki jutaan bobot dan bias sehingga menghitung gradien terdengar seperti pekerjaan yang berat. Untungnya, Tensorflow saja yang melakukannya untuk kita. Properti matematika gradien adalah bahwa gradien mengarah "ke atas". Karena kita ingin menuju tempat entropi silang rendah, kita akan menuju ke arah yang berlawanan. Kita memperbarui bobot dan bias dengan menggunakan sebagian kecil dari gradien. Kemudian, kita melakukan hal yang sama berulang kali menggunakan batch gambar dan label pelatihan berikutnya, dalam loop pelatihan. Mudah-mudahan, ini konvergensi ke tempat di mana entropi silang minimal meskipun tidak ada jaminan bahwa minimum ini unik.
Pengelompokan mini dan momentum
Anda dapat menghitung gradien hanya pada satu contoh gambar dan segera memperbarui bobot dan bias, tetapi melakukannya pada batch, misalnya, 128 gambar akan memberikan gradien yang lebih baik mewakili batasan yang diberlakukan oleh berbagai contoh gambar sehingga cenderung akan berkonvergensi ke solusi lebih cepat. Ukuran tumpukan mini adalah parameter yang dapat disesuaikan.
Teknik ini, yang terkadang disebut "stochastic gradient descent", memiliki manfaat lain yang lebih pragmatis: bekerja dengan batch juga berarti bekerja dengan matriks yang lebih besar dan biasanya lebih mudah dioptimalkan di GPU dan TPU.
Namun, konvergensi masih bisa sedikit kacau dan bahkan dapat berhenti jika vektor gradien semuanya nol. Apakah itu berarti kita telah menemukan nilai minimum? Tidak selalu. Komponen gradien dapat bernilai nol pada nilai minimum atau maksimum. Dengan vektor gradien dengan jutaan elemen, jika semuanya bernilai nol, maka probabilitas bahwa setiap nol sesuai dengan nilai minimum dan tidak satu pun dari mereka hingga titik maksimum cukup kecil. Dalam ruang dengan banyak dimensi, titik pelana cukup umum dan kita tidak ingin berhenti di sana.
Ilustrasi: titik pelana. Gradien-nya adalah 0, tetapi bukan nilai minimum di semua arah. (Atribusi gambar Wikimedia: By Nicoguaro - Own work, CC BY 3.0)
Solusinya adalah menambahkan beberapa momentum ke algoritma pengoptimalan sehingga dapat melewati titik pelana tanpa berhenti.
Glosarium
batch atau mini-batch: pelatihan selalu dilakukan pada batch data dan label pelatihan. Tindakan ini membantu algoritma berkonvergensi. Dimensi "batch" biasanya merupakan dimensi pertama dari tensor data. Misalnya, tensor bentuk [100, 192, 192, 3] berisi 100 gambar berukuran 192x192 piksel dengan tiga nilai per piksel (RGB).
kerugian entropi silang: fungsi kerugian khusus yang sering digunakan dalam pengklasifikasi.
lapisan padat: lapisan neuron yang setiap neuronnya terhubung ke semua neuron di lapisan sebelumnya.
fitur: input jaringan saraf terkadang disebut "fitur". Seni untuk mengetahui bagian set data (atau kombinasi bagian) yang akan dimasukkan ke dalam jaringan neural untuk mendapatkan prediksi yang baik disebut "feature engineering".
label: nama lain untuk "class" atau jawaban yang benar dalam masalah klasifikasi berpengawasan
kecepatan pembelajaran: fraksi gradien yang digunakan untuk memperbarui bobot dan bias pada setiap iterasi loop pelatihan.
logits: output dari lapisan neuron sebelum fungsi aktivasi diterapkan disebut "logits". Istilah ini berasal dari "fungsi logistik" atau "fungsi sigmoid" yang dulunya merupakan fungsi aktivasi paling populer. "Output neuron sebelum fungsi logistik" disingkat menjadi "logits".
kerugian: fungsi error yang membandingkan output jaringan neural dengan jawaban yang benar
neuron: menghitung jumlah berbobot dari inputnya, menambahkan bias, dan memasukkan hasilnya melalui fungsi aktivasi.
Encoding one-hot: class 3 dari 5 dienkode sebagai vektor 5 elemen, semua nol kecuali elemen ke-3 yang bernilai 1.
relu: unit linear terarah. Fungsi aktivasi populer untuk neuron.
sigmoid: fungsi aktivasi lain yang dulunya populer dan masih berguna dalam kasus khusus.
softmax: fungsi aktivasi khusus yang bekerja pada vektor, meningkatkan perbedaan antara komponen terbesar dan semua komponen lainnya, dan juga menormalisasi vektor agar memiliki jumlah 1 sehingga dapat ditafsirkan sebagai vektor probabilitas. Digunakan sebagai langkah terakhir dalam pengklasifikasi.
tensor: "Tensor" mirip dengan matriks, tetapi dengan jumlah dimensi yang arbitrer. Tensor 1-dimensi adalah vektor. Tensor 2 dimensi adalah matriks. Dan kemudian Anda dapat memiliki tensor dengan 3, 4, 5 atau lebih dimensi.
5. [INFO] Jaringan neural konvolusional
Ringkasan
Jika semua istilah yang dicetak tebal di paragraf berikutnya sudah Anda ketahui, Anda dapat melanjutkan ke latihan berikutnya. Jika Anda baru memulai jaringan neural konvolusi, lanjutkan membaca.
Ilustrasi: memfilter gambar dengan dua filter berturut-turut yang masing-masing terdiri dari 4x4x3=48 bobot yang dapat dipelajari.
Berikut adalah tampilan jaringan neural konvolusional sederhana di Keras:
model = tf.keras.Sequential([
# input: images of size 192x192x3 pixels (the three stands for RGB channels)
tf.keras.layers.Conv2D(kernel_size=3, filters=24, padding='same', activation='relu', input_shape=[192, 192, 3]),
tf.keras.layers.Conv2D(kernel_size=3, filters=24, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=12, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=6, padding='same', activation='relu'),
tf.keras.layers.Flatten(),
# classifying into 5 categories
tf.keras.layers.Dense(5, activation='softmax')
])
model.compile(
optimizer='adam',
loss= 'categorical_crossentropy',
metrics=['accuracy'])
Jaringan neural konvolusional
Di lapisan jaringan konvolusi, satu "neuron" melakukan jumlah berbobot piksel tepat di atasnya, hanya di area kecil gambar. Lapisan ini menambahkan bias dan memasukkan jumlah melalui fungsi aktivasi, seperti yang dilakukan neuron di lapisan padat reguler. Operasi ini kemudian diulang di seluruh gambar menggunakan bobot yang sama. Ingat bahwa dalam lapisan padat, setiap neuron memiliki bobotnya sendiri. Di sini, satu "patch" bobot bergeser di seluruh gambar dalam kedua arah ("konvolusi"). Output memiliki nilai sebanyak piksel dalam gambar (tetapi beberapa padding diperlukan di bagian tepinya). Ini adalah operasi penyaringan, dengan menggunakan filter dengan bobot 4 x 4 x 3=48.
Namun, 48 bobot tidak akan cukup. Untuk menambahkan lebih banyak derajat kebebasan, kita mengulangi operasi yang sama dengan set berat baru. Tindakan ini akan menghasilkan kumpulan output filter baru. Mari kita sebut sebagai "saluran" output berdasarkan analogi dengan saluran R, G, B dalam gambar input.
Dua set bobot (atau lebih) dapat dijumlahkan sebagai satu tensor dengan menambahkan dimensi baru. Ini memberi kita bentuk umum dari tensor bobot untuk lapisan konvolusional. Karena jumlah saluran input dan output merupakan parameter, kita dapat mulai menumpuk dan merangkai lapisan konvolusional.
Ilustrasi: jaringan neural konvolusional mengubah "kubus" data menjadi "kubus" data lainnya.
Konvolusi berjalan, penggabungan maksimum
Dengan melakukan konvolusi dengan langkah 2 atau 3, kita juga dapat menyusutkan kubus data yang dihasilkan dalam dimensi horizontalnya. Ada dua cara umum untuk melakukannya:
- Konvolusi dengan langkah: filter geser seperti di atas, tetapi dengan langkah >1
- Pengumpulan maksimum: jendela geser yang menerapkan operasi MAX (biasanya pada patch 2x2, diulang setiap 2 piksel)
Ilustrasi: menggeser jendela komputasi sebesar 3 piksel menghasilkan nilai output yang lebih sedikit. Konvolusi melangkah atau penggabungan maksimum (maksimum pada jendela 2x2 yang bergeser dengan langkah 2) adalah cara mengecilkan kubus data dalam dimensi horizontal.
Classifier konvolusi
Terakhir, kita melampirkan kepala klasifikasi dengan meratakan kubus data terakhir dan memasukkannya melalui lapisan padat yang diaktifkan dengan softmax. Pengklasifikasi konvolusional umum dapat terlihat seperti ini:
Ilustrasi: pengklasifikasi gambar yang menggunakan lapisan konvolusional dan softmax. Filter ini menggunakan filter 3x3 dan 1x1. Lapisan maxpool mengambil jumlah maksimal grup titik data 2x2. Head klasifikasi diimplementasikan dengan lapisan padat dengan aktivasi softmax.
Di Keras
Stack konvolusional yang diilustrasikan di atas dapat ditulis dalam Keras seperti ini:
model = tf.keras.Sequential([
# input: images of size 192x192x3 pixels (the three stands for RGB channels)
tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu', input_shape=[192, 192, 3]),
tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=16, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=1, filters=8, padding='same', activation='relu'),
tf.keras.layers.Flatten(),
# classifying into 5 categories
tf.keras.layers.Dense(5, activation='softmax')
])
model.compile(
optimizer='adam',
loss= 'categorical_crossentropy',
metrics=['accuracy'])
6. [INFO BARU] Arsitektur konvolusi modern
Ringkasan
Ilustrasi: "modul" convolutional. Apa yang terbaik untuk saat ini? Lapisan max-pool diikuti oleh lapisan konvolusional 1x1 atau kombinasi lapisan yang berbeda? Coba semuanya, gabungkan hasilnya, dan biarkan jaringan memutuskan. Di sebelah kanan: arsitektur konvolusional " inception" yang menggunakan modul tersebut.
Di Keras, untuk membuat model tempat aliran data dapat bercabang masuk dan keluar, Anda harus menggunakan gaya model "fungsional". Berikut ini contohnya:
l = tf.keras.layers # syntax shortcut
y = l.Conv2D(filters=32, kernel_size=3, padding='same',
activation='relu', input_shape=[192, 192, 3])(x) # x=input image
# module start: branch out
y1 = l.Conv2D(filters=32, kernel_size=1, padding='same', activation='relu')(y)
y3 = l.Conv2D(filters=32, kernel_size=3, padding='same', activation='relu')(y)
y = l.concatenate([y1, y3]) # output now has 64 channels
# module end: concatenation
# many more layers ...
# Create the model by specifying the input and output tensors.
# Keras layers track their connections automatically so that's all that's needed.
z = l.Dense(5, activation='softmax')(y)
model = tf.keras.Model(x, z)
Trik murah lainnya
Filter 3x3 kecil
Dalam ilustrasi ini, Anda melihat hasil dari dua filter 3x3 berturut-turut. Coba lacak kembali titik data mana yang berkontribusi pada hasilnya: dua filter 3x3 berturut-turut ini menghitung beberapa kombinasi dari region 5x5. Ini bukan kombinasi yang sama persis dengan yang akan dihitung oleh filter 5x5 tetapi perlu dicoba karena dua filter 3x3 berturut-turut lebih murah daripada satu filter 5x5.
Konvolusi 1x1?
Dalam istilah matematika, konvolusi "1x1" adalah perkalian dengan konstanta, bukan konsep yang sangat berguna. Namun, dalam jaringan neural konvolusional, ingat bahwa filter diterapkan ke kubus data, bukan hanya gambar 2D. Oleh karena itu, filter "1x1" menghitung jumlah berbobot dari kolom data 1x1 (lihat ilustrasi) dan saat menggesernya ke seluruh data, Anda akan mendapatkan kombinasi linear dari saluran input. Hal ini sebenarnya berguna. Jika Anda menganggap saluran sebagai hasil dari operasi pemfilteran individual, misalnya filter untuk "telinga runcing", yang lain untuk "kumis", dan yang ketiga untuk "mata bercak", maka lapisan konvolusional "1x1" akan menghitung beberapa kemungkinan kombinasi linier dari fitur-fitur ini, yang mungkin berguna saat mencari "kucing". Selain itu, lapisan 1x1 menggunakan bobot yang lebih sedikit.
7. Squeezenet
Cara mudah untuk menyatukan ide-ide ini telah ditampilkan dalam makalah "Squeezenet". Penulis menyarankan desain modul convolutional yang sangat sederhana, hanya menggunakan lapisan convolutional 1x1 dan 3x3.
Ilustrasi: arsitektur squeezenet berdasarkan "modul api". Lapisan ini bergantian dengan lapisan 1x1 yang "memeras" data yang masuk dalam dimensi vertikal, diikuti dengan dua lapisan konvolusi 1x1 dan 3x3 paralel yang "memperluas" kedalaman data lagi.
Langsung
Lanjutkan di notebook sebelumnya dan buat jaringan neural konvolusional yang terinspirasi squeezenet. Anda harus mengubah kode model menjadi "functional style" Keras.
Keras_Flowers_TPU (playground).ipynb
Info tambahan
Akan sangat berguna untuk latihan ini untuk menentukan fungsi bantuan di modul squeezenet:
def fire(x, squeeze, expand):
y = l.Conv2D(filters=squeeze, kernel_size=1, padding='same', activation='relu')(x)
y1 = l.Conv2D(filters=expand//2, kernel_size=1, padding='same', activation='relu')(y)
y3 = l.Conv2D(filters=expand//2, kernel_size=3, padding='same', activation='relu')(y)
return tf.keras.layers.concatenate([y1, y3])
# this is to make it behave similarly to other Keras layers
def fire_module(squeeze, expand):
return lambda x: fire(x, squeeze, expand)
# usage:
x = l.Input(shape=[192, 192, 3])
y = fire_module(squeeze=24, expand=48)(x) # typically, squeeze is less than expand
y = fire_module(squeeze=32, expand=64)(y)
...
model = tf.keras.Model(x, y)
Target kali ini adalah mencapai akurasi 80%.
Hal-hal yang dapat dicoba
Mulai dengan satu lapisan konvolusional, lalu ikuti dengan "fire_modules
", bergantian dengan lapisan MaxPooling2D(pool_size=2)
. Anda dapat bereksperimen dengan 2 hingga 4 lapisan max pooling di jaringan dan juga dengan 1, 2, atau 3 modul fire berturut-turut di antara lapisan max pooling.
Dalam modul aktif, parameter "squeeze" biasanya harus lebih kecil daripada parameter "expand". Parameter ini sebenarnya adalah jumlah filter. Biasanya, rentangnya dapat berkisar dari 8 hingga 196. Anda dapat bereksperimen dengan arsitektur yang jumlah filternya meningkat secara bertahap melalui jaringan, atau arsitektur sederhana yang semua modul fire-nya memiliki jumlah filter yang sama.
Berikut ini contohnya:
x = tf.keras.layers.Input(shape=[*IMAGE_SIZE, 3]) # input is 192x192 pixels RGB
y = tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu')(x)
y = fire_module(24, 48)(y)
y = tf.keras.layers.MaxPooling2D(pool_size=2)(y)
y = fire_module(24, 48)(y)
y = tf.keras.layers.MaxPooling2D(pool_size=2)(y)
y = fire_module(24, 48)(y)
y = tf.keras.layers.GlobalAveragePooling2D()(y)
y = tf.keras.layers.Dense(5, activation='softmax')(y)
model = tf.keras.Model(x, y)
Pada tahap ini, Anda mungkin melihat bahwa eksperimen Anda tidak berjalan dengan baik dan tujuan akurasi 80% tampaknya tidak mungkin tercapai. Saatnya untuk beberapa trik murah lainnya.
Normalisasi Batch
Normalisasi batch akan membantu mengatasi masalah konvergensi yang Anda alami. Akan ada penjelasan mendetail tentang teknik ini di workshop berikutnya. Untuk saat ini, gunakan sebagai helper "ajaib" kotak hitam dengan menambahkan baris ini setelah setiap lapisan konvolusi di jaringan Anda, termasuk lapisan di dalam fungsi fire_module:
y = tf.keras.layers.BatchNormalization(momentum=0.9)(y)
# please adapt the input and output "y"s to whatever is appropriate in your context
Parameter momentum harus dikurangi dari nilai default 0,99 menjadi 0,9 karena set data kita kecil. Untuk sekarang, abaikan detail ini.
Pengayaan data
Anda akan mendapatkan beberapa poin persentase lagi dengan meningkatkan data dengan transformasi yang mudah seperti membalik kiri-kanan perubahan saturasi:
Hal ini sangat mudah dilakukan di Tensorflow dengan tf.data.Dataset API. Tentukan fungsi transformasi baru untuk data Anda:
def data_augment(image, label):
image = tf.image.random_flip_left_right(image)
image = tf.image.random_saturation(image, lower=0, upper=2)
return image, label
Kemudian gunakan dalam transformasi data akhir Anda ("set data pelatihan dan validasi", fungsi "get_batched_dataset"):
dataset = dataset.repeat() # existing line
# insert this
if augment_data:
dataset = dataset.map(data_augment, num_parallel_calls=AUTO)
dataset = dataset.shuffle(2048) # existing line
Jangan lupa untuk membuat augmentasi data menjadi opsional dan menambahkan kode yang diperlukan untuk memastikan hanya set data pelatihan yang ditingkatkan. Tidak masuk akal untuk menambah set data validasi.
Akurasi 80% dalam 35 epoch kini akan dapat dicapai.
Solusi
Berikut adalah notebook solusinya. Anda dapat menggunakannya jika mengalami kesulitan.
Keras_Flowers_TPU_squeezenet.ipynb
Yang telah kita bahas
- 🤔 Model "gaya fungsional" keras
- 🤓 Arsitektur Squeezenet
- 🤓 Augmentasi data dengan tf.data.datset
Luangkan waktu sejenak untuk membaca {i>checklist<i} ini di kepala Anda.
8. Xception disesuaikan
Konvolusi yang dapat dipisahkan
Cara lain untuk menerapkan lapisan konvolusi telah menjadi populer baru-baru ini: konvolusi yang dapat dipisahkan kedalamannya. Saya tahu, tidak masuk akal, tetapi konsepnya cukup sederhana. Class ini diimplementasikan di Tensorflow dan Keras sebagai tf.keras.layers.SeparableConv2D
.
Konvolusi yang dapat dipisahkan juga menjalankan filter pada gambar, tetapi menggunakan kumpulan bobot yang berbeda untuk setiap saluran gambar input. Langkah ini diikuti dengan "konvolusi 1x1", serangkaian perkalian titik yang menghasilkan jumlah berbobot dari saluran yang difilter. Dengan bobot baru setiap kali, sebanyak mungkin rekombinasi berbobot dari saluran dihitung sesuai kebutuhan.
Ilustrasi: konvolusi yang dapat dipisahkan. Fase 1: konvolusi dengan filter terpisah untuk setiap saluran. Fase 2: rekombinasi linear saluran. Diulang dengan kumpulan bobot baru hingga jumlah saluran output yang diinginkan tercapai. Fase 1 juga dapat diulang, dengan bobot baru setiap waktu, tetapi dalam praktiknya jarang demikian.
Konvolusi yang dapat dipisahkan digunakan dalam arsitektur jaringan konvolusi terbaru: MobileNetV2, Xception, EfficientNet. Omong-omong, MobileNetV2 adalah model yang Anda gunakan untuk pemelajaran transfer sebelumnya.
Mereka lebih murah daripada konvolusi reguler dan telah terbukti sama efektifnya dalam praktiknya. Berikut adalah jumlah bobot untuk contoh yang diilustrasikan di atas:
Lapisan konvolusi: 4 x 4 x 3 x 5 = 240
Lapisan konvolusi yang dapat dipisahkan: 4 x 4 x 3 + 3 x 5 = 48 + 15 = 63
Hal ini dibiarkan sebagai latihan bagi pembaca untuk menghitung jumlah perkalian yang diperlukan untuk menerapkan setiap gaya skala lapisan konvolusi dengan cara yang serupa. Konvolusi yang dapat dipisahkan lebih kecil dan jauh lebih efektif secara komputasi.
Langsung
Mulai ulang dari notebook playground "pembelajaran transfer", tetapi kali ini pilih Xception sebagai model terlatih. Xception hanya menggunakan konvolusi yang dapat dipisahkan. Biarkan semua bobot dapat dilatih. Kita akan menyesuaikan bobot terlatih pada data kita, bukan menggunakan lapisan terlatih seperti itu.
Keras Flowers transfer learning (playground).ipynb
Sasaran: akurasi > 95% (Tidak, serius, itu mungkin!)
Ujian ini adalah latihan terakhir, dan latihan ini membutuhkan lebih banyak kode dan pekerjaan sains data.
Info tambahan tentang fine-tuning
Xception tersedia dalam model standar terlatih di tf.keras.application.* Jangan lupa untuk membiarkan semua bobot dapat dilatih kali ini.
pretrained_model = tf.keras.applications.Xception(input_shape=[*IMAGE_SIZE, 3],
include_top=False)
pretrained_model.trainable = True
Untuk mendapatkan hasil yang baik saat menyesuaikan model, Anda harus memperhatikan kecepatan pembelajaran dan menggunakan jadwal kecepatan pembelajaran dengan periode peningkatan. Seperti ini:
Memulai dengan kecepatan pembelajaran standar akan mengganggu bobot model yang telah dilatih sebelumnya. Mulai secara bertahap mempertahankannya hingga model telah terkunci pada data Anda sehingga dapat mengubahnya dengan cara yang masuk akal. Setelah ramp, Anda dapat melanjutkan dengan kecepatan pemelajaran yang konstan atau menurun secara eksponensial.
Di Keras, kecepatan pemelajaran ditentukan melalui callback yang memungkinkan Anda menghitung kecepatan pemelajaran yang sesuai untuk setiap epoch. Keras akan meneruskan kecepatan pemelajaran yang benar ke pengoptimal untuk setiap epoch.
def lr_fn(epoch):
lr = ...
return lr
lr_callback = tf.keras.callbacks.LearningRateScheduler(lr_fn, verbose=True)
model.fit(..., callbacks=[lr_callback])
Solusi
Berikut adalah notebook solusinya. Anda dapat menggunakannya jika mengalami kesulitan.
07_Keras_Flowers_TPU_xception_fine_tuned_best.ipynb
Yang telah kita bahas
- 🤔 Konvolusi yang dapat dipisahkan kedalamannya
- 🤓 Jadwal kecepatan pembelajaran
- 📈 Meningkatkan kualitas model terlatih.
Luangkan waktu sejenak untuk mengingat checklist ini.
9. Selamat!
Anda telah membangun jaringan neural konvolusional modern pertama Anda dan melatihnya hingga akurasi 90% +, sehingga melakukan iterasi pada pelatihan berturut-turut hanya dalam hitungan menit berkat TPU. Ini adalah akhir dari 4 "codelab Keras di TPU":
- Pipeline data berkecepatan TPU: tf.data.Dataset dan TFRecords
- Model Keras pertama Anda, dengan pemelajaran transfer
- Jaringan neural konvolusional, dengan Keras dan TPU
- [THIS LAB] ConvNets, SqueezeNet, Xception modern, dengan Keras dan TPU
TPU dalam praktik
TPU dan GPU tersedia di Cloud AI Platform:
- Di VM Deep Learning
- Di AI Platform Notebooks
- Dalam tugas Pelatihan AI Platform
Terakhir, kami senang menerima masukan. Beri tahu kami jika Anda melihat ada yang tidak beres di lab ini atau jika menurut Anda ada yang perlu ditingkatkan. Masukan dapat diberikan melalui masalah GitHub [ link masukan].
|