diff --git a/docs/About/links.md b/docs/About/links.md
index 3915932ac..ffa83e5f7 100644
--- a/docs/About/links.md
+++ b/docs/About/links.md
@@ -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/)
## 或许有用
diff --git a/docs/Note/GFW/client.md b/docs/Note/GFW/client.md
index 19716cc03..669bfced5 100644
--- a/docs/Note/GFW/client.md
+++ b/docs/Note/GFW/client.md
@@ -3,7 +3,7 @@ tags:
- GFW和VPN
---
-# 梯子客户端评测
+# 常见的客户端
??? caution "免责声明"
总之就是免责
diff --git a/docs/Note/GFW/intro.md b/docs/Note/GFW/intro.md
index e4f4c1bcb..e04a97550 100644
--- a/docs/Note/GFW/intro.md
+++ b/docs/Note/GFW/intro.md
@@ -1,5 +1,5 @@
---
-title: 关于墙和梯子的基础知识
+title: 介绍
tags:
- GFW和VPN
---
diff --git a/docs/Note/GFW/server.md b/docs/Note/GFW/server.md
index 542e1607f..f0b0d247e 100644
--- a/docs/Note/GFW/server.md
+++ b/docs/Note/GFW/server.md
@@ -3,6 +3,6 @@ tags:
- GFW和VPN
---
-# 搭建一个VPN服务器
+# 常见的代理协议
TBD:搭建一个VPN服务器
\ No newline at end of file
diff --git a/docs/Python/ThirdPartyLibrary/pytorch/assets/2024-03-16-15-31-08.png b/docs/Python/ThirdPartyLibrary/pytorch/assets/2024-03-16-15-31-08.png
new file mode 100644
index 000000000..328f5a8f8
Binary files /dev/null and b/docs/Python/ThirdPartyLibrary/pytorch/assets/2024-03-16-15-31-08.png differ
diff --git a/docs/Python/ThirdPartyLibrary/pytorch/data.md b/docs/Python/ThirdPartyLibrary/pytorch/data.md
new file mode 100644
index 000000000..08a214e79
--- /dev/null
+++ b/docs/Python/ThirdPartyLibrary/pytorch/data.md
@@ -0,0 +1,8 @@
+---
+tags:
+- pytorch
+---
+
+# 数据加载
+
+TBD:pytorch data
\ No newline at end of file
diff --git a/docs/Python/ThirdPartyLibrary/pytorch/index.md b/docs/Python/ThirdPartyLibrary/pytorch/index.md
index d943ce2c2..a6d4bc0d0 100644
--- a/docs/Python/ThirdPartyLibrary/pytorch/index.md
+++ b/docs/Python/ThirdPartyLibrary/pytorch/index.md
@@ -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介绍
\ No newline at end of file
+## 自动梯度计算
+> [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}
+$$
+### 手算
+这里的模型比较简单,我们可以很容易(好吧也没那么容易,翻书翻了半天,矩阵的微分是真的容易忘掉)计算得到:
+$$
+\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=)
+tensor(6.0846, grad_fn=)
+```
+使用`.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=)
+tensor([[-1.2958],
+ [ 0.8720],
+ [-2.3819]], grad_fn=)
+```
+### 计算图
+实际上每次`torch`计算都会**动态构建**如下计算图:
+> 图中使用的损失函数是CE(cross entropy),我们这里实际上是MSE
+
+
+
+我们调用`backward`的时候,只要追溯每个操作的`grad function`就可以完成梯度的反向传播。
+
+读者不难注意到我们之前输出`z`和`loss`的时候就可以看到`grad function`的信息:
+```hl_lines="3 4"
+tensor([[-2.1098],
+ [-0.2148],
+ [-3.1912]], grad_fn=)
+tensor(6.0846, grad_fn=)
+```
+
+## 模块化的模型搭建
+> [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))
+```
+
+各有千秋吧,你怎么看?
\ No newline at end of file
diff --git a/docs/Python/ThirdPartyLibrary/pytorch/model.md b/docs/Python/ThirdPartyLibrary/pytorch/model.md
index da503828c..8866e5b7c 100644
--- a/docs/Python/ThirdPartyLibrary/pytorch/model.md
+++ b/docs/Python/ThirdPartyLibrary/pytorch/model.md
@@ -3,6 +3,6 @@ tags:
- pytorch
---
-# 训练一个模型
+# 搭建模型
-TBD:pytorch模型训练
\ No newline at end of file
+TBD:pytorch model
\ No newline at end of file
diff --git a/docs/Python/ThirdPartyLibrary/pytorch/optimizer.md b/docs/Python/ThirdPartyLibrary/pytorch/optimizer.md
new file mode 100644
index 000000000..ec660b58b
--- /dev/null
+++ b/docs/Python/ThirdPartyLibrary/pytorch/optimizer.md
@@ -0,0 +1,8 @@
+---
+tags:
+- pytorch
+---
+
+# 训练模型
+
+TBD:pytorch 训练模型
\ No newline at end of file
diff --git a/docs/Python/ThirdPartyLibrary/pytorch/quick_start.md b/docs/Python/ThirdPartyLibrary/pytorch/quick_start.md
new file mode 100644
index 000000000..f254edf0c
--- /dev/null
+++ b/docs/Python/ThirdPartyLibrary/pytorch/quick_start.md
@@ -0,0 +1,7 @@
+---
+tags:
+- pytorch
+---
+
+# 快速入门
+请看[Quickstart](https://pytorch.org/tutorials/beginner/basics/quickstart_tutorial.html),懒得翻译了。
\ No newline at end of file
diff --git a/mkdocs.yml b/mkdocs.yml
index 7c94190a8..5465c137c 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -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
diff --git a/overrides/main.html b/overrides/main.html
index b450145d7..83c98a0a4 100644
--- a/overrides/main.html
+++ b/overrides/main.html
@@ -3,7 +3,7 @@
{% block announce %}
-Latest Update(๑•ᴗ•๑)♡ : 面向对象编程
+Latest Update(๑•ᴗ•๑)♡ : PyTorch简介
{% endblock %}