Bagikan melalui


Melatih model pengklasifikasi gambar Anda dengan PyTorch

Pada tahap sebelumnya dari tutorial ini, kami memperoleh himpunan data yang akan kami gunakan untuk melatih pengklasifikasi gambar kami dengan PyTorch. Sekarang, saatnya untuk menggunakan data itu.

Untuk melatih pengklasifikasi gambar dengan PyTorch, Anda perlu menyelesaikan langkah-langkah berikut:

  1. Muat data. Jika Anda telah melakukan langkah sebelumnya dari tutorial ini, Anda telah menanganinya.
  2. Tentukan Jaringan Neural Konvolusi.
  3. Tentukan fungsi kehilangan.
  4. Latih model pada data pelatihan.
  5. Uji jaringan pada data pengujian.

Tentukan Jaringan Neural Konvolusi.

Untuk membangun jaringan neural dengan PyTorch, Anda akan menggunakan paket tersebut torch.nn . Paket ini berisi modul, kelas yang dapat diperluas, dan semua komponen yang diperlukan untuk membangun jaringan neural.

Di sini, Anda akan membangun jaringan neural konvolusi dasar (CNN) untuk mengklasifikasikan gambar dari himpunan data CIFAR10.

CNN adalah kelas jaringan saraf, didefinisikan sebagai jaringan saraf multilayer yang dirancang untuk mendeteksi fitur kompleks dalam data. Mereka paling umum digunakan dalam aplikasi visi komputer.

Jaringan kami akan disusun dengan 14 lapisan berikut:

Conv -> BatchNorm -> ReLU -> Conv -> BatchNorm -> ReLU -> MaxPool -> Conv -> BatchNorm -> ReLU -> Conv -> BatchNorm -> ReLU -> Linear.

Lapisan konvolusi

Lapisan konvolusi adalah lapisan utama CNN yang membantu kami mendeteksi fitur dalam gambar. Masing-masing lapisan memiliki jumlah saluran untuk mendeteksi fitur tertentu dalam gambar, dan sejumlah kernel untuk menentukan ukuran fitur yang terdeteksi. Oleh karena itu, lapisan konvolusi dengan 64 saluran dan ukuran kernel 3 x 3 akan mendeteksi 64 fitur yang berbeda, masing-masing berukuran 3 x 3. Ketika Anda menentukan lapisan konvolusi, Anda menyediakan jumlah dalam saluran, jumlah saluran luar, dan ukuran kernel. Jumlah saluran keluar dalam lapisan berfungsi sebagai jumlah dalam saluran ke lapisan berikutnya.

Misalnya: Lapisan Konvolusi dengan in-channels=3, out-channels=10, dan kernel-size=6 akan mendapatkan gambar RGB (3 saluran) sebagai input, dan akan menerapkan 10 detektor fitur ke gambar dengan ukuran kernel 6x6. Ukuran kernel yang lebih kecil akan mengurangi waktu komputasi dan berbagi berat badan.

Lapisan lainnya

Lapisan lain berikut terlibat dalam jaringan kami:

  • Lapisan ReLU adalah fungsi aktivasi untuk menentukan semua fitur masuk menjadi 0 atau lebih besar. Ketika Anda menerapkan lapisan ini, angka apa pun yang kurang dari 0 diubah menjadi nol, sementara yang lain tetap sama.
  • BatchNorm2d lapisan menerapkan normalisasi pada input untuk memiliki nilai rata-rata nol dan varian unit dan meningkatkan akurasi jaringan.
  • Lapisan ini MaxPool akan membantu kami memastikan bahwa lokasi objek dalam gambar tidak akan memengaruhi kemampuan jaringan neural untuk mendeteksi fitur spesifiknya.
  • Lapisan Linear ini adalah lapisan akhir di jaringan kami, yang menghitung skor masing-masing kelas. Dalam himpunan data CIFAR10, ada sepuluh kelas label. Label dengan skor tertinggi akan menjadi salah satu prediksi model. Di lapisan linier, Anda harus menentukan jumlah fitur input dan jumlah fitur output yang harus sesuai dengan jumlah kelas.

Bagaimana cara kerja Jaringan Neural?

