Jaringan saraf pertama Anda pada unit pemrosesan grafis (GPU). Panduan Pemula

Jaringan saraf pertama Anda pada unit pemrosesan grafis (GPU). Panduan Pemula
Pada artikel ini, saya akan memberi tahu Anda cara menyiapkan lingkungan pembelajaran mesin dalam 30 menit, membuat jaringan saraf untuk pengenalan gambar, dan kemudian menjalankan jaringan yang sama pada prosesor grafis (GPU).

Pertama, mari kita definisikan apa itu jaringan saraf.

Dalam kasus kami, ini adalah model matematika, serta perwujudan perangkat lunak atau perangkat kerasnya, yang dibangun berdasarkan prinsip pengorganisasian dan fungsi jaringan saraf biologis - jaringan sel saraf organisme hidup. Konsep ini muncul ketika mempelajari proses yang terjadi di otak dan mencoba memodelkan proses tersebut.

Jaringan saraf tidak diprogram dalam arti kata yang biasa, melainkan dilatih. Kemampuan untuk belajar adalah salah satu keunggulan utama jaringan saraf dibandingkan algoritma tradisional. Secara teknis, pembelajaran terdiri dari mencari koefisien hubungan antar neuron. Selama proses pelatihan, jaringan saraf mampu mengidentifikasi ketergantungan kompleks antara data masukan dan data keluaran, serta melakukan generalisasi.

Dari sudut pandang pembelajaran mesin, jaringan saraf adalah kasus khusus dari metode pengenalan pola, analisis diskriminan, metode pengelompokan, dan metode lainnya.

Оборудование

Pertama, mari kita lihat perlengkapannya. Kami memerlukan server dengan sistem operasi Linux yang diinstal di dalamnya. Peralatan yang diperlukan untuk mengoperasikan sistem pembelajaran mesin cukup kuat dan akibatnya mahal. Bagi mereka yang tidak memiliki mesin yang bagus, saya sarankan untuk memperhatikan penawaran dari penyedia cloud. Anda dapat menyewa server yang diperlukan dengan cepat dan hanya membayar waktu penggunaan.

Dalam proyek yang memerlukan pembuatan jaringan saraf, saya menggunakan server salah satu penyedia cloud Rusia. Perusahaan ini menawarkan penyewaan server cloud khusus untuk pembelajaran mesin dengan prosesor grafis (GPU) Tesla V100 yang kuat dari NVIDIA. Singkatnya: menggunakan server dengan GPU bisa puluhan kali lebih efisien (cepat) dibandingkan dengan server dengan biaya serupa yang menggunakan CPU (unit pemrosesan pusat yang terkenal) untuk perhitungan. Hal ini dicapai karena kekhasan arsitektur GPU, yang mengatasi penghitungan lebih cepat.

Untuk menerapkan contoh yang dijelaskan di bawah ini, kami membeli server berikut selama beberapa hari:

  • Disk SSD 150GB
  • RAMnya 32GB
  • Prosesor Tesla V100 16 Gb dengan 4 core

Kami menginstal Ubuntu 18.04 di mesin kami.

Menyiapkan lingkungan

Sekarang mari kita instal semua yang diperlukan untuk bekerja di server. Karena artikel kami ditujukan terutama untuk pemula, saya akan membahas beberapa poin yang akan berguna bagi mereka.

Banyak pekerjaan saat menyiapkan lingkungan dilakukan melalui baris perintah. Sebagian besar pengguna menggunakan Windows sebagai OS kerjanya. Konsol standar di OS ini menyisakan banyak hal yang diinginkan. Oleh karena itu, kami akan menggunakan alat yang mudah digunakan Cmder/. Unduh versi mini dan jalankan Cmder.exe. Selanjutnya Anda perlu terhubung ke server melalui SSH:

ssh root@server-ip-or-hostname

Daripada menggunakan ip-atau-nama host-server, tentukan alamat IP atau nama DNS server Anda. Selanjutnya masukkan password dan jika koneksi berhasil, kita akan menerima pesan seperti ini.

Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-74-generic x86_64)

Bahasa utama untuk mengembangkan model ML adalah Python. Dan platform yang paling populer untuk penggunaannya di Linux adalah Anaconda.

