Pemrograman Dengan PyTorch: Membangun Aplikasi Pembelajaran Mendalam

gambarHalo para Penduduk! Ian Poynter akan membantu Anda mengetahui cara menyiapkan PyTorch di cloud, cara membuat arsitektur neural yang membuatnya lebih mudah untuk bekerja dengan gambar, suara, dan teks. Buku ini mencakup konsep penting untuk mempelajari porting, model debugging, dan menggunakan perpustakaan PyTorch. Anda akan belajar untuk: - Menerapkan model pembelajaran mendalam - Menggunakan PyTorch dalam proyek skala besar - Menerapkan bungkus pembelajaran - Menggunakan model PyTorch torchaudio dan konvolusional untuk mengklasifikasikan data audio - Menerapkan teknik NLP paling canggih menggunakan model yang dilatih di Wikipedia - Men-debug model PyTorch dengan TensorBoard dan Flamegraph - Menerapkan Aplikasi PyTorch dalam Wadah “PyTorch adalah salah satu pustaka pembelajaran mendalam yang tumbuh paling cepat, menyaingi raksasa Google TensorFlow - hampir setara.





Klasifikasi gambar dengan PyTorch



Buku teks pembelajaran mendalam penuh dengan terminologi profesional dan tidak dapat dipahami. Saya mencoba menjaganya tetap minimum dan selalu memberikan satu contoh yang dapat dengan mudah diperpanjang saat Anda terbiasa bekerja dengan PyTorch. Kami menggunakan contoh ini di seluruh buku untuk mendemonstrasikan cara men-debug model (Bab 7) atau menerapkannya ke produksi (Bab 8).



Mulai sekarang hingga akhir Bab 4, kami akan mengkompilasi pengklasifikasi gambar. Jaringan saraf biasanya digunakan sebagai pengklasifikasi gambar; jaringan menawarkan gambar dan mengajukan pertanyaan sederhana: "Apa ini?"



Mari kita mulai dengan membuat aplikasi kita di PyTorch.



Masalah klasifikasi



Di sini kita akan membuat pengklasifikasi sederhana yang dapat membedakan ikan dari kucing. Kami akan mengulangi proses desain dan pengembangan model kami agar lebih akurat.

Dalam gambar. 2.1 dan 2.2 menggambarkan seekor ikan dan kucing dengan segala keagungannya. Saya tidak yakin apakah ikan itu memiliki nama, tetapi nama kucing itu adalah Helvetica.



Mari kita mulai dengan membahas beberapa masalah klasifikasi standar.



gambar gambar



Kesulitan standar



Bagaimana cara menulis program yang dapat membedakan ikan dari kucing? Mungkin Anda akan menulis seperangkat aturan yang menjelaskan apakah seekor kucing memiliki ekor atau ikan bersisik, dan menerapkan aturan tersebut pada gambar sehingga program dapat mengklasifikasikan gambar. Tetapi ini akan membutuhkan waktu, tenaga dan keterampilan. Bagaimana jika Anda menemukan kucing Manx? Meski jelas seekor kucing, ia tidak memiliki ekor.



Aturan ini menjadi semakin kompleks saat Anda mencoba menjelaskan semua kemungkinan skenario yang menggunakannya. Juga, saya harus mengakui bahwa pemrograman visual sangat buruk bagi saya, jadi pikiran harus menulis kode secara manual untuk semua aturan ini menakutkan.



Anda membutuhkan fungsi yang mengembalikan kucing atau ikan saat Anda memasukkan gambar. Sulit untuk membangun fungsi seperti itu hanya dengan mendaftar semua kriteria secara lengkap. Tetapi pembelajaran mendalam pada dasarnya memaksa komputer untuk bekerja keras membuat semua aturan yang baru saja kita bicarakan ini, asalkan kita membuat struktur, menyediakan banyak data pada jaringan, dan memberi tahu jika itu memberikan jawaban yang benar. Inilah yang akan kami lakukan. Selain itu, Anda akan mempelajari beberapa teknik dasar penggunaan PyTorch.



Tapi pertama-tama datanya



Pertama, kami membutuhkan data. Berapa banyak kuota? Tergantung berbagai faktor. Seperti yang akan Anda lihat di Bab 4, gagasan bahwa teknik pembelajaran mendalam apa pun membutuhkan data dalam jumlah besar untuk melatih jaringan neural belum tentu benar. Namun, sekarang kita akan mulai dari awal, yang biasanya membutuhkan akses ke banyak data. Diperlukan banyak gambar ikan dan kucing.



