Mạng thần kinh đầu tiên của bạn trên bộ xử lý đồ họa (GPU). Hướng dẫn cho người mới bắt đầu

Mạng thần kinh đầu tiên của bạn trên bộ xử lý đồ họa (GPU). Hướng dẫn cho người mới bắt đầu
Trong bài viết này, tôi sẽ cho bạn biết cách thiết lập môi trường máy học trong 30 phút, tạo mạng thần kinh để nhận dạng hình ảnh, sau đó chạy cùng một mạng trên bộ xử lý đồ họa (GPU).

Đầu tiên, hãy định nghĩa mạng lưới thần kinh là gì.

Trong trường hợp của chúng tôi, đây là một mô hình toán học, cũng như phương án phần mềm hoặc phần cứng của nó, được xây dựng dựa trên nguyên tắc tổ chức và hoạt động của mạng lưới thần kinh sinh học - mạng lưới các tế bào thần kinh của một sinh vật sống. Khái niệm này nảy sinh khi nghiên cứu các quá trình xảy ra trong não và cố gắng mô hình hóa các quá trình này.

Mạng lưới thần kinh không được lập trình theo nghĩa thông thường của từ này, chúng được đào tạo. Khả năng học hỏi là một trong những lợi thế chính của mạng lưới thần kinh so với các thuật toán truyền thống. Về mặt kỹ thuật, việc học bao gồm việc tìm ra hệ số kết nối giữa các nơ-ron. Trong quá trình đào tạo, mạng nơ-ron có thể xác định các mối phụ thuộc phức tạp giữa dữ liệu đầu vào và dữ liệu đầu ra, cũng như thực hiện khái quát hóa.

Từ quan điểm của học máy, mạng lưới thần kinh là một trường hợp đặc biệt của các phương pháp nhận dạng mẫu, phân tích phân biệt, phương pháp phân cụm và các phương pháp khác.

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

Đầu tiên, chúng ta hãy nhìn vào thiết bị. Chúng tôi cần một máy chủ có cài đặt hệ điều hành Linux trên đó. Thiết bị cần thiết để vận hành hệ thống máy học khá mạnh và do đó đắt tiền. Đối với những người không có sẵn một chiếc máy tốt, tôi khuyên bạn nên chú ý đến lời đề nghị của các nhà cung cấp đám mây. Bạn có thể thuê máy chủ theo yêu cầu một cách nhanh chóng và chỉ trả tiền cho thời gian sử dụng.

Trong các dự án cần tạo mạng thần kinh, tôi sử dụng máy chủ của một trong những nhà cung cấp đám mây của Nga. Công ty cung cấp dịch vụ cho thuê máy chủ đám mây dành riêng cho machine learning với bộ xử lý đồ họa (GPU) Tesla V100 mạnh mẽ của NVIDIA. Tóm lại: sử dụng máy chủ có GPU có thể hiệu quả hơn (nhanh) gấp hàng chục lần so với máy chủ có cùng mức giá nhưng sử dụng CPU (bộ xử lý trung tâm nổi tiếng) để tính toán. Điều này đạt được nhờ các tính năng của kiến ​​​​trúc GPU, giúp xử lý các phép tính nhanh hơn.

Để triển khai các ví dụ được mô tả bên dưới, chúng tôi đã mua máy chủ sau trong vài ngày:

  • Ổ cứng SSD 150GB
  • RAM 32 GB
  • Bộ xử lý Tesla V100 16 Gb 4 nhân

Chúng tôi đã cài đặt Ubuntu 18.04 trên máy của mình.

Thiết lập môi trường

Bây giờ hãy cài đặt mọi thứ cần thiết cho công việc trên máy chủ. Vì bài viết của chúng tôi chủ yếu dành cho người mới bắt đầu nên tôi sẽ nói về một số điểm hữu ích cho họ.

