TensorFlow, Keras, dan deep learning tanpa PhD

Dalam codelab ini, Anda akan mempelajari cara membuat dan melatih jaringan neural yang mengenali angka dari tulisan tangan. Seiring meningkatnya jaringan neural untuk mencapai akurasi 99%, Anda juga akan menemukan solusi dagang yang digunakan oleh para profesional deep learning untuk melatih model mereka secara efisien.

Codelab ini menggunakan set data MNIST, yang merupakan kumpulan 60.000 digit berlabel yang telah membuat sibuk PhD selama hampir dua dekade. Anda akan mengatasi masalah ini dengan kurang dari 100 baris kode Python / TensorFlow.

Yang akan Anda pelajari

  • Apa itu jaringan neural dan cara melatihnya
  • Cara membuat jaringan neural 1 lapis dasar menggunakan tf.keras
  • Cara menambahkan lapisan lainnya
  • Cara menyiapkan jadwal kecepatan pembelajaran
  • Cara membuat jaringan neural konvolusional
  • Cara menggunakan teknik normalisasi: dropout, normalisasi batch
  • Apa itu overfit

Yang Anda butuhkan

Hanya browser. Workshop ini dapat dijalankan sepenuhnya dengan Google Colaboratory.

Masukan

Beri tahu kami jika Anda melihat sesuatu yang salah di lab ini atau menurut Anda hal tersebut harus ditingkatkan. Kami menangani masukan melalui masalah GitHub [masukan link].

Lab ini menggunakan Google Colaboratory dan Anda tidak perlu melakukan penyiapan apa pun. Anda dapat menjalankannya dari Chromebook. Buka file di bawah dan jalankan sel untuk mempelajari notebook Colab.

Welcome to Colab.ipynb

Petunjuk tambahan di bawah:

Memilih backend GPU

Di menu Colab, pilih Runtime > Ubah jenis runtime lalu pilih GPU. Koneksi ke runtime akan terjadi secara otomatis pada eksekusi pertama, atau Anda dapat menggunakan tombol "Connect" di sudut kanan atas.

Eksekusi notebook

Jalankan sel satu per satu dengan mengklik sel dan menggunakan Shift-ENTER. Anda juga dapat menjalankan seluruh notebook dengan Runtime > Jalankan semua

Daftar isi

Semua notebook memiliki daftar isi. Anda dapat membukanya menggunakan panah hitam di sebelah kiri.

Sel tersembunyi

Beberapa sel hanya akan menampilkan judulnya. Ini adalah fitur notebook khusus Colab. Anda dapat mengkliknya dua kali untuk melihat kode di dalamnya, tetapi biasanya tidak terlalu menarik. Biasanya adalah fungsi dukungan atau visualisasi. Anda tetap harus menjalankan sel ini agar fungsi di dalamnya dapat ditetapkan.

Kita akan menonton kereta jaringan neural terlebih dahulu. Buka notebook di bawah dan jalankan semua sel. Jangan memperhatikan kode tersebut, kami akan mulai menjelaskannya nanti.

keras_01_mnist.ipynb

Saat mengeksekusi notebook, fokuslah pada visualisasi. Lihat penjelasannya di bawah.

Data pelatihan

Kami memiliki set data digit tulisan tangan yang telah diberi label sehingga kami mengetahui arti setiap gambar, yaitu angka antara 0 dan 9. Di notebook, Anda akan melihat kutipan:

Jaringan neural yang akan kita buat mengklasifikasikan angka tulisan tangan dalam 10 kelasnya (0, .., 9). Fitur ini didasarkan pada parameter internal yang harus memiliki nilai yang benar agar klasifikasi berfungsi dengan baik. "Nilai yang benar" ini dipelajari melalui proses pelatihan yang memerlukan "set data berlabel" dengan gambar dan jawaban benar yang terkait.

Bagaimana kita tahu apakah jaringan neural terlatih berperforma baik atau tidak? Menggunakan set data pelatihan untuk menguji jaringan akan menipu. Set data telah dilihat beberapa kali selama pelatihan dan tentunya sangat berperforma tinggi. Kita memerlukan set data berlabel lain, yang tidak pernah dilihat selama pelatihan, untuk mengevaluasi performa jaringan. Ini disebut "set data validasi"

Pelatihan

Saat pelatihan berlangsung, satu set data pelatihan dalam satu waktu, parameter model internal diperbarui dan model menjadi semakin baik dalam mengenali angka dari tulisan tangan. Anda dapat melihatnya di grafik pelatihan:

Di sebelah kanan, "akurasi" hanyalah persentase digit yang dikenali dengan benar. Hal ini akan terus berlanjut seiring kemajuan pelatihan, dan ini bagus.

Di sebelah kiri, kita dapat melihat "loss". Untuk mendorong pelatihan, kita akan mendefinisikan fungsi "kerugian" yang mewakili seberapa buruk sistem mengenali angka, dan mencoba meminimalkannya. Yang Anda lihat di sini adalah kerugian terjadi baik pada data pelatihan maupun validasi selama pelatihan berlangsung: itu bagus. Artinya, jaringan neural sedang belajar.

Sumbu X menunjukkan jumlah "epoch" atau iterasi melalui seluruh set data.

Predictions

Saat model dilatih, kita dapat menggunakannya untuk mengenali angka dari tulisan tangan. Visualisasi berikutnya menunjukkan seberapa baik performanya di beberapa digit yang dirender dari font lokal (baris pertama), lalu pada 10.000 digit set data validasi. Class yang diprediksi akan muncul di bawah setiap digit, dan berwarna merah jika salah.

Seperti yang dapat Anda lihat, model awal ini tidak terlalu bagus namun tetap mengenali beberapa digit dengan benar. Akurasi validasi akhirnya adalah sekitar 90% yang tidak terlalu buruk untuk model sederhana yang kita mulai, tetapi itu masih berarti bahwa ia melewatkan 1000 digit validasi dari 10.000. Jauh lebih banyak yang dapat ditampilkan, itulah sebabnya tampaknya semua jawaban salah (merah).

Tensor

