PyTorch

**PyTorch**是一个开源的Python机器学习库，基于库，底层由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
```


## 参考文献

## 参见
* 
* 人工神经网络
* 深度学习
* 机器学习
* 损失函数
* 激活函数

## 外部链接
* 
* 从 GitHub 访问 PyTorch 教程 
* PyTorch基金会的Youtube账号