Rất nhiều công việc khi thiết lập môi trường được thực hiện thông qua dòng lệnh. Hầu hết người dùng sử dụng Windows làm hệ điều hành làm việc của họ. Bảng điều khiển tiêu chuẩn trong hệ điều hành này còn nhiều điều đáng mong đợi. Vì vậy, chúng ta sẽ sử dụng một công cụ tiện lợi Cmder/. Tải xuống phiên bản mini và chạy Cmder.exe. Tiếp theo bạn cần kết nối với máy chủ thông qua SSH:

ssh root@server-ip-or-hostname

Thay vì server-ip-hoặc-hostname, hãy chỉ định địa chỉ IP hoặc tên DNS của máy chủ của bạn. Tiếp theo, nhập mật khẩu và nếu kết nối thành công, chúng ta sẽ nhận được thông báo tương tự như thế này.

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

Ngôn ngữ chính để phát triển mô hình ML là Python. Và nền tảng phổ biến nhất để sử dụng nó trên Linux là Loại rắn lớn ở mỹ.

Hãy cài đặt nó trên máy chủ của chúng tôi.

Chúng tôi bắt đầu bằng cách cập nhật trình quản lý gói cục bộ:

sudo apt-get update

Cài đặt Curl (tiện ích dòng lệnh):

sudo apt-get install curl

Tải xuống phiên bản mới nhất của Anaconda Distribution:

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

Hãy bắt đầu cài đặt:

bash Anaconda3-2019.10-Linux-x86_64.sh

Trong quá trình cài đặt, bạn sẽ được yêu cầu xác nhận thỏa thuận cấp phép. Sau khi cài đặt thành công bạn sẽ thấy điều này:

Thank you for installing Anaconda3!

Hiện tại, nhiều khung đã được tạo để phát triển các mô hình ML; chúng tôi làm việc với những khung phổ biến nhất: Kim tự tháp и Dòng chảy.

Sử dụng khung cho phép bạn tăng tốc độ phát triển và sử dụng các công cụ làm sẵn cho các tác vụ tiêu chuẩn.

Trong ví dụ này, chúng tôi sẽ làm việc với PyTorch. Hãy cài đặt nó:

conda install pytorch torchvision cudatoolkit=10.1 -c pytorch

Bây giờ chúng tôi cần khởi chạy Jupyter Notebook, một công cụ phát triển phổ biến dành cho các chuyên gia ML. Nó cho phép bạn viết mã và xem ngay kết quả thực thi của nó. Jupyter Notebook được bao gồm trong Anaconda và đã được cài đặt trên máy chủ của chúng tôi. Bạn cần kết nối với nó từ hệ thống máy tính để bàn của chúng tôi.

Để thực hiện việc này, trước tiên chúng tôi sẽ khởi chạy Jupyter trên máy chủ chỉ định cổng 8080:

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

Tiếp theo, mở một tab khác trong bảng điều khiển Cmder (menu trên cùng - Hộp thoại bảng điều khiển mới), chúng tôi sẽ kết nối qua cổng 8080 với máy chủ qua SSH:

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

Khi chúng tôi nhập lệnh đầu tiên, chúng tôi sẽ được cung cấp các liên kết để mở Jupyter trong trình duyệt của chúng tôi:

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

Hãy sử dụng liên kết cho localhost:8080. Sao chép đường dẫn đầy đủ và dán nó vào thanh địa chỉ của trình duyệt cục bộ trên PC của bạn. Máy tính xách tay Jupyter sẽ mở ra.

Hãy tạo một sổ ghi chép mới: Mới - Notebook - Python 3.

Hãy kiểm tra hoạt động chính xác của tất cả các thành phần mà chúng tôi đã cài đặt. Hãy nhập mã PyTorch mẫu vào Jupyter và chạy thực thi (nút Run):

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

Kết quả sẽ giống như thế này:

Mạng thần kinh đầu tiên của bạn trên bộ xử lý đồ họa (GPU). Hướng dẫn cho người mới bắt đầu