Data disimpan dalam matriks. Gambar hitam putih berukuran 28x28 piksel dapat disertakan dalam matriks dua dimensi 28x28. Namun, untuk gambar berwarna, kita perlu lebih banyak dimensi. Ada 3 nilai warna per piksel (Merah, Hijau, Biru), sehingga diperlukan tabel tiga dimensi dengan dimensi [28, 28, 3]. Dan untuk menyimpan batch 128 gambar berwarna, diperlukan tabel empat dimensi dengan dimensi [128, 28, 28, 3].

Tabel multidimensi ini disebut "tensors" dan daftar dimensinya adalah "shape".

Singkatnya

Jika semua istilah yang dicetak tebal di paragraf berikutnya sudah Anda ketahui, Anda dapat melanjutkan ke latihan berikutnya. Jika Anda baru memulai deep learning, maka selamat datang.

penyihir.png

Untuk model yang dibuat sebagai urutan lapisan Keras, menawarkan Sequential API. Misalnya, pengklasifikasi gambar yang menggunakan tiga lapisan padat dapat ditulis di Keras sebagai:

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=[28, 28, 1]),
    tf.keras.layers.Dense(200, activation="relu"),
    tf.keras.layers.Dense(60, activation="relu"),
    tf.keras.layers.Dense(10, activation='softmax') # classifying into 10 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, ... )

Satu lapisan padat

Digit tulisan tangan dalam set data MNIST adalah gambar hitam putih berukuran 28x28 piksel. Pendekatan paling sederhana untuk mengklasifikasikannya adalah menggunakan 28x28=784 piksel sebagai input untuk jaringan neural 1 lapis.

Screenshot 26-07-2016 pukul 12.32.24.png

Setiap "neuron" di jaringan neural melakukan bobot bobot dari semua inputnya, menambahkan konstanta yang disebut "bias" lalu memberi feed hasilnya melalui beberapa "fungsi aktivasi" non-linear. "weight" dan "bias" adalah parameter yang akan ditentukan melalui pelatihan. Inisialisasi ini diinisialisasi dengan nilai acak pada awalnya.

Gambar di atas mewakili jaringan neural 1 lapisan dengan 10 neuron keluaran karena kita ingin mengklasifikasikan angka menjadi 10 kelas (0 hingga 9).

Dengan perkalian matriks

Berikut adalah cara lapisan jaringan neural, yang memproses koleksi gambar, dapat direpresentasikan oleh perkalian matriks:

matmul.gif

Dengan menggunakan kolom pertama bobot dalam matriks bobot W, kami menghitung jumlah bobot semua piksel dari gambar pertama. Jumlah ini sesuai dengan neuron pertama. Dengan menggunakan kolom bobot, kita melakukan hal yang sama untuk neuron kedua dan seterusnya hingga neuron ke-10. Kemudian, kita dapat mengulangi operasi ini untuk 99 gambar yang tersisa. Jika kita memanggil X matriks yang berisi 100 gambar, semua jumlah bobot untuk 10 neuron kita, dihitung pada 100 gambar hanyalah X.W, perkalian matriks.

Setiap neuron sekarang harus menambahkan biasnya (konstanta). Karena kita memiliki 10 neuron, kita memiliki 10 konstanta bias. Kita akan memanggil vektor 10 nilai b ini. Ini harus ditambahkan ke setiap baris dari matriks yang sudah dihitung sebelumnya. Menggunakan sedikit keajaiban yang disebut "penyiaran" kita akan menulisnya dengan tanda plus sederhana.

Kami akhirnya menerapkan fungsi aktivasi, misalnya "softmax" (dijelaskan di bawah) dan mendapatkan formula yang menjelaskan jaringan neural 1 lapis, diterapkan pada 100 gambar:

Tangkapan Layar 26-07-2016 pukul 16.02.36.png

Di Keras

Dengan library jaringan neural tingkat tinggi seperti Keras, kita tidak perlu menerapkan formula ini. Namun, penting untuk dipahami bahwa lapisan jaringan neural hanyalah sekumpulan perkalian dan penambahan. Pada Keras, lapisan padat akan ditulis sebagai:

tf.keras.layers.Dense(10, activation='softmax')

Pelajari lebih dalam

Membuat lapisan jaringan neural berantai tidaklah sulit. Lapisan pertama menghitung jumlah piksel yang berbobot. Lapisan berikutnya menghitung jumlah bobot output dari lapisan sebelumnya.

Satu-satunya perbedaan, selain jumlah neuron, adalah pilihan fungsi aktivasi.

Fungsi aktivasi: relu, softmax, dan sigmoid

Anda biasanya akan menggunakan fungsi aktivasi "relu" untuk semua lapisan kecuali yang terakhir. Lapisan terakhir, di pengklasifikasi, akan menggunakan aktivasi "softmax".

Sekali lagi, a "neuron" menghitung jumlah bobot dari semua inputnya, menambahkan nilai yang disebut "bias" dan meng-feed hasilnya melalui fungsi aktivasi.

Fungsi aktivasi yang paling populer disebut "RELU" untuk Unit Linear Terarah. Ini adalah fungsi yang sangat sederhana seperti yang dapat Anda lihat di grafik di atas.

Fungsi aktivasi tradisional di jaringan neural adalah "sigmoid" tetapi "relu" terbukti memiliki properti konvergensi yang lebih baik hampir di mana saja dan kini lebih disukai.

Aktivasi softmax untuk klasifikasi

Lapisan terakhir jaringan neural kita memiliki 10 neuron karena kita ingin mengklasifikasikan angka dari tulisan tangan menjadi 10 class (0,..9). Ini akan menghasilkan 10 angka antara 0 dan 1 yang mewakili probabilitas angka ini adalah 0, 1, 2 dan seterusnya. Untuk lapisan ini, kita akan menggunakan fungsi aktivasi yang disebut "softmax" di lapisan terakhir.

Menerapkan softmax pada vektor dilakukan dengan mengambil eksponensial dari setiap elemen dan kemudian menormalisasi vektor, biasanya dengan membaginya dengan "L1" norma (yaitu jumlah nilai absolut) sehingga nilai yang dinormalkan menambahkan hingga 1 dan dapat ditafsirkan sebagai probabilitas.