Seseorang dapat menghabiskan waktu mengunduh banyak gambar dari pencarian gambar di Google, tetapi ada cara yang lebih mudah: koleksi gambar standar yang digunakan untuk melatih jaringan saraf adalah ImageNet. Ini berisi lebih dari 14 juta gambar dan 20 ribu kategori gambar. Ini adalah standar yang digunakan untuk membandingkan semua pengklasifikasi gambar. Oleh karena itu, saya mengambil gambar dari sana, meskipun Anda dapat memilih opsi lain jika Anda mau.



Selain data, PyTorch juga harus memiliki cara untuk mendefinisikan apa itu kucing dan apa itu ikan. Ini cukup mudah bagi kami, tetapi lebih sulit untuk komputer (itulah sebabnya kami membuat program!). Kami menggunakan pelabelan yang dilampirkan pada data dan ini disebut pembelajaran yang diawasi. (Jika Anda tidak memiliki akses ke salah satu label, maka Anda dapat menebaknya, pembelajaran mesin tanpa pengawasan digunakan.)



Jika kami menggunakan data ImageNet, label mereka tidak akan berguna karena berisi terlalu banyak informasi. Memberi label pada kucing kucing atau ikan trout untuk komputer tidak sama dengan kucing atau ikan.



Diperlukan untuk melabel ulang mereka. Karena ImageNet adalah koleksi gambar yang sangat banyak, saya telah mengumpulkan gambar dan menandai URL ikan dan kucing (https://oreil.ly/NbtEU).



Anda dapat menjalankan skrip download.py di direktori itu dan itu akan mengunduh gambar dari url dan menempatkannya di lokasi pelatihan yang sesuai. Pemberian label ulang itu sederhana; skrip menyimpan gambar kucing di direktori kereta / kucing dan gambar ikan di direktori kereta / ikan. Jika Anda tidak ingin menggunakan skrip untuk mengunduh, cukup buat direktori ini dan letakkan gambar yang sesuai di tempat yang tepat. Kami sekarang memiliki data, tetapi kami perlu mengubahnya menjadi format yang dapat dipahami PyTorch.



PyTorch dan pemuat data



Memuat dan mengubah data menjadi format siap pelatihan sering kali merupakan salah satu bidang ilmu data yang membutuhkan waktu terlalu lama. PyTorch telah mengembangkan persyaratan interaksi data yang membuatnya cukup mudah, baik Anda bekerja dengan gambar, teks, atau audio.



Dua kondisi utama untuk bekerja dengan data adalah set data dan pemuat data. Dataset adalah kelas Python yang memungkinkan kita mendapatkan data yang kita kirim ke jaringan saraf.



Pemuat data adalah apa yang mentransfer data dari kumpulan data ke jaringan. (Ini mungkin termasuk informasi seperti: Berapa banyak proses pekerja yang mengunggah data ke jaringan? Berapa banyak gambar yang kita unggah pada saat yang sama?)



Mari kita lihat dataset terlebih dahulu. Setiap set data, apakah itu berisi gambar, audio, teks, lanskap 3D, informasi pasar saham, atau apa pun, dapat berinteraksi dengan PyTorch jika memenuhi persyaratan kelas Python abstrak ini:



class Dataset(object):
     def __getitem__(self, index):
          raise NotImplementedError

     def __len__(self):
          raise NotImplementedError


Ini cukup sederhana: kita harus menggunakan metode yang mengembalikan ukuran dataset kita (len) dan yang dapat mengambil elemen dari dataset secara berpasangan (label, tensor). Ini dipanggil oleh pemuat data saat memasukkan data ke jaringan saraf untuk pelatihan. Jadi kita harus menulis tubuh untuk metode getitem yang dapat mengambil gambar, mengubahnya menjadi tensor dan meletakkannya kembali dan menandainya kembali sehingga PyTorch dapat bekerja dengannya. Semuanya jelas, tapi jelas skenario ini cukup umum, jadi mungkin PyTorch akan membuat tugasnya lebih mudah?



Membuat set data pelatihan



Paket torchvision menyertakan kelas ImageFolder yang melakukan hampir semua hal, dengan asumsi gambar kita berada dalam struktur di mana setiap direktori adalah label (misalnya, semua kucing ada dalam direktori bernama cat). Inilah yang Anda butuhkan untuk contoh kucing dan ikan:



import torchvision
from torchvision import transforms

train_data_path = "./train/"
transforms = transforms.Compose([
      transforms.Resize(64),
      transforms.ToTensor(),
      transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                std=[0.229, 0.224, 0.225] )
      ])