CNN adalah jaringan feed-forward. Selama proses pelatihan, jaringan akan memproses input melalui semua lapisan, menghitung kerugian untuk memahami seberapa jauh label gambar yang diprediksi jatuh dari yang benar, dan menyebarluaskan gradien kembali ke jaringan untuk memperbarui bobot lapisan. Dengan melakukan iterasi pada himpunan data input yang besar, jaringan akan "belajar" untuk mengatur bobotnya untuk mencapai hasil terbaik.

Fungsi penerusan menghitung nilai fungsi kerugian, dan fungsi mundur menghitung gradien parameter yang dapat dipelajari. Ketika Anda membuat jaringan neural kami dengan PyTorch, Anda hanya perlu menentukan fungsi penerusan. Fungsi mundur akan ditentukan secara otomatis.

  1. Salin kode berikut ke PyTorchTraining.py dalam file di Visual Studio untuk menentukan CCN.
import torch
import torch.nn as nn
import torchvision
import torch.nn.functional as F

# Define a convolution neural network
class Network(nn.Module):
    def __init__(self):
        super(Network, self).__init__()
        
        self.conv1 = nn.Conv2d(in_channels=3, out_channels=12, kernel_size=5, stride=1, padding=1)
        self.bn1 = nn.BatchNorm2d(12)
        self.conv2 = nn.Conv2d(in_channels=12, out_channels=12, kernel_size=5, stride=1, padding=1)
        self.bn2 = nn.BatchNorm2d(12)
        self.pool = nn.MaxPool2d(2,2)
        self.conv4 = nn.Conv2d(in_channels=12, out_channels=24, kernel_size=5, stride=1, padding=1)
        self.bn4 = nn.BatchNorm2d(24)
        self.conv5 = nn.Conv2d(in_channels=24, out_channels=24, kernel_size=5, stride=1, padding=1)
        self.bn5 = nn.BatchNorm2d(24)
        self.fc1 = nn.Linear(24*10*10, 10)

    def forward(self, input):
        output = F.relu(self.bn1(self.conv1(input)))      
        output = F.relu(self.bn2(self.conv2(output)))     
        output = self.pool(output)                        
        output = F.relu(self.bn4(self.conv4(output)))     
        output = F.relu(self.bn5(self.conv5(output)))     
        output = output.view(-1, 24*10*10)
        output = self.fc1(output)

        return output

# Instantiate a neural network model 
model = Network()

Catatan

Tertarik untuk mempelajari lebih lanjut tentang jaringan neural dengan PyTorch? Lihat dokumentasi PyTorch

Menentukan fungsi kehilangan

Fungsi kerugian menghitung nilai yang memperkirakan seberapa jauh output dari target. Tujuan utamanya adalah untuk mengurangi nilai fungsi kehilangan dengan mengubah nilai vektor bobot melalui backpropagation di jaringan neural.

Nilai kerugian berbeda dari akurasi model. Fungsi kehilangan memberi kita pemahaman tentang seberapa baik model berperilaku setelah setiap iterasi pengoptimalan pada set pelatihan. Akurasi model dihitung pada data pengujian dan menunjukkan persentase prediksi yang tepat.

Di PyTorch, paket jaringan neural berisi berbagai fungsi kehilangan yang membentuk blok penyusun jaringan neural dalam. Dalam tutorial ini, Anda akan menggunakan fungsi kehilangan Klasifikasi berdasarkan Tentukan fungsi kerugian dengan Klasifikasi Kehilangan Lintas Entropi dan Pengoptimal Adam. laju Pembelajaran (lr) mengatur kontrol berapa banyak Anda menyesuaikan bobot jaringan kami sehubungan dengan gradien kehilangan. Anda akan mengaturnya sebagai 0,001. Semakin rendah, semakin lambat pelatihannya.

  1. Salin kode berikut ke PyTorchTraining.py dalam file di Visual Studio untuk menentukan fungsi kehilangan dan pengoptimal.
from torch.optim import Adam
 
# Define the loss function with Classification Cross-Entropy loss and an optimizer with Adam optimizer
loss_fn = nn.CrossEntropyLoss()
optimizer = Adam(model.parameters(), lr=0.001, weight_decay=0.0001)

Latih model pada data pelatihan.