Mari kita instal di server kita.

Kami mulai dengan memperbarui manajer paket lokal:

sudo apt-get update

Instal curl (utilitas baris perintah):

sudo apt-get install curl

Unduh Distribusi Anaconda versi terbaru:

cd /tmp
curl –O https://repo.anaconda.com/archive/Anaconda3-2019.10-Linux-x86_64.sh

Mari kita mulai instalasinya:

bash Anaconda3-2019.10-Linux-x86_64.sh

Selama proses instalasi, Anda akan diminta untuk mengkonfirmasi perjanjian lisensi. Setelah instalasi berhasil, Anda akan melihat ini:

Thank you for installing Anaconda3!

Banyak kerangka kerja kini telah dibuat untuk pengembangan model ML; kami bekerja dengan yang paling populer: PyTorch и aliran tensor.

Penggunaan kerangka kerja memungkinkan Anda meningkatkan kecepatan pengembangan dan menggunakan alat yang sudah jadi untuk tugas-tugas standar.

Dalam contoh ini kita akan bekerja dengan PyTorch. Mari kita instal:

conda install pytorch torchvision cudatoolkit=10.1 -c pytorch

Sekarang kita perlu meluncurkan Jupyter Notebook, alat pengembangan populer untuk spesialis ML. Ini memungkinkan Anda untuk menulis kode dan segera melihat hasil eksekusinya. Notebook Jupyter disertakan dengan Anaconda dan sudah diinstal di server kami. Anda perlu menyambungkannya dari sistem desktop kami.

Untuk melakukan ini, pertama-tama kita akan meluncurkan Jupyter di server yang menentukan port 8080:

jupyter notebook --no-browser --port=8080 --allow-root

Selanjutnya, membuka tab lain di konsol Cmder kami (menu atas - Dialog konsol baru) kami akan terhubung melalui port 8080 ke server melalui SSH:

ssh -L 8080:localhost:8080 root@server-ip-or-hostname

Saat kami memasukkan perintah pertama, kami akan ditawari tautan untuk membuka Jupyter di browser kami:

To access the notebook, open this file in a browser:
        file:///root/.local/share/jupyter/runtime/nbserver-18788-open.html
    Or copy and paste one of these URLs:
        http://localhost:8080/?token=cca0bd0b30857821194b9018a5394a4ed2322236f116d311
     or http://127.0.0.1:8080/?token=cca0bd0b30857821194b9018a5394a4ed2322236f116d311

Mari gunakan tautan untuk localhost:8080. Salin jalur lengkap dan tempel ke bilah alamat browser lokal PC Anda. Buku Catatan Jupyter akan terbuka.

Mari buat buku catatan baru: Baru - Buku Catatan - Python 3.

Mari kita periksa kebenaran pengoperasian semua komponen yang kita pasang. Mari masukkan contoh kode PyTorch ke Jupyter dan jalankan eksekusi (tombol Jalankan):

from __future__ import print_function
import torch
x = torch.rand(5, 3)
print(x)

Hasilnya akan seperti ini:

Jaringan saraf pertama Anda pada unit pemrosesan grafis (GPU). Panduan Pemula

Jika Anda mendapatkan hasil yang serupa, maka kami telah mengonfigurasi semuanya dengan benar dan kami dapat mulai mengembangkan jaringan saraf!

Membuat jaringan saraf

Kami akan membuat jaringan saraf untuk pengenalan gambar. Mari kita ambil ini sebagai dasar panduan.

Kami akan menggunakan kumpulan data CIFAR10 yang tersedia untuk umum untuk melatih jaringan. Ia memiliki kelas: “pesawat”, “mobil”, “burung”, “kucing”, “rusa”, “anjing”, “katak”, “kuda”, “kapal”, “truk”. Gambar di CIFAR10 berukuran 3x32x32, yaitu gambar berwarna 3 saluran berukuran 32x32 piksel.

Jaringan saraf pertama Anda pada unit pemrosesan grafis (GPU). Panduan Pemula
Untuk bekerja, kami akan menggunakan paket yang dibuat oleh PyTorch untuk bekerja dengan gambar - torchvision.