Nếu bạn có kết quả tương tự thì chúng tôi đã định cấu hình mọi thứ chính xác và chúng tôi có thể bắt đầu phát triển mạng lưới thần kinh!

Tạo mạng lưới thần kinh

Chúng tôi sẽ tạo ra một mạng lưới thần kinh để nhận dạng hình ảnh. Hãy lấy điều này làm cơ sở khả năng lãnh đạo.

Chúng tôi sẽ sử dụng bộ dữ liệu CIFAR10 có sẵn công khai để đào tạo mạng. Nó có các lớp: “máy bay”, “ô tô”, “chim”, “mèo”, “hươu”, “chó”, “ếch”, “ngựa”, “tàu”, “xe tải”. Hình ảnh trong CIFAR10 có kích thước 3x32x32, tức là hình ảnh màu 3 kênh có kích thước 32x32 pixel.

Mạng thần kinh đầu tiên của bạn trên bộ xử lý đồ họa (GPU). Hướng dẫn cho người mới bắt đầu
Đối với công việc, chúng tôi sẽ sử dụng gói do PyTorch tạo để làm việc với hình ảnh - torchvision.

Chúng ta sẽ thực hiện theo thứ tự các bước sau:

  • Đang tải và chuẩn hóa các tập dữ liệu huấn luyện và kiểm tra
  • Định nghĩa mạng lưới thần kinh
  • Huấn luyện mạng trên dữ liệu huấn luyện
  • Kiểm tra mạng trên dữ liệu thử nghiệm
  • Hãy lặp lại đào tạo và kiểm tra bằng GPU

Chúng tôi sẽ thực thi tất cả mã bên dưới trong Jupyter Notebook.

Đang tải và chuẩn hóa CIFAR10

Sao chép và chạy đoạn mã sau trong 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')

Câu trả lời nên là:

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

Hãy hiển thị một số hình ảnh đào tạo để thử nghiệm:


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)))

Mạng thần kinh đầu tiên của bạn trên bộ xử lý đồ họa (GPU). Hướng dẫn cho người mới bắt đầu

Định nghĩa mạng lưới thần kinh

Trước tiên chúng ta hãy xem xét cách hoạt động của mạng lưới thần kinh để nhận dạng hình ảnh. Đây là một mạng điểm-điểm đơn giản. Nó lấy dữ liệu đầu vào, chuyển từng lớp một và cuối cùng tạo ra dữ liệu đầu ra.

Mạng thần kinh đầu tiên của bạn trên bộ xử lý đồ họa (GPU). Hướng dẫn cho người mới bắt đầu

Hãy tạo một mạng tương tự trong môi trường của chúng tôi:


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()

Chúng tôi cũng xác định hàm mất mát và trình tối ưu hóa


import torch.optim as optim

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

Huấn luyện mạng trên dữ liệu huấn luyện

Hãy bắt đầu đào tạo mạng lưới thần kinh của chúng ta. Xin lưu ý rằng sau khi chạy mã này, bạn sẽ phải đợi một thời gian cho đến khi công việc hoàn tất. Tôi phải mất 5 phút. Phải mất thời gian để đào tạo mạng.

 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')

Chúng tôi nhận được kết quả sau:

Mạng thần kinh đầu tiên của bạn trên bộ xử lý đồ họa (GPU). Hướng dẫn cho người mới bắt đầu

Chúng tôi lưu mô hình được đào tạo của chúng tôi:

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

Kiểm tra mạng trên dữ liệu thử nghiệm

Chúng tôi đã đào tạo mạng bằng cách sử dụng một bộ dữ liệu đào tạo. Nhưng chúng ta cần kiểm tra xem mạng có học được gì không.

Chúng tôi sẽ kiểm tra điều này bằng cách dự đoán nhãn lớp mà mạng thần kinh xuất ra và kiểm tra xem nó có đúng hay không. Nếu dự đoán đúng, chúng ta thêm mẫu vào danh sách dự đoán đúng.
Hãy hiển thị một hình ảnh từ bộ thử nghiệm:

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)))

