Hướng dẫn PyTorch: Hồi quy, Ví dụ phân loại hình ảnh
Tóm tắt hướng dẫn Pytorch
Trong hướng dẫn về pytorch này, bạn sẽ học tất cả các khái niệm từ đầu. Hướng dẫn này bao gồm các chủ đề từ cơ bản đến nâng cao như định nghĩa pytorch, ưu điểm và nhược điểm của pytorch, so sánh, cài đặt, khung pytorch, hồi quy và phân loại hình ảnh. Hướng dẫn sử dụng pytorch này hoàn toàn miễn phí.
PyTorch là gì?
Kim tự tháp là thư viện Machine Learning dựa trên Torch mã nguồn mở để xử lý ngôn ngữ tự nhiên bằng cách sử dụng Python. Nó tương tự như NumPy nhưng có hỗ trợ GPU mạnh mẽ. Nó cung cấp Đồ thị tính toán động mà bạn có thể sửa đổi khi đang di chuyển với sự trợ giúp của autograd. PyTorch cũng nhanh hơn một số framework khác. Nó được phát triển bởi Nhóm nghiên cứu AI của Facebook vào năm 2016.
Ưu điểm và nhược điểm của PyTorch
Sau đây là ưu điểm và nhược điểm của PyTorch:
Ưu điểm của PyTorch
- Thư viện đơn giản
Mã PyTorch rất đơn giản. Thật dễ hiểu và bạn có thể sử dụng thư viện ngay lập tức. Ví dụ: hãy xem đoạn mã dưới đây:
class Net(torch.nn.Module): def __init__(self): super(Net, self).__init__() self.layer = torch.nn.Linear(1, 1) def forward(self, x): x = self.layer(x) return x
Như đã đề cập ở trên, bạn có thể xác định mô hình mạng một cách dễ dàng và có thể hiểu mã nhanh chóng mà không cần đào tạo nhiều.
- Đồ thị tính toán động
Nguồn hình ảnh: Khám phá Deep Learning với PyTorch
Pytorch cung cấp Đồ thị tính toán động (DAG). Đồ thị tính toán là một cách thể hiện các biểu thức toán học trong các mô hình hoặc lý thuyết đồ thị như nút và cạnh. Nút sẽ thực hiện phép toán và cạnh là một Tensor sẽ được đưa vào các nút và mang đầu ra của nút trong Tensor.
DAG là một biểu đồ có hình dạng tùy ý và có thể thực hiện các thao tác giữa các biểu đồ đầu vào khác nhau. Mỗi lần lặp lại, một biểu đồ mới được tạo ra. Vì vậy, có thể có cấu trúc biểu đồ giống nhau hoặc tạo một biểu đồ mới với một phép toán khác hoặc chúng ta có thể gọi nó là biểu đồ động.
- Hiệu suất tốt hơn
Cộng đồng và các nhà nghiên cứu, đánh giá và so sánh các khung để xem khung nào nhanh hơn. Kho lưu trữ GitHub Điểm chuẩn trên các khung và GPU học sâu đã báo cáo rằng PyTorch nhanh hơn khung khác về số hình ảnh được xử lý mỗi giây.
Như bạn có thể thấy bên dưới, biểu đồ so sánh với vgg16 và resnet152
- Native Python
PyTorch dựa trên python nhiều hơn. Ví dụ: nếu muốn huấn luyện một mô hình, bạn có thể sử dụng luồng điều khiển gốc như vòng lặp và đệ quy mà không cần thêm các biến hoặc phiên đặc biệt hơn để có thể chạy chúng. Điều này rất hữu ích cho quá trình đào tạo.
Pytorch cũng triển khai Lập trình mệnh lệnh và chắc chắn nó linh hoạt hơn. Vì vậy, có thể in ra giá trị tensor ở giữa quá trình tính toán.
Nhược điểm của PyTorch
PyTorch yêu cầu ứng dụng của bên thứ ba để Trực quan hóa. Nó cũng cần một máy chủ API để sản xuất.
Tiếp theo trong hướng dẫn PyTorch này, chúng ta sẽ tìm hiểu về sự khác biệt giữa PyTorch và TensorFlow.
PyTorch Vs. Dòng chảy căng
Tham số | Kim tự tháp | Dòng chảy |
---|---|---|
Định nghĩa mô hình | Mô hình được định nghĩa trong một lớp con và cung cấp gói dễ sử dụng | Mô hình được định nghĩa với nhiều mô hình và bạn cần hiểu cú pháp |
Hỗ trợ GPU | Có | Có |
Loại đồ thị | Năng động | tĩnh |
CÔNG CỤ | Không có công cụ trực quan | Bạn có thể sử dụng công cụ trực quan Tensorboard |
Cộng đồng | Cộng đồng vẫn đang phát triển | Cộng đồng tích cực lớn |
Cài đặt PyTorch
Linux
Thật đơn giản để cài đặt nó trong Linux. Bạn có thể chọn sử dụng môi trường ảo hoặc cài đặt trực tiếp với quyền truy cập root. Nhập lệnh này trong terminal
pip3 install --upgrade torch torchvision
Nhà sản xuất hiền nhân AWS
Sagemaker là một trong những nền tảng trong Amazon Dịch vụ web cung cấp công cụ Machine Learning mạnh mẽ với các cấu hình deep learning được cài đặt sẵn để nhà khoa học hoặc nhà phát triển dữ liệu xây dựng, đào tạo và triển khai các mô hình ở mọi quy mô.
Đầu tiên mở Amazon người làm hiền triết bảng điều khiển và nhấp vào Tạo phiên bản sổ ghi chép và điền đầy đủ thông tin cho sổ ghi chép của bạn.
Bước tiếp theo, nhấp vào Mở để khởi chạy phiên bản sổ ghi chép của bạn.
Cuối cùng, trong Jupyter, Nhấp vào Mới và chọn conda_pytorch_p36 và bạn đã sẵn sàng sử dụng phiên bản sổ ghi chép của mình đã cài đặt Pytorch.
Tiếp theo trong hướng dẫn PyTorch này, chúng ta sẽ tìm hiểu về những điều cơ bản về khung PyTorch.
Khái niệm cơ bản về khung PyTorch
Hãy tìm hiểu các khái niệm cơ bản về PyTorch trước khi đi sâu vào. PyTorch sử dụng Tensor cho mọi biến tương tự như ndarray của numpy nhưng có hỗ trợ tính toán GPU. Ở đây chúng tôi sẽ giải thích mô hình mạng, chức năng mất, Backprop và Trình tối ưu hóa.
Mô hình mạng
Mạng có thể được xây dựng bằng cách phân lớp torch.nn. Có 2 phần chính,
- Phần đầu tiên là xác định các tham số và lớp mà bạn sẽ sử dụng
- Phần thứ hai là nhiệm vụ chính được gọi là quá trình chuyển tiếp sẽ lấy đầu vào và dự đoán đầu ra.
Import torch import torch.nn as nn import torch.nn.functional as F class Model(nn.Module): def __init__(self): super(Model, self).__init__() self.conv1 = nn.Conv2d(3, 20, 5) self.conv2 = nn.Conv2d(20, 40, 5) self.fc1 = nn.Linear(320, 10) def forward(self, x): x = F.relu(self.conv1(x)) x = F.relu(self.conv2(x)) x = x.view(-1, 320) x = F.relu(self.fc1(x)) return F.log_softmax(x) net = Model()
Như bạn có thể thấy ở trên, bạn tạo một lớp nn.Module có tên là Model. Nó chứa 2 lớp Conv2d và một lớp Tuyến tính. Lớp đối lưu đầu tiên có đầu vào là 2 và hình dạng đầu ra là 3. Lớp thứ hai sẽ có đầu vào là 20 và sẽ tạo ra hình dạng đầu ra là 20. Lớp cuối cùng là lớp được kết nối đầy đủ có hình dạng 40 và sẽ tạo ra đầu ra là 320.
Quá trình chuyển tiếp sẽ lấy đầu vào của X và đưa nó vào lớp đối lưu1 và thực hiện chức năng ReLU,
Tương tự, nó cũng sẽ cung cấp lớp conv2. Sau đó, x sẽ được định hình lại thành (-1, 320) và đưa vào lớp FC cuối cùng. Trước khi gửi đầu ra, bạn sẽ sử dụng chức năng kích hoạt softmax.
Quá trình lùi được xác định tự động bởi autograd, do đó bạn chỉ cần xác định quy trình chuyển tiếp.
Mất chức năng
Hàm mất mát được sử dụng để đo lường mức độ mô hình dự đoán có thể dự đoán kết quả mong đợi. PyTorch đã có nhiều hàm mất tiêu chuẩn trong mô-đun torch.nn. Ví dụ: bạn có thể sử dụng Cross-Entropy Loss để giải quyết vấn đề phân loại PyTorch nhiều lớp. Thật dễ dàng để xác định hàm mất mát và tính toán tổn thất:
loss_fn = nn.CrossEntropyLoss() #training process loss = loss_fn(out, target)
Thật dễ dàng để sử dụng phép tính hàm tổn thất của riêng bạn với PyTorch.
Chống đỡ sau
Để thực hiện lan truyền ngược, bạn chỉ cần gọi los.backward(). Lỗi sẽ được tính toán nhưng hãy nhớ xóa gradient hiện có bằng zero_grad()
net.zero_grad() # to clear the existing gradient loss.backward() # to perform backpropragation
Trình tối ưu hóa
Torch.optim cung cấp các thuật toán tối ưu hóa phổ biến. Bạn có thể xác định trình tối ưu hóa bằng một bước đơn giản:
optimizer = torch.optim.SGD(net.parameters(), lr = 0.01, momentum=0.9)
Bạn cần truyền các tham số mô hình mạng và tốc độ học để ở mỗi lần lặp, các tham số sẽ được cập nhật sau quá trình backprop.
Hồi quy đơn giản với PyTorch
Hãy cùng tìm hiểu hồi quy đơn giản với các ví dụ PyTorch:
Bước 1) Tạo mô hình mạng của chúng tôi
Mô hình mạng của chúng tôi là một lớp Tuyến tính đơn giản với hình dạng đầu vào và đầu ra là 1.
from __future__ import print_function import torch import torch.nn as nn import torch.nn.functional as F from torch.autograd import Variable class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.layer = torch.nn.Linear(1, 1) def forward(self, x): x = self.layer(x) return x net = Net() print(net)
Và đầu ra mạng sẽ như thế này
Net( (hidden): Linear(in_features=1, out_features=1, bias=True) )
Bước 2) Dữ liệu kiểm tra
Trước khi bắt đầu quá trình đào tạo, bạn cần biết dữ liệu của chúng tôi. Bạn thực hiện một hàm ngẫu nhiên để kiểm tra mô hình của chúng tôi. Y = x3 sin(x)+ 3x+0.8 rand(100)
# Visualize our data import matplotlib.pyplot as plt import numpy as np x = np.random.rand(100) y = np.sin(x) * np.power(x,3) + 3*x + np.random.rand(100)*0.8 plt.scatter(x, y) plt.show()
Đây là biểu đồ phân tán của chức năng của chúng tôi:
Trước khi bắt đầu quá trình đào tạo, bạn cần chuyển đổi mảng có nhiều mảng thành Biến được hỗ trợ bởi Torch và autograd như trong ví dụ hồi quy PyTorch bên dưới.
# convert numpy array to tensor in shape of input size x = torch.from_numpy(x.reshape(-1,1)).float() y = torch.from_numpy(y.reshape(-1,1)).float() print(x, y)
Bước 3) Tối ưu hóa và mất mát
Tiếp theo, bạn nên xác định Trình tối ưu hóa và Hàm mất cho quá trình đào tạo của chúng tôi.
# Define Optimizer and Loss Function optimizer = torch.optim.SGD(net.parameters(), lr=0.2) loss_func = torch.nn.MSELoss()
Bước 4) Đào tạo
Bây giờ hãy bắt đầu quá trình đào tạo của chúng tôi. Với kỷ nguyên 250, bạn sẽ lặp lại dữ liệu của chúng tôi để tìm giá trị tốt nhất cho siêu tham số của chúng tôi.
inputs = Variable(x) outputs = Variable(y) for i in range(250): prediction = net(inputs) loss = loss_func(prediction, outputs) optimizer.zero_grad() loss.backward() optimizer.step() if i % 10 == 0: # plot and show learning process plt.cla() plt.scatter(x.data.numpy(), y.data.numpy()) plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=2) plt.text(0.5, 0, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 10, 'color': 'red'}) plt.pause(0.1) plt.show()
Bước 5) Kết quả
Như bạn có thể thấy bên dưới, bạn đã thực hiện thành công hồi quy PyTorch với mạng nơ-ron. Trên thực tế, trên mỗi lần lặp, đường màu đỏ trong biểu đồ sẽ cập nhật và thay đổi vị trí của nó để phù hợp với dữ liệu. Nhưng trong hình ảnh này, nó chỉ hiển thị cho bạn kết quả cuối cùng như trong ví dụ PyTorch bên dưới:
Ví dụ phân loại hình ảnh với PyTorch
Một trong những phương pháp phổ biến để học những kiến thức cơ bản về học kĩ càng là với bộ dữ liệu MNIST. Đó là “Hello World” trong học sâu. Bộ dữ liệu chứa các số viết tay từ 0 – 9 với tổng số 60,000 mẫu huấn luyện và 10,000 mẫu thử nghiệm đã được dán nhãn kích thước 28×28 pixel.
Bước 1) Xử lý trước dữ liệu
Trong bước đầu tiên của ví dụ phân loại PyTorch này, bạn sẽ tải tập dữ liệu bằng mô-đun torchvision.
Trước khi bắt đầu quá trình đào tạo, bạn cần hiểu dữ liệu. Torchvision sẽ tải tập dữ liệu và chuyển đổi hình ảnh với yêu cầu phù hợp với mạng như hình dạng và chuẩn hóa hình ảnh.
import torch import torchvision import numpy as np from torchvision import datasets, models, transforms # This is used to transform the images to Tensor and normalize it transform = transforms.Compose( [transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]) training = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform) train_loader = torch.utils.data.DataLoader(training, batch_size=4, shuffle=True, num_workers=2) testing = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform) test_loader = torch.utils.data.DataLoader(testing, batch_size=4, shuffle=False, num_workers=2) classes = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') import matplotlib.pyplot as plt import numpy as np #create an iterator for train_loader # get random training images data_iterator = iter(train_loader) images, labels = data_iterator.next() #plot 4 images to visualize the data rows = 2 columns = 2 fig=plt.figure() for i in range(4): fig.add_subplot(rows, columns, i+1) plt.title(classes[labels[i]]) img = images[i] / 2 + 0.5 # this is for unnormalize the image img = torchvision.transforms.ToPILImage()(img) plt.imshow(img) plt.show()
Hàm biến đổi chuyển đổi hình ảnh thành tensor và chuẩn hóa giá trị. Hàm torchvision.transforms.MNIST, sẽ tải xuống tập dữ liệu (nếu không có) trong thư mục, đặt tập dữ liệu để đào tạo nếu cần và thực hiện quá trình chuyển đổi.
Để trực quan hóa tập dữ liệu, bạn sử dụng data_iterator để lấy lô hình ảnh và nhãn tiếp theo. Bạn sử dụng matplot để vẽ những hình ảnh này và nhãn thích hợp của chúng. Như bạn có thể thấy bên dưới hình ảnh của chúng tôi và nhãn của chúng.
Bước 2) Cấu hình mô hình mạng
Bây giờ trong ví dụ PyTorch này, bạn sẽ tạo một mạng nơ-ron đơn giản để phân loại hình ảnh PyTorch.
Ở đây, chúng tôi giới thiệu cho bạn một cách khác để tạo mô hình Mạng trong PyTorch. Chúng ta sẽ sử dụng nn.Sequential để tạo mô hình trình tự thay vì tạo một lớp con của nn.Module.
import torch.nn as nn # flatten the tensor into class Flatten(nn.Module): def forward(self, input): return input.view(input.size(0), -1) #sequential based model seq_model = nn.Sequential( nn.Conv2d(1, 10, kernel_size=5), nn.MaxPool2d(2), nn.ReLU(), nn.Dropout2d(), nn.Conv2d(10, 20, kernel_size=5), nn.MaxPool2d(2), nn.ReLU(), Flatten(), nn.Linear(320, 50), nn.ReLU(), nn.Linear(50, 10), nn.Softmax(), ) net = seq_model print(net)
Đây là đầu ra của mô hình mạng của chúng tôi
Sequential( (0): Conv2d(1, 10, kernel_size=(5, 5), stride=(1, 1)) (1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (2): ReLU() (3): Dropout2d(p=0.5) (4): Conv2d(10, 20, kernel_size=(5, 5), stride=(1, 1)) (5): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (6): ReLU() (7): Flatten() (8): Linear(in_features=320, out_features=50, bias=True) (9): ReLU() (10): Linear(in_features=50, out_features=10, bias=True) (11): Softmax() )
Giải thích mạng
- Trình tự là lớp đầu tiên là lớp Conv2D có hình dạng đầu vào là 1 và hình dạng đầu ra là 10 với kích thước hạt nhân là 5
- Tiếp theo, bạn có lớp MaxPool2D
- Chức năng kích hoạt ReLU
- một lớp Dropout để loại bỏ các giá trị xác suất thấp.
- Sau đó, Conv2d thứ hai với hình dạng đầu vào là 10 từ lớp cuối cùng và hình dạng đầu ra là 20 với kích thước hạt nhân là 5
- Tiếp theo là lớp MaxPool2d
- Chức năng kích hoạt ReLU.
- Sau đó, bạn sẽ làm phẳng tensor trước khi đưa nó vào lớp Linear
- Lớp tuyến tính sẽ ánh xạ đầu ra của chúng tôi ở lớp Tuyến tính thứ hai với chức năng kích hoạt softmax
Bước 3) Huấn luyện mô hình
Trước khi bắt đầu quá trình đào tạo, cần phải thiết lập chức năng tiêu chí và tối ưu hóa.
Đối với tiêu chí, bạn sẽ sử dụng CrossEntropyLoss. Đối với Trình tối ưu hóa, bạn sẽ sử dụng SGD với tốc độ học tập là 0.001 và động lượng là 0.9 như trong ví dụ PyTorch bên dưới.
import torch.optim as optim criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
Quá trình chuyển tiếp sẽ lấy hình dạng đầu vào và chuyển nó sang lớp đối lưu đầu tiên. Sau đó, nó sẽ được đưa vào maxpool2d và cuối cùng được đưa vào hàm kích hoạt ReLU. Quá trình tương tự sẽ xảy ra ở lớp đối lưu thứ hai. Sau đó, đầu vào sẽ được định hình lại thành (-2) và đưa vào lớp fc để dự đoán đầu ra.
Bây giờ, bạn sẽ bắt đầu quá trình đào tạo. Bạn sẽ lặp lại tập dữ liệu của chúng tôi 2 lần hoặc với kỷ nguyên là 2 và in ra mức lỗ hiện tại ở mỗi đợt 2000.
for epoch in range(2): #set the running loss at each epoch to zero running_loss = 0.0 # we will enumerate the train loader with starting index of 0 # for each iteration (i) and the data (tuple of input and labels) for i, data in enumerate(train_loader, 0): inputs, labels = data # clear the gradient optimizer.zero_grad() #feed the input and acquire the output from network outputs = net(inputs) #calculating the predicted and the expected loss loss = criterion(outputs, labels) #compute the gradient loss.backward() #update the parameters optimizer.step() # print statistics running_loss += loss.item() if i % 1000 == 0: print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 1000)) running_loss = 0.0
Ở mỗi kỷ nguyên, điều tra viên sẽ nhận được bộ dữ liệu đầu vào tiếp theo và các nhãn tương ứng. Trước khi cung cấp đầu vào cho mô hình mạng của mình, chúng tôi cần xóa gradient trước đó. Điều này là cần thiết vì sau quá trình truyền ngược (quá trình lan truyền ngược), gradient sẽ được tích lũy thay vì bị thay thế. Sau đó, chúng ta sẽ tính toán tổn thất từ sản lượng dự đoán từ sản lượng dự kiến. Sau đó, chúng tôi sẽ thực hiện lan truyền ngược để tính toán độ dốc và cuối cùng, chúng tôi sẽ cập nhật các tham số.
Đây là kết quả của quá trình đào tạo
[1, 1] loss: 0.002 [1, 1001] loss: 2.302 [1, 2001] loss: 2.295 [1, 3001] loss: 2.204 [1, 4001] loss: 1.930 [1, 5001] loss: 1.791 [1, 6001] loss: 1.756 [1, 7001] loss: 1.744 [1, 8001] loss: 1.696 [1, 9001] loss: 1.650 [1, 10001] loss: 1.640 [1, 11001] loss: 1.631 [1, 12001] loss: 1.631 [1, 13001] loss: 1.624 [1, 14001] loss: 1.616 [2, 1] loss: 0.001 [2, 1001] loss: 1.604 [2, 2001] loss: 1.607 [2, 3001] loss: 1.602 [2, 4001] loss: 1.596 [2, 5001] loss: 1.608 [2, 6001] loss: 1.589 [2, 7001] loss: 1.610 [2, 8001] loss: 1.596 [2, 9001] loss: 1.598 [2, 10001] loss: 1.603 [2, 11001] loss: 1.596 [2, 12001] loss: 1.587 [2, 13001] loss: 1.596 [2, 14001] loss: 1.603
Bước 4) Kiểm tra mô hình
Sau khi đào tạo mô hình của chúng tôi, bạn cần kiểm tra hoặc đánh giá bằng các bộ hình ảnh khác.
Chúng tôi sẽ sử dụng một trình vòng lặp cho test_loader và nó sẽ tạo ra một loạt hình ảnh và nhãn sẽ được chuyển đến mô hình được đào tạo. Đầu ra dự đoán sẽ được hiển thị và so sánh với đầu ra dự kiến.
#make an iterator from test_loader #Get a batch of training images test_iterator = iter(test_loader) images, labels = test_iterator.next() results = net(images) _, predicted = torch.max(results, 1) print('Predicted: ', ' '.join('%5s' % classes[predicted[j]] for j in range(4))) fig2 = plt.figure() for i in range(4): fig2.add_subplot(rows, columns, i+1) plt.title('truth ' + classes[labels[i]] + ': predict ' + classes[predicted[i]]) img = images[i] / 2 + 0.5 # this is to unnormalize the image img = torchvision.transforms.ToPILImage()(img) plt.imshow(img) plt.show()
Tổng kết
- PyTorch là một ứng dụng dựa trên Torch mã nguồn mở Machine Learning thư viện cho xử lý ngôn ngữ tự nhiên sử dụng Python.
- Ưu điểm của PyTorch: 1) Thư viện đơn giản, 2) Đồ thị tính toán động, 3) Hiệu suất tốt hơn, 4) Bản địa Python
- PyTorch sử dụng Tensor cho mọi biến tương tự như ndarray của numpy nhưng có hỗ trợ tính toán GPU.
- Một trong những phương pháp phổ biến để tìm hiểu kiến thức cơ bản về học sâu là sử dụng bộ dữ liệu MNIST.