Output lapisan terakhir, sebelum aktivasi terkadang disebut "logits". Jika vektor ini adalah L = [L0, L1, L2, L3, L4, L5, L6, L7, L8, L9], maka:

Kerugian lintas entropi

Setelah jaringan neural kita menghasilkan prediksi dari gambar input, kita perlu mengukur seberapa baik prediksi tersebut, yaitu jarak antara apa yang dikatakan jaringan dan jawaban yang benar, yang sering disebut "label". Ingat, kami memiliki label yang benar untuk semua gambar dalam set data.

Setiap jarak akan berfungsi, tetapi untuk masalah klasifikasi, yang disebut "jarak-entropi silang" adalah yang paling efektif. Kita akan menyebutnya error atau "loss" fungsi:

Penurunan gradien

"Pelatihan" jaringan neural sebenarnya berarti menggunakan gambar dan label pelatihan untuk menyesuaikan bobot dan bias guna meminimalkan fungsi kerugian lintas-entropi. Berikut adalah cara kerjanya.

Entropi silang adalah fungsi bobot, bias, piksel dari gambar pelatihan dan class yang diketahuinya.

Jika kita menghitung turunan parsial dari entropi silang relatif terhadap semua bobot dan semua bias, kita memperoleh "gradasi", yang dihitung untuk gambar, label, dan nilai bobot dan bias yang diberikan. Ingat bahwa kita dapat memiliki jutaan bobot dan bias sehingga menghitung gradien yang terdengar seperti banyak pekerjaan. Untungnya, TensorFlow melakukannya untuk kami. Properti matematika dari gradien adalah ia menunjuk "up". Karena kita ingin menuju ke tempat entropi silang rendah, kita akan berlawanan arah. Kami memperbarui bobot dan bias berdasarkan perbandingan gradien. Kemudian kita melakukan hal yang sama berulang-ulang menggunakan kumpulan gambar dan label pelatihan berikutnya, dalam loop pelatihan. 0:01:48.480, 0:04:48.680 Semoga informasi ini bisa bertemu di mana cross-entropy minimal meskipun tidak ada yang menjamin bahwa nilai minimum ini unik.

penurunan gradien2.png

Pengelompokan dan momentum mini

Anda dapat menghitung gradien hanya pada satu gambar contoh dan memperbarui bobot dan bias dengan segera, tetapi melakukannya pada sekelompok gambar, misalnya, 128 gambar memberikan gradien yang lebih mewakili batasan yang diberlakukan oleh gambar contoh yang berbeda dan karena itu cenderung menyatu dengan solusi dengan lebih cepat. Ukuran tumpukan mini adalah parameter yang dapat disesuaikan.

Teknik ini, terkadang disebut "penurunan gradien stokastik" memiliki manfaat lain yang lebih pragmatis: bekerja dengan batch juga berarti bekerja dengan matriks yang lebih besar dan ini biasanya lebih mudah untuk dioptimalkan pada GPU dan TPU.

Konvergensinya masih bisa sedikit kacau dan bahkan bisa berhenti jika vektor gradien semuanya nol. Apakah itu berarti kami telah menemukan jumlah minimum? Tidak selalu. Komponen gradien dapat bernilai nol atau minimum. Dengan vektor gradien dengan jutaan elemen, jika semuanya nol, probabilitas bahwa setiap nol sesuai dengan minimum dan tidak ada satu pun dari titik maksimum tersebut yang cukup kecil. Dalam banyak dimensi, titik pelana cukup umum dan kami tidak ingin berhenti pada titik itu.

Ilustrasi: titik pelana. Gradiennya 0, tetapi bukan minimum untuk semua arah. (Atribusi gambar Wikimedia: Oleh Nicoguaro - Karya sendiri, CC BY 3.0)

Solusinya adalah dengan menambahkan beberapa momentum ke algoritme pengoptimalan sehingga dapat melewati titik pelana tanpa berhenti.

Glosarium

batch atau mini-batch: pelatihan selalu dilakukan pada batch data dan label pelatihan. Hal ini membantu algoritma bertemu. Dimensi "batch" biasanya merupakan dimensi pertama tensor data. Misalnya tensor bentuk [100, 192, 192, 3] berisi 100 gambar 192x192 piksel dengan tiga nilai per piksel (RGB).

kerugian lintas entropi: fungsi kerugian khusus yang sering digunakan dalam pengklasifikasi.

lapisan padat: lapisan neuron tempat setiap neuron terhubung ke semua neuron di lapisan sebelumnya.

fitur: input jaringan neural terkadang disebut "features". Teknik mencari tahu bagian set data mana (atau kombinasi dari bagian-bagian) untuk dimasukkan ke dalam jaringan neural untuk mendapatkan prediksi yang baik disebut "engineering fitur".

labels: nama lain untuk "class" atau jawaban yang benar dalam masalah klasifikasi yang diawasi

kecepatan pembelajaran: fraksi gradien dengan bobot dan bias yang diperbarui pada setiap iterasi loop pelatihan.

logits: output dari lapisan neuron sebelum fungsi aktivasi diterapkan disebut "logits". Istilah ini berasal dari "fungsi logistik" alias & “fungsi sigmoid" yang dulunya merupakan fungsi aktivasi paling populer. "Output saraf sebelum fungsi logistik" dipersingkat menjadi "logits".

loss: fungsi error yang membandingkan output jaringan neural dengan jawaban yang benar

neuron: menghitung jumlah bobot inputnya, menambahkan bias dan memberikan hasil melalui fungsi aktivasi.

enkode one-hot: class 3 dari 5 dienkode sebagai vektor 5 elemen, semuanya nol kecuali yang ke-3 adalah 1.

relu: unit linear yang diperbaiki. Fungsi aktivasi populer untuk neuron.

sigmoid: fungsi aktivasi lain yang sebelumnya populer dan masih berguna dalam kasus khusus.

softmax: fungsi aktivasi khusus yang bekerja pada vektor, meningkatkan perbedaan antara komponen terbesar dan yang lainnya, dan juga menormalkan vektor untuk memiliki jumlah 1 sehingga dapat ditafsirkan sebagai vektor probabilitas. Digunakan sebagai langkah terakhir dalam pengklasifikasi.