train_data = torchvision.datasets.ImageFolder
(root=train_data_path,transform=transforms)


Sesuatu yang lain ditambahkan di sini karena torchvision juga memungkinkan Anda menentukan daftar transformasi yang akan diterapkan ke gambar sebelum memasuki jaringan saraf. Transformasi default adalah mengambil data gambar dan mengubahnya menjadi tensor (metode trans forms.ToTensor () yang ditampilkan di kode sebelumnya), tetapi juga melakukan beberapa hal lain yang mungkin tidak terlalu jelas.



Pertama, GPU dibuat untuk melakukan komputasi ukuran standar yang cepat. Tapi kami mungkin memiliki bermacam-macam gambar dalam banyak resolusi. Untuk meningkatkan kinerja pemrosesan, kami menskalakan setiap gambar yang masuk ke resolusi 64x64 yang sama menggunakan transformasi Resize (64). Kemudian kami mengubah gambar menjadi tensor dan akhirnya menormalkan tensor di sekitar kumpulan titik rata-rata dan standar deviasi tertentu.



Normalisasi penting karena sejumlah besar perkalian diharapkan dilakukan saat masukan melewati lapisan jaringan saraf; menjaga nilai input antara 0 dan 1 mencegah peningkatan nilai yang besar selama fase pembelajaran (dikenal sebagai masalah gradien yang meledak). Inkarnasi ajaib ini hanyalah mean dan deviasi standar dari kumpulan data ImageNet secara keseluruhan. Anda dapat menghitungnya secara khusus untuk subset ikan dan kucing, tetapi nilai ini cukup dapat diandalkan. (Jika Anda mengerjakan kumpulan data yang sama sekali berbeda, mean dan varians ini harus dihitung, meskipun banyak yang hanya menggunakan konstanta ImageNet dan melaporkan hasil yang dapat diterima.)



Transformasi yang dapat digabungkan juga memudahkan untuk melakukan tindakan seperti rotasi gambar dan pergeseran gambar untuk augmentasi data, yang akan kita bahas di Bab 4.



Dalam contoh ini, kami mengubah ukuran gambar menjadi 64x64. Saya membuat pilihan acak ini untuk mempercepat komputasi di jaringan pertama kami. Sebagian besar arsitektur yang ada, yang akan Anda lihat di Bab 3, menggunakan gambar masukan 224x224 atau 299x299 .. Umumnya, semakin besar ukuran file masukan, semakin banyak data yang dapat dipelajari jaringan. Sisi lain dari koin ini adalah bahwa Anda biasanya dapat memasukkan sejumlah kecil gambar ke dalam memori GPU.


Ada banyak informasi lain tentang kumpulan data, dan itu belum semuanya. Tapi mengapa kita harus tahu lebih banyak daripada yang kita butuhkan jika kita sudah tahu tentang dataset pelatihan?



Validasi dan kumpulan data referensi



Dataset pelatihan kami sudah disiapkan, tetapi sekarang kami perlu mengulangi langkah yang sama dengan set data validasi. Apa bedanya disini? Salah satu kendala deep learning (dan sebenarnya semua machine learning) adalah overfitting: model ini sangat bagus dalam mengenali apa yang telah dilatih, tetapi tidak berfungsi pada contoh yang belum pernah dilihatnya. Model melihat gambar kucing, dan jika semua gambar kucing lainnya tidak terlalu mirip dengan ini, model memutuskan bahwa itu bukan kucing, meskipun yang jelas sebaliknya. Untuk mencegah jaringan saraf berperilaku seperti ini, kami memuat sampel kontrol ke download.py, yaitu, ke dalam rangkaian gambar kucing dan ikan yang tidak ada dalam set data pelatihan. Di akhir setiap siklus pelatihan (juga dikenal sebagai epoch), kami membandingkan set ini untuk memastikan jaringan tidak salah. Jangan khawatir, kode untuk pemeriksaan ini sangat sederhana:ini adalah kode yang sama dengan beberapa nama variabel yang diubah:



val_data_path = "./val/"
val_data = torchvision.datasets.ImageFolder(root=val_data_path,
                                                                  transform=transforms)


Kami hanya menggunakan rantai transformasi alih-alih mendefinisikannya lagi.



Selain dataset validasi, kita juga perlu membuat dataset validasi. Ini digunakan untuk menguji model setelah menyelesaikan semua pelatihan:



test_data_path = "./test/"
test_data = torchvision.datasets.ImageFolder(root=test_data_path,
                                                                   transform=transforms)


Sekilas, berbagai jenis set bisa jadi rumit dan membingungkan, jadi saya menyusun tabel untuk menunjukkan bagian pelatihan mana yang menggunakan setiap set (Tabel 2.1).



gambar


Sekarang kita dapat membuat pemuat data dengan beberapa baris lagi kode Python:



batch_size=64
train_data_loader = data.DataLoader(train_data, batch_size=batch_size)
val_data_loader = data.DataLoader(val_data, batch_size=batch_size)
test_data_loader = data.DataLoader(test_data, batch_size=batch_size)


Yang baru dan penting dalam kode ini adalah perintah batch_size. Dia mengatakan berapa banyak gambar yang akan melalui jaringan sebelum kami melatih dan memperbaruinya. Secara teori, kita bisa menetapkan batch_size ke serangkaian gambar dalam set data pengujian dan pelatihan sehingga jaringan melihat setiap gambar sebelum memuat ulang. Dalam praktiknya, ini biasanya tidak dilakukan karena paket yang lebih kecil (lebih dikenal dalam literatur sebagai paket mini) memerlukan lebih sedikit memori dan tidak perlu menyimpan semua informasi tentang setiap gambar dalam dataset, dan ukuran paket yang lebih kecil mengarah pada pembelajaran yang lebih cepat sejak jaringan. memperbarui lebih cepat. Untuk pemuat data PyTorch, batch_size disetel ke 1 secara default. Anda kemungkinan besar ingin mengubahnya. Meskipun saya memilih 64, Anda dapat bereksperimen untuk memahamiberapa banyak paket mini yang dapat digunakan tanpa kehabisan memori GPU. Bereksperimen dengan beberapa parameter tambahan: misalnya, Anda dapat menentukan bagaimana kumpulan data diambil, apakah seluruh kumpulan data diacak setiap kali dijalankan, dan berapa banyak alur kerja yang terlibat untuk mengambil data dari kumpulan data. Semua ini dapat ditemukan diDokumentasi PyTorch .



Ini tentang meneruskan data ke PyTorch, jadi sekarang mari kita bayangkan jaringan saraf sederhana yang akan mulai mengklasifikasikan gambar kita.



Akhirnya, jaringan saraf!



Kita akan mulai dengan jaringan pembelajaran dalam yang paling sederhana - lapisan masukan yang akan bekerja dengan tensor masukan (gambar kita); sebuah lapisan keluaran ukuran jumlah kelas keluaran kita (2); dan lapisan tersembunyi di antaranya. Pada contoh pertama, kita akan menggunakan layer yang terhubung sepenuhnya. Dalam gambar. 2.3 menunjukkan lapisan masukan dari tiga node,

lapisan tersembunyi dari tiga node dan output dari dua node.



Dalam contoh ini, setiap node dalam satu lapisan mempengaruhi node di lapisan berikutnya, dan setiap koneksi memiliki bobot yang menentukan kekuatan sinyal dari node tersebut ke lapisan berikutnya. (Ini adalah bobot yang akan diperbarui saat kita melatih jaringan, biasanya dari inisialisasi acak.) Saat masukan melewati jaringan, kita (atau PyTorch) dapat mengalikan matriks dengan mudah bobot dan bias lapisan itu dengan masukan. Sebelum meneruskannya ke fungsi berikutnya, hasil ini memasuki fungsi aktivasi, yang merupakan cara untuk memperkenalkan nonlinier ke dalam sistem kami.



gambar


Fungsi aktivasi



Fungsi aktivasi terdengar rumit, tetapi fungsi aktivasi paling umum yang dapat Anda temukan sekarang adalah ULT, atau unit linier tersearah. Lagi pintar! Tapi ini hanya fungsi yang mengimplementasikan max (0, x), jadi hasilnya 0 jika inputnya negatif, atau hanya input (x) jika x positif. Sesederhana itu!