Mạng thần kinh đầu tiên của bạn trên bộ xử lý đồ họa (GPU). Hướng dẫn cho người mới bắt đầu

Bây giờ hãy yêu cầu mạng lưới thần kinh cho chúng ta biết những bức ảnh này có gì:


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)))

Mạng thần kinh đầu tiên của bạn trên bộ xử lý đồ họa (GPU). Hướng dẫn cho người mới bắt đầu

Kết quả có vẻ khá tốt: mạng đã xác định chính xác ba trong số bốn bức ảnh.

Hãy xem mạng hoạt động như thế nào trên toàn bộ tập dữ liệu.


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))

Mạng thần kinh đầu tiên của bạn trên bộ xử lý đồ họa (GPU). Hướng dẫn cho người mới bắt đầu

Có vẻ như mạng biết điều gì đó và đang hoạt động. Nếu anh ta xác định các lớp một cách ngẫu nhiên, độ chính xác sẽ là 10%.

Bây giờ hãy xem mạng xác định lớp nào tốt hơn:

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]))

Mạng thần kinh đầu tiên của bạn trên bộ xử lý đồ họa (GPU). Hướng dẫn cho người mới bắt đầu

Có vẻ như mạng này xác định ô tô và tàu thủy tốt nhất: độ chính xác 71%.

Vậy là mạng đang hoạt động. Bây giờ chúng ta hãy thử chuyển công việc của nó sang bộ xử lý đồ họa (GPU) và xem có gì thay đổi.

Huấn luyện mạng lưới thần kinh trên GPU

Đầu tiên tôi sẽ giải thích ngắn gọn CUDA là gì. CUDA (Kiến trúc thiết bị hợp nhất tính toán) là một nền tảng điện toán song song được NVIDIA phát triển để tính toán chung trên các đơn vị xử lý đồ họa (GPU). Với CUDA, các nhà phát triển có thể tăng tốc đáng kể các ứng dụng điện toán bằng cách tận dụng sức mạnh của GPU. Nền tảng này đã được cài đặt trên máy chủ mà chúng tôi đã mua.

Trước tiên hãy xác định GPU của chúng tôi là thiết bị cuda hiển thị đầu tiên.

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 )

Mạng thần kinh đầu tiên của bạn trên bộ xử lý đồ họa (GPU). Hướng dẫn cho người mới bắt đầu

Gửi mạng tới GPU:

net.to(device)

Chúng tôi cũng sẽ phải gửi đầu vào và mục tiêu ở mỗi bước tới GPU:

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

Hãy đào tạo lại mạng trên 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')

Lần này, quá trình đào tạo mạng kéo dài khoảng 3 phút. Chúng ta hãy nhớ lại rằng giai đoạn tương tự trên bộ xử lý thông thường kéo dài 5 phút. Sự khác biệt không đáng kể, điều này xảy ra do mạng lưới của chúng tôi không quá lớn. Khi sử dụng mảng lớn để huấn luyện, sự khác biệt giữa tốc độ của GPU và bộ xử lý truyền thống sẽ tăng lên.

Đó dường như là tất cả. Những gì chúng tôi đã làm được:

  • Chúng tôi đã xem GPU là gì và chọn máy chủ để cài đặt nó;
  • Chúng tôi đã thiết lập môi trường phần mềm để tạo mạng lưới thần kinh;
  • Chúng tôi đã tạo ra một mạng lưới thần kinh để nhận dạng hình ảnh và đào tạo nó;
  • Chúng tôi lặp lại quá trình đào tạo mạng bằng GPU và nhận được tốc độ tăng lên.

Tôi sẽ sẵn lòng trả lời các câu hỏi trong phần bình luận.

Nguồn: www.habr.com

Thêm một lời nhận xét