Untuk melatih model, Anda harus mengulang iterator data kami, mengumpankan input ke jaringan, dan mengoptimalkan. PyTorch tidak memiliki pustaka khusus untuk penggunaan GPU, tetapi Anda dapat menentukan perangkat eksekusi secara manual. Perangkat akan menjadi GPU Nvidia jika ada di komputer Anda, atau CPU Anda jika tidak.

  1. Tambahkan kode berikut ke PyTorchTraining.py file
from torch.autograd import Variable

# Function to save the model
def saveModel():
    path = "./myFirstModel.pth"
    torch.save(model.state_dict(), path)

# Function to test the model with the test dataset and print the accuracy for the test images
def testAccuracy():
    
    model.eval()
    accuracy = 0.0
    total = 0.0
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    
    with torch.no_grad():
        for data in test_loader:
            images, labels = data
            # run the model on the test set to predict labels
            outputs = model(images.to(device))
            # the label with the highest energy will be our prediction
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            accuracy += (predicted == labels.to(device)).sum().item()
    
    # compute the accuracy over all test images
    accuracy = (100 * accuracy / total)
    return(accuracy)


# Training function. We simply have to loop over our data iterator and feed the inputs to the network and optimize.
def train(num_epochs):
    
    best_accuracy = 0.0

    # Define your execution device
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    print("The model will be running on", device, "device")
    # Convert model parameters and buffers to CPU or Cuda
    model.to(device)

    for epoch in range(num_epochs):  # loop over the dataset multiple times
        running_loss = 0.0
        running_acc = 0.0

        for i, (images, labels) in enumerate(train_loader, 0):
            
            # get the inputs
            images = Variable(images.to(device))
            labels = Variable(labels.to(device))

            # zero the parameter gradients
            optimizer.zero_grad()
            # predict classes using images from the training set
            outputs = model(images)
            # compute the loss based on model output and real labels
            loss = loss_fn(outputs, labels)
            # backpropagate the loss
            loss.backward()
            # adjust parameters based on the calculated gradients
            optimizer.step()

            # Let's print statistics for every 1,000 images
            running_loss += loss.item()     # extract the loss value
            if i % 1000 == 999:    
                # print every 1000 (twice per epoch) 
                print('[%d, %5d] loss: %.3f' %
                      (epoch + 1, i + 1, running_loss / 1000))
                # zero the loss
                running_loss = 0.0

        # Compute and print the average accuracy fo this epoch when tested over all 10000 test images
        accuracy = testAccuracy()
        print('For epoch', epoch+1,'the test accuracy over the whole test set is %d %%' % (accuracy))
        
        # we want to save the model if the accuracy is the best
        if accuracy > best_accuracy:
            saveModel()
            best_accuracy = accuracy

Uji model pada data pengujian.

Sekarang, Anda dapat menguji model dengan batch gambar dari set pengujian kami.

  1. Tambahkan kode berikut ke file PyTorchTraining.py.
import matplotlib.pyplot as plt
import numpy as np

# Function to show the images
def imageshow(img):
    img = img / 2 + 0.5     # unnormalize
    npimg = img.numpy()
    plt.imshow(np.transpose(npimg, (1, 2, 0)))
    plt.show()


# Function to test the model with a batch of images and show the labels predictions
def testBatch():
    # get batch of images from the test DataLoader  
    images, labels = next(iter(test_loader))

    # show all images as one image grid
    imageshow(torchvision.utils.make_grid(images))
   
    # Show the real labels on the screen 
    print('Real labels: ', ' '.join('%5s' % classes[labels[j]] 
                               for j in range(batch_size)))
  
    # Let's see what if the model identifiers the  labels of those example
    outputs = model(images)
    
    # We got the probability for every 10 labels. The highest (max) probability should be correct label
    _, predicted = torch.max(outputs, 1)
    
    # Let's show the predicted labels on the screen to compare with the real ones
    print('Predicted: ', ' '.join('%5s' % classes[predicted[j]] 
                              for j in range(batch_size)))

Terakhir, mari kita tambahkan kode utama. Ini akan memulai pelatihan model, menyimpan model, dan menampilkan hasilnya di layar. Kami hanya akan menjalankan dua iterasi [train(2)] selama set pelatihan, sehingga proses pelatihan tidak akan memakan waktu terlalu lama.

  1. Tambahkan kode berikut ke file PyTorchTraining.py.
