PyTorch

**PyTorch** là một framework học máy dựa trên thư viện Torch, được sử dụng trong lĩnh vực thị giác máy tính và xử lý ngôn ngữ tự nhiên, do Meta AI phát triển và ngày nay là một phần của Linux Foundation. Đây là phần mềm tự do nguồn mở phát hành dựa trên giấy phép BSD đã qua sửa đổi. Mặc dù được phát triển chính yếu ở dạng giao diện ngôn ngữ Python, PyTorch cũng hỗ trợ giao diện C++.

Nhiều phần mềm học sâu được xây dựng theo PyTorch, bao gồm Tesla Autopilot, Pyro của Uber, Hugging Face's Transformers, PyTorch Lightning, và Catalyst.

PyTorch cung cấp 2 tính năng cao cấp:
* Điện toán Tensor (như NumPy) với khả năng tăng tốc mạnh mẽ thông qua các bộ xử lý đồ họa (GPU)
* Các mạng neuron sâu được xây dựng dựa trên hệ thống vi phân tự động

## Lịch sử
Meta (trước đó là Facebook) vận hành cả *PyTorch* và *Convolutional Architecture for Fast Feature Embedding* (Caffe2), nhưng các mô hình được xác định do 2 framework không tương thích với nhau. Dự án The Open Neural Network Exchange (ONNX) do Meta và Microsoft sáng lập tháng 9 năm 2017 cho việc chuyển đổi giữa các framework. Caffe2 sáp nhập vào PyTorch vào cuối tháng 3 năm 2018. Vào tháng 9 năm 2022, Meta thông báo *PyTorch* sẽ được quản lý bởi PyTorch Foundation - một tổ chức độc lập mới được thành lập nhưng vẫn là công ty con của Linux Foundation.

## PyTorch tensor
PyTorch định nghĩa một lớp (class) gọi là Tensor (`torch.Tensor`) để lưu trữ và hoạt động trên các mảng số hình chữ nhật đa chiều đồng nhất. PyTorch Tensor giống với mảng NumPy, nhưng có thể vận hành được trên GPU NVIDIA có hỗ trợ CUDA. PyTorch cũng phát triển phương thức hỗ trợ cho các nền tảng GPU khác, ví dụ, ROCm của AMD và Metal Framework của Apple.

PyTorch hỗ trợ nhiều loại tensor phụ khác nhau.

Lưu ý thuật ngữ "tensor" không mang ý nghĩa về tensor trong lĩnh vực toán hay lý.

## Module
### Module Autograd
PyTorch sử dụng một phương pháp gọi là vi phân tự động. Một thiết bị ghi hình lại một quá trình diễn ra sau đó nó phát ngược lại để tính toán gradient. Phương pháp này phát huy rất hiệu quả khi dựng các mạng neuron để tiết kiệm thời gian cho một epoch bằng cách vi phân các tham số tại bước chuyển tiếp.

### Module <code>Optim</code>
`torch.optim` là một module thực hiện các thuật toán tối ưu hóa khác nhau sử dụng các mạng neuron để xây dựng. Hầu hết các phương pháp phổ biến này đã được hỗ trợ, vì thế không cần xây dựng lại chúng từ đầu.

### Module <code>nn</code>
Tính năng autograd của PyTorch giúp dễ dàng xác định được các biểu đồ tính toán và tính gradient, nhưng autograd thô có thể ở level quá thấp để xác định các mạng neuron phức tạp. Đây là lúc module `nn` phát huy công dụng. Module `nn` cung cấp các lớp và công cụ để dễ dàng tạo nên các mạng neuron chỉ bằng cách xác định các lớp trong mạng.

PyTorch cũng có các module con hữu ích khác như tiện ích tải dữ liệu và chức năng đào tạo phân tán.

## Ví dụ
Chương trình sau đây cho thấy chức năng level thấp của thư viện bằng một ví dụ đơn giản.


```python
import torch
dtype = torch.float
device = torch.device("cpu") # Thực hiện tất cả việc tính toán trên CPU
# device = torch.device("cuda:0") # Thực hiện tất cả việc tính toán trên GPU

# Tạo một tensor và điền vào tensor đó các số ngẫu nhiên
a = torch.randn(2, 3, device=device, dtype=dtype)
print(a) # Kết quả tensor A
# Output: tensor([[-1.1884,  0.8498, -1.7129],
#                  [-0.8816,  0.1944,  0.5847]])

# Tạo một tensor và điền vào tensor đó các số ngẫu nhiên
b = torch.randn(2, 3, device=device, dtype=dtype)
print(b) # Kết quả tensor B
# Output: tensor([[ 0.7178, -0.8453, -1.3403],
#                  [ 1.3262,  1.1512, -1.7070]])

print(a*b) # Kết quả phép nhân 2 tensor
# Output: tensor([[-0.8530, -0.7183,  2.58],
#                  [-1.1692,  0.2238, -0.9981]])

print(a.sum()) # Kết quả phép cộng tất cả các giá trị của tensor A
# Output: tensor(-2.1540)

print(a[1,2]) # Xuất giá trị ở dòng 2 cột 3
# Output: tensor(0.5847)

print(a.max()) # Xuất giá trị lớn nhất của tensor A
# Output: tensor(-1.7129)
```
Code block sau cho thấy một ví dụ về module `nn` ở level cao hơn. Một mạng neuron với các lớp tuyến tính được định nghĩa trong ví dụ. 
```python3
import torch
from torch import nn # Nhập module nn từ PyTorch

class NeuralNetwork(nn.Module): # Các mạng neuron được định nghĩa là các class
    def __init__(self): # Các lớp và biến được định nghĩa ở phương thức __init__
        super(NeuralNetwork, self).__init__() # Phải có cho mọi mạng.
        self.flatten = nn.Flatten() # Định nghĩa lớp flatten.
        self.linear_relu_stack = nn.Sequential( # Định nghĩa một stack của lớp.
            nn.Linear(28*28, 512), # Lớp tuyến tính dạng đầu vào và đầu ra
            nn.ReLU(), # ReLU là một trong các hàm kích hoạt được cung cấp bởi module nn
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10), 
        )

    def forward(self, x): # Hàm forward.
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits
```


## Xem thêm

* So sánh các phần mềm học sâu
* Lập trình khả vi
* DeepSpeed
* Torch (học máy)

## Tham khảo

## Liên kết ngoài
*