Skip to content

Commit

Permalink
update pytorch index
Browse files Browse the repository at this point in the history
  • Loading branch information
AIboy996 committed Mar 16, 2024
1 parent 00cafa3 commit 1a402a8
Show file tree
Hide file tree
Showing 12 changed files with 313 additions and 13 deletions.
9 changes: 5 additions & 4 deletions docs/About/links.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ hide:

## 友链

- [杨希杰的主页](https://yang-xijie.github.io/)
- [谢益辉的主页](https://yihui.org/)
- [刘原冶](https://henrylau7.github.io/)
- [杨希杰](https://yang-xijie.github.io/)
- [谢益辉](https://yihui.org/)
- [老陳网志](https://blog.chenyyds.com/)
- [朱英华的主页](https://williamzhu01.github.io/william-circle.github.io/)
- [张舟的主页](https://zhangzhou.site/)
- [朱英华](https://williamzhu01.github.io/william-circle.github.io/)
- [张舟](https://zhangzhou.site/)

## 或许有用

Expand Down
2 changes: 1 addition & 1 deletion docs/Note/GFW/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ tags:
- GFW和VPN
---

# 梯子客户端评测
# 常见的客户端

??? caution "免责声明"
总之就是免责
Expand Down
2 changes: 1 addition & 1 deletion docs/Note/GFW/intro.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: 关于墙和梯子的基础知识
title: 介绍
tags:
- GFW和VPN
---
Expand Down
2 changes: 1 addition & 1 deletion docs/Note/GFW/server.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ tags:
- GFW和VPN
---

# 搭建一个VPN服务器
# 常见的代理协议

TBD:搭建一个VPN服务器
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions docs/Python/ThirdPartyLibrary/pytorch/data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
tags:
- pytorch
---

# 数据加载

TBD:pytorch data
279 changes: 276 additions & 3 deletions docs/Python/ThirdPartyLibrary/pytorch/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,284 @@ tags:
- pytorch
hide:
- tags
- toc
include:
- math
---

# pytorch

梯度下降的艺术。
[PyTorch](https://pytorch.org/)是一个开源的Python机器学习库,基于[torch](http://torch.ch/)实现。它们二者的关系大家可以看看[浅谈Pytorch与Torch的关系
](https://oldpan.me/archives/pytorch-torch-relation)

TBD:pytorch介绍
## 自动梯度计算
> [torch.autograd](https://pytorch.org/docs/stable/autograd.html)
既然是搞机器学习,那就逃不开**梯度下降**这一最通用的优化方法。所以pytorch比较核心的设计就是梯度的计算。

### 模型
举例来说,我们考虑用下面的线性预测模型来拟合$y\in \mathbb{R}^3$:

$$
z = wx+b
$$

其中$x\in \mathbb{R}^5$是自变量,$w\in \mathbb{R}^{3\times 5}$和$b\in \mathbb{R}^3$是模型的参数,我们定义
$$
\mathrm{loss} = \frac{1}{3}\lVert y-z\rVert_2^2
$$
我们想要做梯度下降来最小化`loss`,那么就需要计算:
$$
\frac{\partial\mathrm{loss}}{\partial w}, \frac{\partial\mathrm{loss}}{\partial b}
$$
### 手算
这里的模型比较简单,我们可以很容易(<s>好吧也没那么容易,翻书翻了半天,矩阵的微分是真的容易忘掉</s>)计算得到:
$$
\frac{\partial\mathrm{loss}}{\partial w} = \frac{-2(y-b-wx)x^T}{3}
$$
$$
\frac{\partial\mathrm{loss}}{\partial b} = \frac{-2(y-b-wx)}{3}
$$

??? question "咋算的"
利用链式法则:
$$
\frac{\partial\mathrm{loss}}{\partial w} = \frac{ \partial \frac{1}{3}\lVert y-z\rVert_2^2}{\partial w} = \frac{1}{3} \frac{ \partial \lVert y-z\rVert_2^2}{\partial z} \frac{\partial z}{\partial w}
$$
其中
$$
\frac{ \partial \lVert y-z\rVert_2^2}{\partial z} = -2(y-z)
$$
以及
$$
\frac{\partial z}{\partial w} = x^T
$$
都是比较常见的结论。

### torch实现
`torch`就实现了这些梯度的自动计算。我们来用`torch`实现上述的预测模型:
```python hl_lines="6 7"
import torch
torch.manual_seed(1) # set a random seed

x = torch.randn((5,1)) # input tensor
y = torch.randn((3,1)) # expected output
w = torch.randn(3, 5, requires_grad=True)
b = torch.randn(3, 1, requires_grad=True)
z = torch.matmul(w, x)+b
loss = torch.nn.MSELoss()(z, y)
print(w, b, z, loss, sep='\n')
```
注意高亮的两行代码,我们需要额外申明`requires_grad``torch`知道我们相求这两个参数的梯度。此外由于我们设置了随机数种子,输出的结果是固定的:
```
tensor([[-1.0276, -0.5631, -0.8923, -0.0583, -0.1955],
[-0.9656, 0.4224, 0.2673, -0.4212, -0.5107],
[-1.5727, -0.1232, 3.5870, -1.8313, 1.5987]], requires_grad=True)
tensor([[-1.2770],
[ 0.3255],
[-0.4791]], requires_grad=True)
tensor([[-2.1098],
[-0.2148],
[-3.1912]], grad_fn=<AddBackward0>)
tensor(6.0846, grad_fn=<MseLossBackward0>)
```
使用`.backward`即可完成自动梯度的反向传播计算:
```python hl_lines="1"
loss.backward()
print(w.grad)
print(b.grad)
```
输出
```
tensor([[-0.8570, -0.3459, -0.0799, -0.8051, 0.5856],
[ 0.5767, 0.2328, 0.0538, 0.5418, -0.3941],
[-1.5753, -0.6358, -0.1469, -1.4799, 1.0764]])
tensor([[-1.2958],
[ 0.8720],
[-2.3819]])
```
可以验证这个结果和我们手动计算的梯度是一样的:
```python
print((-2*(y-b-w@x)@x.T)/3)
print((-2*(y-b-w@x))/3)
```
```
tensor([[-0.8570, -0.3459, -0.0799, -0.8051, 0.5856],
[ 0.5767, 0.2328, 0.0538, 0.5418, -0.3941],
[-1.5753, -0.6358, -0.1469, -1.4799, 1.0764]], grad_fn=<DivBackward0>)
tensor([[-1.2958],
[ 0.8720],
[-2.3819]], grad_fn=<DivBackward0>)
```
### 计算图
实际上每次`torch`计算都会**动态构建**如下计算图:
> 图中使用的损失函数是CE(cross entropy),我们这里实际上是MSE
<figure markdown>
![](assets/2024-03-16-15-31-08.png){width=500}
</figure>

我们调用`backward`的时候,只要追溯每个操作的`grad function`就可以完成梯度的反向传播。

读者不难注意到我们之前输出`z``loss`的时候就可以看到`grad function`的信息:
```hl_lines="3 4"
tensor([[-2.1098],
[-0.2148],
[-3.1912]], grad_fn=<AddBackward0>)
tensor(6.0846, grad_fn=<MseLossBackward0>)
```

## 模块化的模型搭建
> [torch.nn](https://pytorch.org/docs/stable/nn.html)
PyTorch另外一个比较核心特点的就是模型的模块化,我们可以使用`torch.nn`中提供的各种模块构建自己的模型,自定义程度非常高。
> 这一点很有可能是PyTorch在机器学习学术研究领域一枝独秀的最主要原因
```python
from torch import nn

class NeuralNetwork(nn.Module):
def __init__(self):
super().__init__()
self.flatten = nn.Flatten()
self.linear_relu_stack = nn.Sequential(
nn.Linear(28*28, 512),
nn.ReLU(),
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
```

## 高性能计算
> [torch.tensor](https://pytorch.org/docs/stable/tensors.html)
最后但不得不提的是PyTorch的高性能计算,作为出了名的慢速语言Python的库(当然PyTorch也提供其他语言比如C++的api),PyTorch却不是很慢,它的底层运算主要是是C、C++和CUDA等高性能的代码来处理。

`torch`定义了一个名为张量(`torch.Tensor`) 的类来存储和操作多维数组。PyTorch的张量与NumPy的数组类似,但前者可以在[支持CUDA的N卡](https://pytorch.org/docs/stable/notes/cuda.html)上做运算。

PyTorch 也一直在开发对其他 GPU 平台的支持,例如 [AMD 的 ROCm](https://pytorch.org/blog/pytorch-for-amd-rocm-platform-now-available-as-python-package/)[Apple 的Metal Framework](https://developer.apple.com/metal/pytorch/)

此外PyTorch还支持多卡训练,可以实现multithreading(`DataParallel`)或者multiprocessing(`DistributedDataParallel`)训练。

## v.s. TensorFlow
> tensor flow,这个名字太优雅了!!
PyTorch是[Meta(前Facebook)的开源项目](https://opensource.fb.com/projects/pytorch/),TensorFlow则是[Google的开源项目](https://opensource.google/projects/tensorflow/),因而自然形成了两大阵营。

二者都是非常热门的机器学习框架,我一直是用PyTorch的。不过我最近发现TensorFlow写起来也很爽,比如官网的小例子:

```python
import tensorflow as tf
# MNIST数据集
mnist = tf.keras.datasets.mnist

# 数据集拆分
(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

# 模型定义
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation='softmax')
])

# 模型编译
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])

# 模型训练
model.fit(x_train, y_train, epochs=5)

# 模型评估
model.evaluate(x_test, y_test)
```

这个训练流程如果要用`torch`实现,大概是这样的(下面的代码是GPT3.5写的,基本没问题):
```python
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
from torchvision.datasets import MNIST

# 定义数据预处理
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])

# 加载 MNIST 数据集
train_dataset = MNIST(root='./data', train=True, download=True, transform=transform)
test_dataset = MNIST(root='./data', train=False, download=True, transform=transform)

# 定义数据加载器
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)

# 定义模型
class SimpleNet(nn.Module):
def __init__(self):
super(SimpleNet, self).__init__()
self.flatten = nn.Flatten()
self.fc1 = nn.Linear(28*28, 128)
self.relu = nn.ReLU()
self.dropout = nn.Dropout(0.2)
self.fc2 = nn.Linear(128, 10)
self.softmax = nn.LogSoftmax(dim=1)

def forward(self, x):
x = self.flatten(x)
x = self.fc1(x)
x = self.relu(x)
x = self.dropout(x)
x = self.fc2(x)
x = self.softmax(x)
return x

# 创建模型实例
model = SimpleNet()

# 定义损失函数和优化器
criterion = nn.NLLLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 训练模型
epochs = 5
for epoch in range(epochs):
running_loss = 0.0
for images, labels in train_loader:
optimizer.zero_grad()

outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()

running_loss += loss.item()
else:
print(f"Epoch {epoch+1} - Training loss: {running_loss/len(train_loader)}")

# 评估模型
correct = 0
total = 0
with torch.no_grad():
for images, labels in test_loader:
outputs = model(images)
_, predicted = torch.max(outputs, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()

print('Accuracy on test images: %d %%' % (100 * correct / total))
```

各有千秋吧,你怎么看?
4 changes: 2 additions & 2 deletions docs/Python/ThirdPartyLibrary/pytorch/model.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ tags:
- pytorch
---

# 训练一个模型
# 搭建模型

TBD:pytorch模型训练
TBD:pytorch model
8 changes: 8 additions & 0 deletions docs/Python/ThirdPartyLibrary/pytorch/optimizer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
tags:
- pytorch
---

# 训练模型

TBD:pytorch 训练模型
7 changes: 7 additions & 0 deletions docs/Python/ThirdPartyLibrary/pytorch/quick_start.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
tags:
- pytorch
---

# 快速入门
请看[Quickstart](https://pytorch.org/tutorials/beginner/basics/quickstart_tutorial.html),懒得翻译了。
3 changes: 3 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,11 @@ nav:
- Python/ThirdPartyLibrary/pandas/dataframe.md
- pytorch:
- Python/ThirdPartyLibrary/pytorch/index.md
- Python/ThirdPartyLibrary/pytorch/quick_start.md
- Python/ThirdPartyLibrary/pytorch/tensor.md
- Python/ThirdPartyLibrary/pytorch/data.md
- Python/ThirdPartyLibrary/pytorch/model.md
- Python/ThirdPartyLibrary/pytorch/optimizer.md
- Python/ThirdPartyLibrary/pytorch/multi_gpu.md
- 应用案例(MISC):
- Python/Example/email.md
Expand Down
2 changes: 1 addition & 1 deletion overrides/main.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

{% block announce %}
<!-- Add announcement here, including arbitrary HTML -->
Latest Update(๑•ᴗ•๑)♡ : <a href="/Python/SeniorSyntax/OOP/">面向对象编程</a>
Latest Update(๑•ᴗ•๑)♡ : <a href="/Python/ThirdPartyLibrary/pytorch/">PyTorch简介</a>
{% endblock %}


Expand Down

0 comments on commit 1a402a8

Please sign in to comment.