Kami akan melakukan langkah-langkah berikut secara berurutan:

  • Memuat dan menormalkan kumpulan data pelatihan dan pengujian
  • Definisi Jaringan Syaraf Tiruan
  • Pelatihan jaringan pada data pelatihan
  • Pengujian jaringan pada data pengujian
  • Mari ulangi pelatihan dan pengujian menggunakan GPU

Kami akan mengeksekusi semua kode di bawah ini di Jupyter Notebook.

Memuat dan normalisasi CIFAR10

Salin dan jalankan kode berikut di Jupyter:


import torch
import torchvision
import torchvision.transforms as transforms

transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
                                        download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
                                          shuffle=True, num_workers=2)

testset = torchvision.datasets.CIFAR10(root='./data', train=False,
                                       download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=4,
                                         shuffle=False, num_workers=2)

classes = ('plane', 'car', 'bird', 'cat',
           'deer', 'dog', 'frog', 'horse', 'ship', 'truck')

Jawabannya seharusnya:

Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to ./data/cifar-10-python.tar.gz
Extracting ./data/cifar-10-python.tar.gz to ./data
Files already downloaded and verified

Mari kita tampilkan beberapa gambar pelatihan untuk pengujian:


import matplotlib.pyplot as plt
import numpy as np

# functions to show an image

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

# get some random training images
dataiter = iter(trainloader)
images, labels = dataiter.next()

# show images
imshow(torchvision.utils.make_grid(images))
# print labels
print(' '.join('%5s' % classes[labels[j]] for j in range(4)))

Jaringan saraf pertama Anda pada unit pemrosesan grafis (GPU). Panduan Pemula

Definisi Jaringan Syaraf Tiruan

Pertama-tama mari kita pertimbangkan cara kerja jaringan saraf untuk pengenalan gambar. Ini adalah jaringan point-to-point yang sederhana. Dibutuhkan data masukan, meneruskannya melalui beberapa lapisan satu per satu, dan akhirnya menghasilkan data keluaran.

Jaringan saraf pertama Anda pada unit pemrosesan grafis (GPU). Panduan Pemula

Mari buat jaringan serupa di lingkungan kita:


import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 16 * 5 * 5)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

net = Net()

Kami juga mendefinisikan fungsi kerugian dan pengoptimal


import torch.optim as optim

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

Pelatihan jaringan pada data pelatihan

Mari kita mulai melatih jaringan saraf kita. Harap dicatat bahwa setelah Anda menjalankan kode ini, Anda perlu menunggu beberapa saat hingga pekerjaan selesai. Butuh waktu 5 menit. Perlu waktu untuk melatih jaringan.

 for epoch in range(2):  # loop over the dataset multiple times

    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        # get the inputs; data is a list of [inputs, labels]
        inputs, labels = data

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()
        if i % 2000 == 1999:    # print every 2000 mini-batches
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

print('Finished Training')

Kami mendapatkan hasil berikut:

Jaringan saraf pertama Anda pada unit pemrosesan grafis (GPU). Panduan Pemula

Kami menyimpan model terlatih kami:

PATH = './cifar_net.pth'
torch.save(net.state_dict(), PATH)

Pengujian jaringan pada data pengujian

Kami melatih jaringan menggunakan sekumpulan data pelatihan. Namun kita perlu memeriksa apakah jaringan telah mempelajari sesuatu.

Kami akan mengujinya dengan memprediksi label kelas yang dihasilkan jaringan saraf dan mengujinya untuk melihat apakah label tersebut benar. Jika prediksinya benar, kami menambahkan sampel ke daftar prediksi yang benar.
Mari kita tampilkan gambar dari set pengujian:

dataiter = iter(testloader)
images, labels = dataiter.next()

# print images
imshow(torchvision.utils.make_grid(images))
print('GroundTruth: ', ' '.join('%5s' % classes[labels[j]] for j in range(4)))

Jaringan saraf pertama Anda pada unit pemrosesan grafis (GPU). Panduan Pemula

Sekarang mari kita minta jaringan saraf untuk memberi tahu kita apa yang ada di gambar ini:


net = Net()
net.load_state_dict(torch.load(PATH))

outputs = net(images)

_, predicted = torch.max(outputs, 1)

print('Predicted: ', ' '.join('%5s' % classes[predicted[j]]
                              for j in range(4)))

Jaringan saraf pertama Anda pada unit pemrosesan grafis (GPU). Panduan Pemula

Hasilnya tampak cukup bagus: jaringan mengidentifikasi tiga dari empat gambar dengan benar.

Mari kita lihat bagaimana kinerja jaringan di seluruh kumpulan data.


correct = 0
total = 0
with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = net(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print('Accuracy of the network on the 10000 test images: %d %%' % (
    100 * correct / total))

Jaringan saraf pertama Anda pada unit pemrosesan grafis (GPU). Panduan Pemula

Sepertinya jaringan mengetahui sesuatu dan berfungsi. Jika dia menentukan kelas secara acak, akurasinya adalah 10%.

Sekarang mari kita lihat kelas mana yang diidentifikasi jaringan dengan lebih baik:

class_correct = list(0. for i in range(10))
class_total = list(0. for i in range(10))
with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = net(images)
        _, predicted = torch.max(outputs, 1)
        c = (predicted == labels).squeeze()
        for i in range(4):
            label = labels[i]
            class_correct[label] += c[i].item()
            class_total[label] += 1


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

Jaringan saraf pertama Anda pada unit pemrosesan grafis (GPU). Panduan Pemula

Tampaknya jaringan ini paling baik dalam mengidentifikasi mobil dan kapal: akurasi 71%.

Jadi jaringannya berfungsi. Sekarang mari kita coba mentransfer pekerjaannya ke pengolah grafis (GPU) dan lihat perubahannya.

Melatih jaringan saraf pada GPU

Pertama saya akan menjelaskan secara singkat apa itu CUDA. CUDA (Compute Unified Device Architecture) adalah platform komputasi paralel yang dikembangkan oleh NVIDIA untuk komputasi umum pada unit pemrosesan grafis (GPU). Dengan CUDA, pengembang dapat mempercepat aplikasi komputasi secara dramatis dengan memanfaatkan kekuatan GPU. Platform ini sudah terinstal di server yang kami beli.

Pertama mari kita definisikan GPU kita sebagai perangkat cuda pertama yang terlihat.

device = torch . device ( "cuda:0" if torch . cuda . is_available () else "cpu" )
# Assuming that we are on a CUDA machine, this should print a CUDA device:
print ( device )

Jaringan saraf pertama Anda pada unit pemrosesan grafis (GPU). Panduan Pemula

Mengirim jaringan ke GPU:

net.to(device)

Kami juga harus mengirimkan masukan dan target di setiap langkah ke GPU:

inputs, labels = data[0].to(device), data[1].to(device)

Mari kita latih kembali jaringan pada GPU:

import torch.optim as optim

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
for epoch in range(2):  # loop over the dataset multiple times

    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        # get the inputs; data is a list of [inputs, labels]
    inputs, labels = data[0].to(device), data[1].to(device)

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()
        if i % 2000 == 1999:    # print every 2000 mini-batches
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

print('Finished Training')

Pelatihan jaringan kali ini berlangsung sekitar 3 menit. Ingatlah bahwa tahap yang sama pada prosesor konvensional berlangsung selama 5 menit. Perbedaannya tidak terlalu signifikan, hal ini terjadi karena jaringan kita tidak begitu besar. Saat menggunakan array besar untuk pelatihan, perbedaan antara kecepatan GPU dan prosesor tradisional akan meningkat.

Sepertinya itu saja. Apa yang berhasil kami lakukan:

  • Kami melihat apa itu GPU dan memilih server tempat GPU tersebut diinstal;
  • Kami telah menyiapkan lingkungan perangkat lunak untuk membuat jaringan saraf;
  • Kami menciptakan jaringan saraf untuk pengenalan gambar dan melatihnya;
  • Kami mengulangi pelatihan jaringan menggunakan GPU dan menerima peningkatan kecepatan.

Saya akan dengan senang hati menjawab pertanyaan di komentar.

Sumber: www.habr.com

Tambah komentar