Fungsi aktivasi lain yang paling mungkin Anda temui adalah fungsi logistik multivariat (softmax), yang sedikit lebih rumit dalam pengertian matematis. Pada dasarnya, ini menghasilkan satu set nilai dari 0 hingga 1, yang menambahkan hingga 1 (probabilitas!), Dan membobotkan nilai sedemikian rupa untuk meningkatkan perbedaan, yaitu, menghasilkan satu hasil dalam vektor yang akan lebih besar dari yang lain. Anda akan sering melihatnya digunakan di akhir jaringan klasifikasi untuk memastikan bahwa jaringan akan membuat prediksi yang pasti tentang kelas apa yang dianggapnya sebagai data masukan.



Sekarang setelah kita memiliki semua blok bangunan ini, kita dapat mulai membangun jaringan saraf pertama kita.



Pembuatan jaringan saraf



Membangun jaringan neural di PyTorch mirip dengan pemrograman di Python. Kami mewarisi dari kelas yang disebut torch.nn.Network dan mengisi metode __init__ dan meneruskan:



class SimpleNet(nn.Module):

def __init__(self):
     super(Net, self).__init__()
     self.fc1 = nn.Linear(12288, 84)
     self.fc2 = nn.Linear(84, 50)
     self.fc3 = nn.Linear(50,2)

def forward(self):
     x = x.view(-1, 12288)
     x = F.relu(self.fc1(x))
     x = F.relu(self.fc2(x))
     x = F.softmax(self.fc3(x))
     return x
simplenet = SimpleNet()


Sekali lagi, ini tidak sulit. Kami membuat pengaturan yang diperlukan di init (), dalam hal ini kami memanggil konstruktor superclass dan tiga lapisan yang terhubung sepenuhnya (disebut Linear di PyTorch, mereka disebut Dense in Keras). Metode forward () menjelaskan bagaimana data ditransmisikan melalui jaringan, baik dalam pelatihan maupun dalam prediksi (inferensi). Pertama, kita harus mengubah tensor 3D (x dan y ditambah informasi warna 3 saluran - merah, hijau, biru) pada gambar - perhatian! - menjadi tensor satu dimensi sehingga dapat diteruskan ke lapisan Linear pertama, dan kami melakukannya menggunakan view (). Jadi kami menerapkan lapisan dan fungsi aktivasi secara berurutan, mengembalikan output softmax untuk mendapatkan prediksi untuk gambar ini.



Angka-angka di lapisan tersembunyi itu sewenang-wenang, kecuali untuk keluaran lapisan terakhir, yaitu 2, yang cocok dengan dua kelas kita - kucing atau ikan. Membutuhkan data di lapisan untuk menyusut saat menyusut di tumpukan. Jika lapisannya berubah, katakanlah, dari 50 masukan menjadi 100 keluaran, maka jaringan dapat belajar hanya dengan meneruskan 50 koneksi ke lima puluh dari seratus keluaran, dan menganggap pekerjaannya telah selesai. Dengan mengurangi ukuran keluaran dalam kaitannya dengan masukan, kami memaksa bagian jaringan ini untuk mempelajari keterwakilan masukan asli dengan sumber daya yang lebih sedikit, yang mungkin berarti bahwa jaringan tersebut mendefinisikan beberapa fitur pembeda gambar: misalnya, ia belajar mengenali sirip atau ekor.



Kami memiliki perkiraan dan dapat membandingkannya dengan pelabelan sebenarnya dari gambar asli untuk melihat apakah itu benar. Tetapi Anda memerlukan beberapa cara untuk memungkinkan PyTorch mengukur tidak hanya kebenaran atau ketidaktepatan prediksi, tetapi juga seberapa benar atau tidak benarnya prediksi tersebut. Fungsi kerugian melakukan ini.



TENTANG PENULIS



Ian Poynter (Ian Pointer) - Ilmu data insinyur, yang mengkhususkan diri dalam solusi untuk pembelajaran mesin (termasuk metode pengajaran yang mendalam) untuk sejumlah klien di Fortune 100. Saat ini, Yang bekerja di Lucidworks, yang terlibat dalam pengembangan aplikasi lanjutan dan NLP.



»Rincian lebih lanjut tentang buku dapat ditemukan di situs web penerbit

» Daftar isi

» Kutipan



Untuk Habitants diskon 25% untuk kupon - PyTorch



Setelah pembayaran untuk versi kertas buku tersebut, sebuah e-book dikirim ke email.



All Articles