tensor: "tensor" seperti matriks tetapi dengan jumlah dimensi arbitrer. Tensor 1 dimensi adalah vektor. Tensor 2 dimensi adalah matriks. Dan kemudian Anda dapat memiliki tensor dengan 3, 4, 5 atau lebih dimensi.

Kembali ke notebook studi dan kali ini, mari kita baca kodenya.

keras_01_mnist.ipynb

Mari kita bahas seluruh sel dalam notebook ini.

Sel "Parameter"

Ukuran batch, jumlah iterasi pelatihan, dan lokasi file data ditentukan di sini. File data dihosting di bucket Google Cloud Storage (GCS) dan itulah sebabnya alamatnya dimulai dengan gs://

Sel "Impor"

Semua library Python yang diperlukan diimpor di sini, termasuk TensorFlow dan juga matplotlib untuk visualisasi.

Sel "utilitas visualisasi [RUN ME]"

Sel ini berisi kode visualisasi yang tidak menarik. File ini diciutkan secara default, tetapi Anda dapat membukanya dan melihat kode saat Anda memiliki waktu dengan mengkliknya dua kali.

Sel "tf.data.Dataset: menguraikan file serta menyiapkan set data pelatihan dan validasi"

Sel ini menggunakan tf.data.Dataset API untuk memuat set data MNIST dari file data. Anda tidak perlu menghabiskan terlalu banyak waktu untuk sel ini. Jika Anda tertarik dengan tf.data.Dataset API, berikut adalah tutorial yang menjelaskannya: Pipeline data kecepatan TPU. Untuk saat ini, dasar-dasarnya adalah:

Gambar dan label (jawaban yang benar) dari set data MNIST disimpan dalam record dengan panjang tetap dalam 4 file. File dapat dimuat dengan fungsi record tetap khusus:

imagedataset = tf.data.FixedLengthRecordDataset(image_filename, 28*28, header_bytes=16)

Sekarang kita memiliki set data byte gambar. Materi iklan tersebut harus didekode ke dalam gambar. Kita menentukan fungsi untuk melakukannya. Gambar tidak dikompresi sehingga fungsi tidak perlu mendekode apa pun (decode_raw pada dasarnya tidak melakukan apa pun). Kemudian, gambar dikonversi ke nilai floating point antara 0 dan 1. Kita dapat membentuk ulang di sini sebagai gambar 2D tetapi sebenarnya kita menyimpannya sebagai array piksel datar berukuran 28*28 karena itulah yang diharapkan oleh lapisan padat awal kita.

def read_image(tf_bytestring):
    image = tf.decode_raw(tf_bytestring, tf.uint8)
    image = tf.cast(image, tf.float32)/256.0
    image = tf.reshape(image, [28*28])
    return image

Kita menerapkan fungsi ini ke set data menggunakan .map dan mendapatkan set data gambar:

imagedataset = imagedataset.map(read_image, num_parallel_calls=16)

Kita melakukan jenis pembacaan dan decoding yang sama untuk label dan juga .zip gambar dan label:

dataset = tf.data.Dataset.zip((imagedataset, labelsdataset))

Kita sekarang memiliki set data pasangan (gambar, label). Inilah yang diharapkan oleh model kami. Kita belum cukup siap untuk menggunakannya dalam fungsi pelatihan:

dataset = dataset.cache()
dataset = dataset.shuffle(5000, reshuffle_each_iteration=True)
dataset = dataset.repeat()
dataset = dataset.batch(batch_size)
dataset = dataset.prefetch(tf.data.experimental.AUTOTUNE)

tf.data.Dataset API memiliki semua fungsi utilitas yang diperlukan untuk menyiapkan set data:

.cache meng-cache set data dalam RAM. Ini adalah set data kecil yang akan berfungsi. .shuffle mengacaknya dengan buffer 5000 elemen. Data pelatihan harus diacak dengan baik. .repeat mengulangi set data. Kita akan melatihnya beberapa kali (beberapa iterasi pelatihan). .batch menyatukan beberapa gambar dan label menjadi mini-natch. Terakhir, .prefetch dapat menggunakan CPU untuk menyiapkan batch berikutnya sementara batch saat ini sedang dilatih di GPU.

Set data validasi disiapkan dengan cara yang sama. Sekarang kita siap untuk menentukan model dan menggunakan set data ini untuk melatihnya.

Sel "Keras Model"

Semua model akan menjadi urutan lapisan lurus sehingga kita dapat menggunakan gaya tf.keras.Sequential untuk membuatnya. Awalnya, di sini ada satu lapisan padat. Ini memiliki 10 neuron karena kita mengklasifikasikan angka dari tulisan tangan ke dalam 10 kelas. Metode ini menggunakan "softmax" aktivasi karena merupakan lapisan terakhir dalam pengklasifikasi.

Model Keras juga perlu mengetahui bentuk inputnya. tf.keras.layers.Input dapat digunakan untuk menentukannya. Di sini, vektor input adalah vektor datar dengan nilai piksel panjang 28*28.

model = tf.keras.Sequential(
  [
    tf.keras.layers.Input(shape=(28*28,)),
    tf.keras.layers.Dense(10, activation='softmax')
  ])