if __name__ == "__main__":
    
    # Let's build our model
    train(5)
    print('Finished Training')

    # Test which classes performed well
    testAccuracy()
    
    # Let's load the model we just created and test the accuracy per label
    model = Network()
    path = "myFirstModel.pth"
    model.load_state_dict(torch.load(path))

    # Test with batch of images
    testBatch()

Mari kita jalankan tes! Pastikan menu dropdown di toolbar atas diatur ke Debug. Ubah Platform Solusi ke x64 untuk menjalankan proyek di komputer lokal Anda jika perangkat Anda 64-bit, atau x86 jika 32-bit.

Memilih nomor epoch (jumlah lengkap melewati himpunan data pelatihan) sama dengan dua ([train(2)]) akan menghasilkan iterasi dua kali melalui seluruh himpunan data pengujian 10.000 gambar. Dibutuhkan waktu sekitar 20 menit untuk menyelesaikan pelatihan pada CPU Intel Generasi ke-8, dan model harus mencapai lebih atau kurang 65% tingkat keberhasilan dalam klasifikasi sepuluh label.

  1. Untuk menjalankan proyek, klik tombol Mulai Penelusuran Kesalahan pada toolbar, atau tekan F5.

Jendela konsol akan muncul dan akan dapat melihat proses pelatihan.

Seperti yang Anda tentukan, nilai kerugian akan dicetak setiap 1.000 batch gambar atau lima kali untuk setiap iterasi selama set pelatihan. Anda mengharapkan nilai kerugian berkurang dengan setiap perulangan.

Anda juga akan melihat akurasi model setelah setiap perulangan. Akurasi model berbeda dari nilai kerugian. Fungsi kehilangan memberi kita pemahaman tentang seberapa baik model berperilaku setelah setiap iterasi pengoptimalan pada set pelatihan. Akurasi model dihitung pada data pengujian dan menunjukkan persentase prediksi yang tepat. Dalam kasus kami, ini akan memberi tahu kami berapa banyak gambar dari set pengujian 10.000 gambar yang dapat diklasifikasikan dengan benar setelah setiap iterasi pelatihan.

Setelah pelatihan selesai, Anda akan mengharapkan untuk melihat output yang mirip dengan di bawah ini. Angka Anda tidak akan sama persis - trianing tergantung pada banyak faktor, dan tidak akan selalu mengembalikan hasil identifikasi - tetapi mereka akan terlihat mirip.

Output from initial model training

Setelah menjalankan hanya 5 epoch, tingkat keberhasilan model adalah 70%. Ini adalah hasil yang baik untuk model dasar yang dilatih untuk waktu yang singkat!

Pengujian dengan batch gambar, model mendapatkan 7 gambar yang tepat dari batch 10. Tidak buruk sama sekali dan konsisten dengan tingkat keberhasilan model.

Successfully classified images

Anda dapat memeriksa kelas mana yang dapat diprediksi model kami yang terbaik. Sederhana tambahkan jalankan kode di bawah ini:

  1. Opsional - tambahkan fungsi berikut testClassess ke PyTorchTraining.py dalam file, tambahkan panggilan fungsi ini - testClassess() di dalam fungsi utama - __name__ == "__main__".
# Function to test what classes performed well
def testClassess():
    class_correct = list(0. for i in range(number_of_labels))
    class_total = list(0. for i in range(number_of_labels))
    with torch.no_grad():
        for data in test_loader:
            images, labels = data
            outputs = model(images)
            _, predicted = torch.max(outputs, 1)
            c = (predicted == labels).squeeze()
            for i in range(batch_size):
                label = labels[i]
                class_correct[label] += c[i].item()
                class_total[label] += 1

    for i in range(number_of_labels):
        print('Accuracy of %5s : %2d %%' % (
            classes[i], 100 * class_correct[i] / class_total[i]))

Outputnya sebagai berikut:

Initial classification accuracy

Langkah berikutnya

Sekarang setelah kita memiliki model klasifikasi, langkah selanjutnya adalah mengonversi model ke format ONNX