PyTorch

PyTorch是一個開源的Python機器學習庫，基於Torch (機器學習)庫，底層由C++實現，應用於人工智慧領域，如電腦視覺和自然語言處理。它最初由Meta Platforms的人工智慧研究團隊開發，現在屬於Linux基金會的一部分。它是在修改後的BSD許可證下發布的自由及開放原始碼軟體。儘管Python接口更加完善並且是開發的主要重點，但 PyTorch 也有C++接口。

許多深度學習軟體都是基於 PyTorch 構建的，包括特斯拉自動駕駛、Uber的Pyro、Hugging Face的Transformers、 PyTorch Lightning、和Catalyst。

## 概述

PyTorch主要有兩大特徵：

- 類似於NumPy的張量計算，能在 GPU 或 MPS 等硬體加速器上加速。
- 基於帶自動微分系統的深度神經網路。

PyTorch包括torch.autograd、torch.nn、torch.optim等子模塊。

PyTorch包含多種損失函數，包括 MSE（均方誤差 = L2 範數）、交叉熵損失和負熵似然損失（對分類器有用）等。

## PyTorch張量

PyTorch定義了一個名為張量(torch.Tensor) 的類別來儲存和操作同構多維矩形數字陣列。PyTorch張量與NumPy陣列類似，但也可以在支援 CUDA 的 英偉達 GPU 上運作。PyTorch 也一直在開發對其他 GPU 平台的支持，例如 AMD 的 ROCm 和 Apple 的Metal Framework。

張量是 PyTorch 中的核心數據抽象，PyTorch 支援各種張量子類型。通常地，一維張量稱為向量（vector），二維張量稱為矩陣（matrix）。

張量的數據類型包括：

- `torch.bool`
- `torch.int8`
- `torch.uint8`
- `torch.int16`
- `torch.int32`
- `torch.int64`
- `torch.half`
- `torch.float`
- `torch.double`
- `torch.bfloat`

## PyTorch神經網路

神經網路由對數據執行操作的層/模塊組成。torch.nn 命名空間提供了使用者需要的所有構建塊來構建自己的神經網路。PyTorch 中的每個模塊都對應nn.模塊。神經網路本身是由其他模塊（層）組成的模塊。這種嵌套結構允許使用者輕鬆構建並管理複雜的架構。神經網路中的許多層都是參數化的，即具有相關的權重以及在訓練期間優化的偏差。自動子類化跟蹤模型對象中定義的所有欄位，並生成所有參數可使用模型或方法訪問。

```pycon
import torch                     # for all things PyTorch
import torch.nn as nn            # for torch.nn.Module, the parent object for PyTorch models
import torch.nn.functional as F  # for the activation function
```

激活函數`torch.nn.Module`具有封裝所有主要內容的對象激活功能，包括 ReLU 及其許多變體、Tanh、 Hardtanh、sigmoid 等。

## PyTorch模型常見圖層類型

### 線性層

最基本的神經網路層類型是線性或完全連接層。在這個層中，每個輸入都會影響每個圖層的輸出到由圖層權重指定的程度。如果 模型有 m 個輸入和 n 個輸出，權重將是一個 m x n 矩陣。

### 卷積層

卷積層旨在處理高度空間相關性。它們在電腦視覺中非常常用，它們檢測組成的特徵的緊密分組更高級別的功能。它們也會在其他上下文中彈出。例如，在 NLP 應用程式中，單詞的直接上下文（即序列中附近的其他單詞）可以影響語句。

### 循環層

遞歸神經網路（RNN）是用於順序數據（從科學儀器到時間序列測量）的自然語言句子。

## 例子

下面的程序用簡單的例子展示這個程序庫的低層功能。

```pycon
>>> import torch
>>> dtype = torch.float
>>> device = torch.device("cpu") # 本次在CPU上执行所有的计算
>>> # device = torch.device("cuda:0") # 本次在GPU上执行所有的计算
>>> 
>>> # 建立一个张量并用随机数填充这个张量
>>> a = torch.randn(2, 3, device=device, dtype=dtype)
>>> print(a) # 输出张量a
tensor([[-0.1460, -0.3490,  0.3705],
        [-1.1141,  0.7661,  1.0823]])
>>> 
>>> # 建立一个张量并用随机数填充这个张量
>>> b = torch.randn(2, 3, device=device, dtype=dtype)
>>> print(b) # 输出张量B
tensor([[ 0.6901, -0.9663,  0.3634],
        [-0.6538, -0.3728, -1.1323]])
>>> 
>>> print(a*b) # 输出两个张量的乘积
tensor([[-0.1007,  0.3372,  0.1346],
        [ 0.7284, -0.2856, -1.2256]])
>>> print(a.sum()) # 输出在张量a中所有元素的总和
tensor(0.6097)
>>> 
>>> print(a[1,2]) # 输出第2行第3列（0起始）的元素
tensor(1.0823)
>>> 
>>> print(a.max()) # 输出在张量a中的极大值
tensor(1.0823)
```

下列代碼塊展示了`nn`模塊提供的高層功能的例子。例子中定義了具有線性層的神經網路。

```python
import torch
from torch import nn # 从PyTorch中导入nn子模块 

class NeuralNetwork(nn.Module): # 神经网络被定义为类
    def __init__(self): # 在__init__方法中定义诸层和变量
        super(NeuralNetwork, self).__init__() # 必须出现在所有网络中
        self.flatten = nn.Flatten() # 定义一个压平层
        self.linear_relu_stack = nn.Sequential( # 定义诸层的一个堆栈
            nn.Linear(28*28, 512), # 线性层有一个输入和输出形状
            nn.ReLU(), # ReLU是nn提供的诸多激活函数之一
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10), 
        )

    def forward(self, x): # 这个函数定义前向传递。
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits
```

## 外部連結

- pytorch.org
- 從 GitHub 訪問 PyTorch 教程
- PyTorch基金會的Youtube帳號

## 基本資料

- 作者：Adam Paszke, Sam Gross, Soumith Chintala, Gregory Chanan
- 開發者：Meta AI
- 發行日期：2016年
- 程式語言：Python, C++, CUDA
- 作業系統：Linux, macOS, Windows
- 平台：IA-32, x86-64, ARM64
- 類型：機器學習和深度學習庫
- 許可協議：BSD許可證