model.compile(optimizer='sgd',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# print model layers
model.summary()

# utility callback that displays training curves
plot_training = PlotTraining(sample_rate=10, zoom=1)

Mengonfigurasi model dilakukan di Keras menggunakan fungsi model.compile. Di sini kami menggunakan pengoptimal dasar 'sgd' (Penurunan Gradien Stokastik). Model klasifikasi memerlukan fungsi kerugian lintas-entropi, yang disebut 'categorical_crossentropy' dalam Keras. Terakhir, kita meminta model untuk menghitung metrik 'accuracy', yang merupakan persentase gambar yang diklasifikasikan dengan benar.

Keras menawarkan utilitas model.summary() yang sangat bagus yang mencetak detail model yang telah Anda buat. Instruktur jenis Anda telah menambahkan utilitas PlotTraining (ditentukan dalam &utilasi visualisasi) sel yang akan menampilkan berbagai kurva pelatihan selama pelatihan.

Sel "Latih dan validasi model"

Di sinilah pelatihan terjadi, dengan memanggil model.fit dan meneruskan set data pelatihan dan validasi. Secara default, Keras menjalankan putaran validasi di akhir setiap iterasi pelatihan.

model.fit(training_dataset, steps_per_epoch=steps_per_epoch, epochs=EPOCHS,
          validation_data=validation_dataset, validation_steps=1,
          callbacks=[plot_training])

Di Keras, Anda dapat menambahkan perilaku khusus selama pelatihan menggunakan callback. Begitulah cara plot pelatihan yang diperbarui secara dinamis diterapkan untuk workshop ini.

Sel "Memvisualisasikan prediksi"

Setelah model dilatih, kita bisa mendapatkan prediksi darinya dengan memanggil model.predict():

probabilities = model.predict(font_digits, steps=1)
predicted_labels = np.argmax(probabilities, axis=1)

Di sini kami telah menyiapkan serangkaian angka cetak yang dirender dari font lokal, sebagai pengujian. Ingat bahwa jaringan neural menampilkan vektor 10 probabilitas dari "softmax&quot terakhirnya. Untuk mendapatkan label, kita harus mencari tahu probabilitas mana yang tertinggi. np.argmax dari library numpy melakukannya.

Untuk memahami mengapa parameter axis=1 diperlukan, harap diingat bahwa kita telah memproses batch 128 gambar sehingga model menampilkan 128 vektor probabilitas. Bentuk tensor output adalah [128, 10]. Kita menghitung argmax pada 10 probabilitas yang ditampilkan untuk setiap gambar, sehingga axis=1 (sumbu pertama menjadi 0).

Model sederhana ini telah mengenali 90% digit. Tidak buruk, tetapi Anda sekarang akan memperbaikinya secara signifikan.

godeep.png

Untuk meningkatkan akurasi pengenalan, kita akan menambahkan lebih banyak lapisan ke jaringan neural.

Tangkapan Layar 27-07-2016 pukul 15.36.55.png

Kami menyimpan softmax sebagai fungsi aktivasi pada lapisan terakhir karena itulah yang paling cocok untuk klasifikasi. Namun pada lapisan menengah, kita akan menggunakan fungsi aktivasi yang paling klasik: sigmoid:

Misalnya, model Anda mungkin terlihat seperti ini (jangan lupa koma, tf.keras.Sequential mengambil daftar lapisan yang dipisahkan koma):

model = tf.keras.Sequential(
  [
      tf.keras.layers.Input(shape=(28*28,)),
      tf.keras.layers.Dense(200, activation='sigmoid'),
      tf.keras.layers.Dense(60, activation='sigmoid'),
      tf.keras.layers.Dense(10, activation='softmax')
  ])

Lihat "ringkasan" model Anda. Parameter ini sekarang memiliki setidaknya 10 kali lebih banyak parameter. Seharusnya 10x lebih baik! Tapi karena suatu alasan, itu tidak ...

Kekalahan itu tampaknya juga gagal. Terjadi masalah.

Anda baru saja mengalami jaringan neural, seperti yang digunakan orang untuk mendesainnya di tahun 80-an dan 90-an. Tidak heran mereka menyerah pada ide, menganut apa yang disebut "AI musim dingin". Memang, saat Anda menambahkan lapisan, jaringan neural memiliki semakin banyak kesulitan untuk bertemu.

Ternyata jaringan neural dalam dengan banyak lapisan (20, 50, bahkan 100 saat ini) dapat berfungsi dengan sangat baik, dengan menyediakan beberapa trik kotor matematika untuk membuatnya berkumpul. Penemuan trik sederhana ini merupakan salah satu alasan munculnya fenomena deep learning pada tahun 2010-an.

Aktivasi RELU

relu.png

Fungsi aktivasi sigmoid sebenarnya cukup bermasalah dalam jaringan dalam. Ini akan menekan semua nilai antara 0 dan 1, dan bila Anda melakukannya berulang kali, output neuron dan gradiennya dapat hilang sepenuhnya. Hal ini disebutkan karena alasan historis, namun jaringan modern menggunakan RELU (Unit Linear Terarah) yang terlihat seperti ini:

Relu di sisi lain memiliki turunan dari 1, setidaknya di sisi kanannya. Dengan aktivasi RELU, meskipun gradien yang berasal dari beberapa neuron bisa nol, akan selalu ada bentuk lain yang memberikan gradien bukan nol yang jelas dan pelatihan dapat berlanjut dengan kecepatan yang baik.

Pengoptimalan yang lebih baik

Dalam ruang berdimensi sangat tinggi seperti di sini — kita memiliki urutan bias dan bobot 10 ribu — "titik pelana&; sering. Ini adalah titik yang bukan titik minimum lokal, tetapi tempat gradiennya tetap nol dan pengoptimal penurunan gradien tetap ada di sana. TensorFlow memiliki berbagai pengoptimal yang tersedia, termasuk beberapa pengoptimal yang berfungsi dengan banyak inersia dan akan berlayar dengan aman melewati titik pelana.

Inisialisasi acak

Seni menginisialisasi bias bobot sebelum pelatihan adalah sebuah area penelitian itu sendiri, dengan banyak makalah yang dipublikasikan tentang topik tersebut. Anda dapat melihat semua penginisialisasi yang tersedia di Keras di sini. Untungnya, Keras melakukan hal yang benar secara default dan menggunakan penginisialisasi 'glorot_uniform' yang merupakan yang terbaik di hampir semua kasus.

Tidak ada yang bisa Anda lakukan, karena Keras sudah melakukan hal yang benar.

NaN ?

Formula lintas-entropi melibatkan logaritma dan log(0) bukan Not (NaN, error numerik jika Anda menginginkannya). Dapatkah input ke entropi silang 0? Input berasal dari softmax yang pada dasarnya adalah eksponensial dan eksponensial tidak pernah nol. Jadi, kami aman!

Iya gitu? Dalam dunia matematika yang indah, kita akan aman, tetapi dalam dunia komputer, exp(-150), yang direpresentasikan dalam format float32, sama dengan null dan error lintas-entropi.

Untungnya, tidak ada yang bisa Anda lakukan di sini, karena Keras menangani masalah ini dan menghitung softmax diikuti oleh entropi silang dengan cara yang sangat hati-hati guna memastikan stabilitas numerik dan menghindari NaN yang ditakuti.

Berhasil?

Sekarang Anda akan mendapatkan akurasi 97%. Tujuan workshop ini adalah untuk secara signifikan melampaui 99%. Jadi, mari kita lanjutkan.

Jika Anda terhenti, berikut solusinya:

keras_02_mnist_dense.ipynb

Mungkin kita bisa mencoba berlatih lebih cepat? Kecepatan pembelajaran default di pengoptimal Adam adalah 0,001. Mari kita coba tingkatkan.

Melakukan sesuatu dengan lebih cepat tampaknya tidak terlalu membantu dan apa suaranya?

Kurva pelatihan benar-benar rumit dan melihat kedua kurva validasi: kurva itu melompat naik dan turun. Artinya, waktu kita terlalu cepat. Kita bisa kembali ke kecepatan sebelumnya, tetapi ada cara yang lebih baik.

perlambat.png

Solusi yang baik adalah memulai dengan cepat dan menurunkan kecepatan pembelajaran secara eksponensial. Di Keras, Anda dapat melakukannya dengan callback tf.keras.callbacks.LearningRateScheduler.

Kode yang berguna untuk menyalin-tempel:

# lr decay function
def lr_decay(epoch):
  return 0.01 * math.pow(0.6, epoch)

# lr schedule callback
lr_decay_callback = tf.keras.callbacks.LearningRateScheduler(lr_decay, verbose=True)

# important to see what you are doing
plot_learning_rate(lr_decay, EPOCHS)

Jangan lupa untuk menggunakan lr_decay_callback yang telah Anda buat. Tambahkan callback ke daftar callback di model.fit:

model.fit(...,  callbacks=[plot_training, lr_decay_callback])

Dampak dari perubahan kecil ini sangat spektakuler. Anda akan melihat bahwa sebagian besar derau hilang dan akurasi pengujian kini berada di atas 98% secara berkelanjutan.

Modelnya sekarang semakin bersatu. Mari kita coba lebih dalam.

Apakah ini membantu?

Sebenarnya tidak, akurasi masih terhenti di 98% dan melihat kerugian validasi. Naik! Algoritme pembelajaran hanya menangani data pelatihan dan mengoptimalkan kerugian pelatihan sebagaimana mestinya. Pengujian ini tidak pernah melihat data validasi sehingga tidak mengejutkan bahwa setelah beberapa saat, pekerjaannya tidak lagi memiliki efek pada kerugian validasi yang berhenti menurun dan terkadang bahkan memantul kembali.

Hal ini tidak langsung memengaruhi kemampuan pengenalan model Anda di dunia nyata, tetapi akan mencegah Anda menjalankan banyak iterasi dan umumnya merupakan tanda bahwa pelatihan tidak lagi memberikan efek positif.

dropout.png

Pemutusan ini biasanya disebut "overfit" dan ketika Anda melihatnya, Anda dapat mencoba menerapkan teknik denormalisasi yang disebut "dropout". Teknik terobosan menembakkan neuron acak ke setiap iterasi pelatihan.

Apakah berhasil?

Derau muncul kembali (tidak mengherankan mengingat cara kerja dropout). Kerugian validasi tampaknya tidak terus turun, tetapi secara keseluruhan lebih tinggi daripada tanpa putus sekolah. Akurasi validasi juga menurun. Ini adalah hasil yang cukup mengecewakan.

Sepertinya pengguna yang tidak menyelesaikan masalah bukanlah solusi yang tepat, atau mungkin "overfit" merupakan konsep yang lebih kompleks dan beberapa penyebabnya tidak dapat disetujui untuk "dropout" perbaikan?

Apa itu "overfit"? Overover terjadi ketika jaringan neural belajar "buruk", dengan cara yang berfungsi untuk contoh pelatihan, tetapi tidak begitu baik pada data dunia nyata. Ada teknik standardisasi seperti dropout yang dapat memaksa model tersebut untuk belajar dengan cara yang lebih baik, tetapi berlebihan juga memiliki root yang lebih dalam.

overfit.png

Overfit dasar terjadi jika jaringan neural memiliki terlalu banyak derajat kebebasan untuk masalah yang dihadapi. Bayangkan kita memiliki begitu banyak neuron sehingga jaringan dapat menyimpan semua gambar pelatihan di dalamnya, lalu mengenalinya dengan pencocokan pola. Metode ini akan gagal pada data dunia nyata sepenuhnya. Jaringan neural harus dibatasi sehingga dipaksa untuk menggeneralisasi apa yang dipelajarinya selama pelatihan.

Jika Anda memiliki data pelatihan yang sangat sedikit, bahkan jaringan kecil dapat mempelajarinya dengan hati-hati dan Anda akan melihat "overfit". Secara umum, Anda selalu memerlukan banyak data untuk melatih jaringan neural.

Terakhir, jika Anda telah melakukan semuanya berdasarkan buku, bereksperimen dengan berbagai ukuran jaringan untuk memastikan tingkat kebebasannya dibatasi, diterapkan, dan dilatih pada banyak data, Anda mungkin masih terjebak pada tingkat performa yang tampaknya tidak dapat ditingkatkan. Artinya jaringan neural Anda, dalam bentuknya yang sekarang, tidak dapat mengekstrak lebih banyak informasi dari data Anda, seperti dalam kasus kami di sini.

Ingat cara kita menggunakan gambar, yang disatukan menjadi satu vektor? Itu ide yang sangat buruk. Digit tulisan tangan terbuat dari bentuk dan kami menghapus informasi bentuk saat kami meratakan pikselnya. Namun, ada jenis jaringan neural yang dapat memanfaatkan informasi bentuk: jaringan konvolusional. Mari kita coba.

Jika Anda terhenti, berikut solusinya:

keras_03_mnist_dense_lrdecay_dropout.ipynb

Singkatnya

Jika semua istilah yang dicetak tebal di paragraf berikutnya sudah Anda ketahui, Anda dapat melanjutkan ke latihan berikutnya. Jika Anda baru saja memulai jaringan neural konvolusional, harap baca selengkapnya.

konvolusional.gif

Ilustrasi: memfilter gambar dengan dua filter berurutan yang masing-masing terdiri dari 4x4x3=48 bobot yang dapat dipelajari.

Berikut adalah tampilan jaringan neural konvolusional sederhana di Keras:

model = tf.keras.Sequential([
    tf.keras.layers.Reshape(input_shape=(28*28,), target_shape=(28, 28, 1)),
    tf.keras.layers.Conv2D(kernel_size=3, filters=12, activation='relu'),
    tf.keras.layers.Conv2D(kernel_size=6, filters=24, strides=2, activation='relu'),
    tf.keras.layers.Conv2D(kernel_size=6, filters=32, strides=2, activation='relu'),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(10, activation='softmax')
])

Dalam lapisan jaringan konvolusional, satu "neuron" melakukan jumlah piksel yang berbobot tepat di atasnya, di seluruh area kecil gambar saja. Penambahan ini akan mencondongkan dan memberi feed jumlah melalui fungsi aktivasi, seperti yang dilakukan neuron pada lapisan padat biasa. Operasi ini kemudian diulang di seluruh gambar menggunakan bobot yang sama. Ingatlah bahwa dalam lapisan padat, setiap neuron memiliki bobotnya sendiri. Di sini, satu "patch" dari bobot bergeser di seluruh gambar dalam kedua arah (a "konvolusi"). Output-nya memiliki nilai sebanyak piksel dalam gambar (namun beberapa padding diperlukan di tepi). Ini adalah operasi pemfilteran. Pada ilustrasi di atas, filter ini menggunakan filter berukuran 4x4x3=48.

Namun, 48 bobot tidak akan cukup. Untuk menambahkan lebih banyak derajat kebebasan, kita mengulangi operasi yang sama dengan serangkaian bobot baru. Tindakan ini akan menghasilkan kumpulan output filter baru. Mari kita sebut sebagai "channel" dari output dengan analogi dengan saluran R,G,B di gambar input.

Tangkapan Layar 29-07-2016 pukul 16.02.37.png

Dua (atau beberapa) kumpulan bobot dapat dijumlahkan sebagai satu tensor dengan menambahkan dimensi baru. Ini memberi kita bentuk umum tensor bobot untuk lapisan konvolusional. Karena jumlah saluran input dan output adalah parameter, kita dapat mulai menumpuk dan merangkai lapisan konvolusional.

Ilustrasi: jaringan neural konvolusional mengubah "kubus" data menjadi "kubus" data lainnya.

Konvolasi beruntun, penggabungan maksimum

Dengan melakukan konvolusi dengan langkah 2 atau 3, kita juga dapat menyusutkan kubus data yang dihasilkan dalam dimensi horizontalnya. Ada 2 cara umum untuk melakukannya:

  • Konvolusi beruntun: filter geser seperti di atas tetapi dengan langkah >1
  • Penggabungan maks: jendela geser yang menerapkan operasi MAX (biasanya pada patch 2x2, diulang setiap 2 piksel)

Ilustrasi: menggeser jendela komputasi sebesar 3 piksel akan menghasilkan nilai output yang lebih sedikit. Konvolusi beruntun atau kumpulan maksimal (maks pada jendela 2x2 yang digeser sebesar 2 langkah) adalah cara untuk menyingkat kubus data dalam dimensi horizontal.

Lapisan akhir

Setelah lapisan konvolusional terakhir, datanya dalam bentuk "kubus". Ada dua cara untuk memasukkannya melalui lapisan akhir yang padat.

Yang pertama adalah meratakan kubus data menjadi vektor, kemudian memasukkannya ke lapisan softmax. Terkadang, Anda bahkan dapat menambahkan lapisan padat sebelum lapisan softmax. Jumlah ini cenderung mahal dalam hal jumlah bobot. Lapisan padat di akhir jaringan konvolusional dapat berisi lebih dari setengah bobot keseluruhan jaringan neural.

Daripada menggunakan lapisan padat yang mahal, kita juga dapat membagi data yang masuk "cube" menjadi sebanyak mungkin bagian dari class, rata-rata nilainya, dan memasukkannya melalui fungsi aktivasi softmax. Dengan cara ini, pembuatan kepala klasifikasi memerlukan biaya 0 bobot. Di Keras, ada lapisan untuk ini: tf.keras.layers.GlobalAveragePooling2D().

Langsung ke bagian berikutnya untuk membuat jaringan konvolusional untuk masalah yang dihadapi.

Mari kita buat jaringan konvolusional untuk pengenalan angka dengan tulisan tangan. Kita akan menggunakan tiga lapisan konvolusional di bagian atas, lapisan pembacaan softmax tradisional di bagian bawah dan menghubungkannya dengan satu lapisan yang sepenuhnya terhubung:

Perhatikan bahwa lapisan konvolusional kedua dan ketiga memiliki dua langkah yang menjelaskan mengapa jumlah nilai output turun dari 28x28 menjadi 14x14, kemudian 7x7.

Mari kita tulis kode Keras.

Perhatian khusus diperlukan sebelum lapisan konvolusional pertama. Hal ini memang mengharapkan 3D 'kubus' data tetapi set data kami sejauh ini telah disiapkan untuk lapisan padat dan semua piksel gambar disatukan menjadi vektor. Kita perlu membentuk ulang gambar tersebut menjadi gambar 28x28x1 (1 saluran untuk gambar hitam putih):

tf.keras.layers.Reshape(input_shape=(28*28,), target_shape=(28, 28, 1))

Anda dapat menggunakan baris ini sebagai pengganti lapisan tf.keras.layers.Input yang Anda miliki saat ini.

Di Keras, sintaksis untuk lapisan konvolusional 'relu&-39;-diaktifkan adalah:

tf.keras.layers.Conv2D(kernel_size=3, filters=12, padding='same', activation='relu')

Untuk konvolusi secara bertahap, Anda akan menulis:

tf.keras.layers.Conv2D(kernel_size=6, filters=24, padding='same', activation='relu', strides=2)

Untuk meratakan kubus data menjadi vektor agar dapat digunakan oleh lapisan padat:

tf.keras.layers.Flatten()

Dan untuk lapisan padat, sintaksisnya tidak berubah:

tf.keras.layers.Dense(200, activation='relu')

Apakah model Anda merusak batasan akurasi 99%? Cukup dekat... tetapi lihat kurva kerugian validasinya. Apakah ini berdering?

Lihat juga prediksinya. Untuk pertama kalinya, Anda akan melihat bahwa sebagian besar dari 10.000 digit uji sekarang dikenali dengan benar. Hanya sekitar 41⁄2 baris kesalahan deteksi yang tersisa (sekitar 110 digit dari 10.000)

Jika Anda terhenti, berikut solusinya:

keras_04_mnist_convolutional.ipynb

Pelatihan sebelumnya menunjukkan tanda-tanda overfit yang jelas (dan masih kurang dari 99% akurasi). Haruskah kami mencoba dropout lagi?

Bagaimana hasilnya kali ini?

Sepertinya pengguna yang berhenti berlangganan kali ini telah berfungsi. Kehilangan validasi tidak lagi terjadi dan akurasi akhir harus jauh di atas 99%. Selamat!

Saat pertama kali mencoba menerapkan dropout, kami merasa ada masalah overboot, padahal sebenarnya masalah tersebut terjadi pada arsitektur jaringan neural. Kami tidak dapat melangkah lebih jauh tanpa lapisan konvolusional dan tidak ada yang dapat dilakukan untuk hal ini.

Kali ini, sepertinya overwear adalah penyebab masalah tersebut dan dropout benar-benar membantu. Ingat, ada banyak hal yang dapat menyebabkan terputusnya kurva kerugian validasi dan pelatihan, di mana kerugian validasi merangkak ke atas. Overfit (terlalu banyak derajat kebebasan, tidak digunakan dengan baik oleh jaringan) hanyalah salah satunya. Jika set data Anda terlalu kecil atau arsitektur jaringan neural Anda tidak memadai, Anda mungkin melihat perilaku serupa pada kurva kerugian, tetapi dropout tidak akan membantu.

Terakhir, mari coba tambahkan normalisasi batch.

Itulah teorinya, dalam praktiknya, cukup ingat beberapa aturan:

Saat ini, mari kita putar bukunya dan menambahkan lapisan norma batch pada setiap lapisan jaringan neural, kecuali lapisan terakhir. Jangan tambahkan ke lapisan "softmax" terakhir. Tidak akan berguna di sana.

# Modify each layer: remove the activation from the layer itself.
# Set use_bias=False since batch norm will play the role of biases.
tf.keras.layers.Conv2D(..., use_bias=False),
# Batch norm goes between the layer and its activation.
# The scale factor can be turned off for Relu activation.
tf.keras.layers.BatchNormalization(scale=False, center=True),
# Finish with the activation.
tf.keras.layers.Activation('relu'),

Bagaimana akurasinya sekarang?

Dengan sedikit penyesuaian (BATCH_SIZE=64, parameter peluruhan kecepatan pembelajaran 0,666, tingkat putus sekolah pada lapisan padat 0,3) dan sedikit keberuntungan, Anda bisa mencapai 99,5%. Kecepatan pembelajaran dan penyesuaian dengan pengecualian dilakukan berdasarkan "praktik terbaik" untuk menggunakan norma batch:

  • Norma batch membantu jaringan neural bertemu dan biasanya memungkinkan Anda berlatih lebih cepat.
  • Norma batch adalah bilangan bulat. Biasanya Anda dapat mengurangi jumlah putus sekolah yang digunakan, atau bahkan tidak menggunakan dropout sama sekali.

Notebook solusi menjalankan pelatihan 99,5%:

keras_05_mnist_batch_norm.ipynb

Anda akan menemukan versi kode cloud-ready di folder mlengine di GitHub, beserta petunjuk untuk menjalankannya di Google Cloud AI Platform. Sebelum dapat menjalankan bagian ini, Anda harus membuat akun Google Cloud dan mengaktifkan penagihan. Resource yang diperlukan untuk menyelesaikan lab harus kurang dari beberapa dolar (dengan asumsi 1 jam waktu pelatihan di satu GPU). Untuk menyiapkan akun:

  1. Buat project Google Cloud Platform (http://cloud.google.com/console).
  2. Aktifkan penagihan.
  3. Instal alat command line GCP (GCP SDK di sini).
  4. Buat bucket Google Cloud Storage (masukkan ke dalam region us-central1). Ini akan digunakan untuk melakukan tahapan kode pelatihan dan menyimpan model terlatih Anda.
  5. Aktifkan API yang diperlukan dan minta kuota yang diperlukan (jalankan perintah pelatihan satu kali dan Anda akan mendapatkan pesan error yang memberitahukan apa yang harus diaktifkan).

Anda telah membangun jaringan neural pertama dan melatihnya hingga 99% akurasi. Teknik yang dipelajari di sepanjang jalur ini tidak khusus untuk set data MNIST, sebenarnya teknik ini banyak digunakan saat bekerja dengan jaringan neural. Sebagai hadiah perpisahan, berikut kartu "tebing'catatan" kartu untuk lab, dalam versi kartun. Anda dapat menggunakannya untuk mengingat hal-hal yang telah dipelajari:

tebing catatan tensorflow lab.png

Langkah berikutnya

  • Setelah jaringan yang sepenuhnya terhubung dan konvolusional, Anda harus melihat jaringan neural berulang.
  • Untuk menjalankan pelatihan atau inferensi di cloud pada infrastruktur terdistribusi, Google Cloud menyediakan AI Platform.
  • Terakhir, kami menyukai masukan. Beri tahu kami jika Anda melihat sesuatu yang salah di lab ini atau menurut Anda hal tersebut harus ditingkatkan. Kami menangani masukan melalui masalah GitHub [masukan link].

HR.png

ID Martin Görner ukuran kecil.jpg

Pengarang: Martin Görner

Twitter: @martin_gorner

Semua gambar kartun dalam hak cipta lab ini: foto stok alexpokusay / 123RF