机器学习present1的md
This commit is contained in:
commit
c565ad2c33
146
Tensorflow的优化器.md
Normal file
146
Tensorflow的优化器.md
Normal file
@ -0,0 +1,146 @@
|
||||
### **1. 基础优化器**
|
||||
#### **(1) SGD(随机梯度下降)**
|
||||
• **原理**:
|
||||
沿梯度的反方向以固定步长(学习率)更新参数。
|
||||
**公式**:
|
||||
$$\theta_{t+1} = \theta_t - \eta \cdot \nabla_\theta J(\theta_t)$$
|
||||
|
||||
|
||||
•$\eta$: 学习率
|
||||
•$\nabla_\theta J(\theta_t)$: 参数$\theta$在损失函数$J$处的梯度
|
||||
• **特点**:
|
||||
• **优点**:简单、稳定,适合凸优化问题。
|
||||
• **缺点**:对学习率敏感,可能陷入局部最优或震荡。
|
||||
• **适用场景**:小型网络或需要精细调参的任务。
|
||||
• **代码示例**:
|
||||
```python
|
||||
optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
|
||||
```
|
||||
---
|
||||
#### **(2) Momentum(动量)**
|
||||
• **原理**:
|
||||
在 SGD 基础上引入动量项,加速收敛并减少震荡。动量模拟物理中的惯性。
|
||||
**公式**:
|
||||
$$v_t = \gamma v_{t-1} + \eta \cdot \nabla_\theta J(\theta_t) \\
|
||||
\theta_{t+1} = \theta_t - v_t$$
|
||||
|
||||
•$\gamma$: 动量系数(通常取 0.9)
|
||||
• **特点**:
|
||||
• **优点**:加速收敛,减少梯度震荡。
|
||||
• **适用场景**:训练深层网络或复杂非凸问题。
|
||||
• **代码示例**:
|
||||
```python
|
||||
optimizer = tf.keras.optimizers.SGD(learning_rate=0.01, momentum=0.9)
|
||||
```
|
||||
---
|
||||
### **2. 自适应学习率优化器**
|
||||
#### **(1) Adagrad(自适应梯度算法)**
|
||||
• **原理**:
|
||||
根据参数自适应调整学习率,频繁更新的参数使用更小的学习率。
|
||||
**公式**:
|
||||
$$ r_t = r_{t-1} + \eta \cdot (\nabla_\theta J(\theta_t))^2 \\
|
||||
\theta_{t+1} = \theta_t - \frac{\eta \cdot \nabla_\theta J(\theta_t)}{\sqrt{r_t} + \epsilon}$$
|
||||
•$r_t$: 累计梯度平方和
|
||||
•$\epsilon$: 防止除零的小常数
|
||||
• **特点**:
|
||||
• **优点**:自动调整学习率,适合稀疏数据(如 NLP)。
|
||||
• **缺点**:学习率可能过早衰减。
|
||||
• **代码示例**:
|
||||
```python
|
||||
optimizer = tf.keras.optimizers.Adagrad(learning_rate=0.01)
|
||||
```
|
||||
---
|
||||
#### **(2) RMSProp(均方根传播)**
|
||||
• **原理**:
|
||||
对梯度平方取指数移动平均,调整学习率以平衡不同参数的更新。
|
||||
**公式**:
|
||||
$$r_t = \gamma r_{t-1} + (1-\gamma) (\nabla_\theta J(\theta_t))^2 \\
|
||||
\theta_{t+1} = \theta_t - \frac{\eta \cdot \nabla_\theta J(\theta_t)}{\sqrt{r_t} + \epsilon}$$
|
||||
|
||||
•$\gamma$: 冷却系数(通常取 0.9)
|
||||
• **特点**:
|
||||
• **优点**:缓解 Adagrad 学习率衰减过快的问题。
|
||||
• **适用场景**:训练循环神经网络(RNN)。
|
||||
• **代码示例**:
|
||||
```python
|
||||
optimizer = tf.keras.optimizers.RMSProp(learning_rate=0.001, rho=0.9)
|
||||
```
|
||||
---
|
||||
#### **(3) Adam(自适应矩估计)**
|
||||
• **原理**:
|
||||
结合 Momentum 和 RMSProp,同时维护一阶矩(均值)和二阶矩(方差)。
|
||||
**公式**:
|
||||
$$ m_t = \beta_1 m_{t-1} + (1-\beta_1) \cdot \nabla_\theta J(\theta_t) \\
|
||||
v_t = \beta_2 v_{t-1} + (1-\beta_2) \cdot (\nabla_\theta J(\theta_t))^2 \\
|
||||
\hat{m}_t = \frac{m_t}{1-\beta_1^t} \\
|
||||
\hat{v}_t = \frac{v_t}{1-\beta_2^t} \\
|
||||
\theta_{t+1} = \theta_t - \frac{\eta \cdot \hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon}$$
|
||||
•$\beta_1$、$\beta_2$: 衰减率(通常取 0.9 和 0.999)
|
||||
• **特点**:
|
||||
• **优点**:快速收敛,内存效率高,适用于大规模数据和复杂网络。
|
||||
• **缺点**:可能对初始学习率敏感。
|
||||
• **适用场景**:大多数深度学习任务(如 CNN、RNN)。
|
||||
• **代码示例**:
|
||||
```python
|
||||
optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
|
||||
```
|
||||
---
|
||||
#### **(4) AdamW(Adam 的改进版)**
|
||||
• **原理**:
|
||||
解决 Adam 的权重衰减(Weight Decay)与梯度裁剪的冲突,通过分离参数更新和权重衰减。
|
||||
**改进点**:
|
||||
$$ \theta_{t+1} = \theta_t - \frac{\eta \cdot \hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon} - \eta \cdot \lambda \cdot \theta_t $$
|
||||
•$\lambda$: 权重衰减系数
|
||||
• **特点**:
|
||||
• **优点**:提升训练稳定性,减少过拟合,效果优于标准 Adam。
|
||||
• **适用场景**:大规模图像分类(如 ImageNet)。
|
||||
• **代码示例**:
|
||||
```python
|
||||
optimizer = tf.keras.optimizers.AdamW(learning_rate=0.001, weight_decay=0.01)
|
||||
```
|
||||
---
|
||||
### **3. 高级优化器**
|
||||
#### **(1) Nadam(Nesterov 加速 Adam)**
|
||||
• **原理**:
|
||||
在 Adam 基础上引入 Nesterov 动量,提前修正梯度方向。
|
||||
**公式**:
|
||||
$$\hat{g}_t = \nabla_\theta J(\theta_t - \gamma \cdot m_{t-1}) \\
|
||||
m_t = \beta_1 m_{t-1} + (1-\beta_1) \cdot \hat{g}_t \\
|
||||
\theta_{t+1} = \theta_t - \frac{\eta \cdot m_t}{\sqrt{v_t} + \epsilon} $$
|
||||
•$\gamma$: Nesterov 动量系数(通常取 0.9)
|
||||
• **特点**:
|
||||
• **优点**:比 Adam 更快的收敛速度。
|
||||
• **适用场景**:需要快速训练的场景。
|
||||
• **代码示例**:
|
||||
```python
|
||||
optimizer = tf.keras.optimizers.Nadam(learning_rate=0.001)
|
||||
```
|
||||
---
|
||||
#### **(2) AMSGrad(Adam 的改进版)**
|
||||
• **原理**:
|
||||
修正 Adam 中二阶矩估计的偏差,使用历史最大值替代当前方差。
|
||||
**公式**:
|
||||
$$v_t^{corrected} = \max(v_t, v_{t-1}^{corrected})$$
|
||||
|
||||
• **特点**:
|
||||
• **优点**:提升训练稳定性,尤其在动态损失函数场景下。
|
||||
• **适用场景**:动态梯度或噪声较大的环境。
|
||||
• **代码示例**:
|
||||
```python
|
||||
optimizer = tf.keras.optimizers.Adam(learning_rate=0.001, amsgrad=True)
|
||||
```
|
||||
---
|
||||
### **4. 选择优化器的建议**
|
||||
| **场景** | **推荐优化器** |
|
||||
|-------------------------|---------------------------|
|
||||
| 简单模型/小数据集 | SGD with Momentum |
|
||||
| 复杂模型/大规模数据 | Adam / AdamW |
|
||||
| RNN 或序列任务 | RMSProp |
|
||||
| 需要快速收敛 | Nadam |
|
||||
| 权重衰减敏感问题 | AdamW |
|
||||
---
|
||||
### **5. 总结**
|
||||
- SGD 和 Momentum 是基础,适合理解优化原理。
|
||||
- Adam 和 AdamW 是工业级默认选择,适用于大多数场景。
|
||||
- RMSProp 和 Adagrad 适合特定任务(如 RNN 或稀疏数据)。
|
||||
- Nadam 和 AMSGrad 用于追求更快的收敛或稳定性。
|
218
Tensorflow的损失函数.md
Normal file
218
Tensorflow的损失函数.md
Normal file
@ -0,0 +1,218 @@
|
||||
|
||||
### **1. 分类任务损失函数**
|
||||
#### **(1) 交叉熵损失(Cross-Entropy Loss)**
|
||||
- **原理**:
|
||||
用于衡量预测概率分布与真实标签分布之间的差异。
|
||||
- **稀疏交叉熵**(`SparseCategoricalCrossentropy`):
|
||||
标签为整数(如 `[0, 1, 2]`),直接计算类别索引的交叉熵。
|
||||
**公式**:
|
||||
$$\
|
||||
H(y, \hat{y}) = -\sum_{i} y_i \log(\hat{y}_i)
|
||||
\ $$
|
||||
- **多分类交叉熵**(`CategoricalCrossentropy`):
|
||||
标签为 One-Hot 编码(如 `[[1,0,0], [0,1,0]]`)。
|
||||
- **适用场景**:
|
||||
图像分类、文本分类等离散标签任务。
|
||||
- **代码示例**:
|
||||
```python
|
||||
from tensorflow.keras.losses import SparseCategoricalCrossentropy
|
||||
model.compile(optimizer='adam', loss=SparseCategoricalCrossentropy(from_logits=True))
|
||||
```
|
||||
---
|
||||
#### **(2) 对数损失(Logistic Loss / Binary Cross-Entropy)**
|
||||
- **原理**:
|
||||
二分类任务的特例,输出为概率值(sigmoid 输出)。
|
||||
**公式**:
|
||||
$$\
|
||||
H(y, \hat{y}) = -\sum_{i} y_i \log(\hat{y}_i) - (1-y_i) \log(1-\hat{y}_i)
|
||||
\ $$
|
||||
- **适用场景**:
|
||||
二分类任务(如垃圾邮件检测)。
|
||||
- **代码示例**:
|
||||
```python
|
||||
from tensorflow.keras.losses import BinaryCrossentropy
|
||||
model.compile(optimizer='adam', loss=BinaryCrossentropy())
|
||||
```
|
||||
---
|
||||
#### **(3) Hinge Loss**
|
||||
- **原理**:
|
||||
最大间隔分类器(如 SVM),关注正确分类的边界。
|
||||
**公式**:
|
||||
$$\
|
||||
L(y, \hat{y}) = \max(0, 1 - y \cdot \hat{y})
|
||||
\ $$
|
||||
- \( y \in \{-1, 1\} \),\( \hat{y} \) 为模型输出(未归一化)。
|
||||
- **适用场景**:
|
||||
文本分类、图像识别中的边界敏感任务。
|
||||
- **代码示例**:
|
||||
```python
|
||||
from tensorflow.keras.losses import Hinge
|
||||
model.compile(optimizer='adam', loss=Hinge())
|
||||
```
|
||||
---
|
||||
### **2. 回归任务损失函数**
|
||||
#### **(1) 均方误差(MSE / Mean Squared Error)**
|
||||
- **原理**:
|
||||
预测值与真实值差的平方的平均值。
|
||||
**公式**:
|
||||
$$\
|
||||
MSE = \frac{1}{N} \sum_{i=1}^{N} (y_{\text{true}}^{(i)} - y_{\text{pred}}^{(i)})^2
|
||||
\ $$
|
||||
- **适用场景**:
|
||||
回归任务(如房价预测、图像修复)。
|
||||
- **代码示例**:
|
||||
```python
|
||||
from tensorflow.keras.losses import MeanSquaredError
|
||||
model.compile(optimizer='adam', loss=MeanSquaredError())
|
||||
```
|
||||
---
|
||||
#### **(2) 平均绝对误差(MAE / Mean Absolute Error)**
|
||||
- **原理**:
|
||||
预测值与真实值差的绝对值的平均值。
|
||||
**公式**:
|
||||
$$\
|
||||
MAE = \frac{1}{N} \sum_{i=1}^{N} |y_{\text{true}}^{(i)} - y_{\text{pred}}^{(i)}|
|
||||
\ $$
|
||||
- **适用场景**:
|
||||
对异常值不敏感的任务(如推荐系统评分预测)。
|
||||
- **代码示例**:
|
||||
```python
|
||||
from tensorflow.keras.losses import MeanAbsoluteError
|
||||
model.compile(optimizer='adam', loss=MeanAbsoluteError())
|
||||
```
|
||||
---
|
||||
#### **(3) Huber Loss**
|
||||
- **原理**:
|
||||
结合 MSE 和 MAE,对中等误差平方处理,对大误差线性处理(降低敏感度)。
|
||||
**公式**:
|
||||
$$\
|
||||
L_\delta(y, \hat{y}) =
|
||||
\begin{cases}
|
||||
\frac{1}{2}\delta^2 (y - \hat{y})^2 & \text{if } |y - \hat{y}| \leq \delta \\
|
||||
\delta (|y - \hat{y}| - \delta) & \text{otherwise}
|
||||
\end{cases}
|
||||
\ $$
|
||||
- $\delta$: 阈值(默认 1.0)。
|
||||
- **适用场景**:
|
||||
存在异常值的回归任务(如自动驾驶中的目标检测)。
|
||||
- **代码示例**:
|
||||
```python
|
||||
from tensorflow.keras.losses import Huber
|
||||
model.compile(optimizer='adam', loss=Huber(delta=1.0))
|
||||
```
|
||||
---
|
||||
### **3. 序列任务损失函数**
|
||||
#### **(1) CTC Loss(Connectionist Temporal Classification)**
|
||||
- **原理**:
|
||||
用于序列到序列任务(如语音识别),解决标签序列与预测序列长度不一致的问题。
|
||||
**特点**:
|
||||
- 自动对齐输入和输出序列。
|
||||
- 支持空格分隔符(如 `"hello world"` → `[h, e, l, l, o, _, w, o, r, l, d]`)。
|
||||
- **适用场景**:
|
||||
语音识别、文本生成、时间序列预测。
|
||||
- **代码示例**:
|
||||
```python
|
||||
from tensorflow.keras.losses import CTCLoss
|
||||
model.compile(optimizer='adam', loss=CTCLoss())
|
||||
```
|
||||
---
|
||||
#### **(2) 自回归损失(AutoRegressive Loss)**
|
||||
- **原理**:
|
||||
逐个预测序列中的每个时间步,累积误差。
|
||||
**公式**:
|
||||
|
||||
$$\
|
||||
L = \sum_{t=1}^{T} \log P(y_t | y_{1:t-1}, x)
|
||||
\ $$
|
||||
|
||||
- **适用场景**:
|
||||
机器翻译、文档摘要生成。
|
||||
---
|
||||
### **4. 自定义损失函数**
|
||||
当内置损失函数无法满足需求时,可以自定义损失函数。以下是一个示例:
|
||||
#### **(1) 自定义 MSE 损失**
|
||||
```python
|
||||
import tensorflow as tf
|
||||
def custom_mse(y_true, y_pred):
|
||||
return tf.reduce_mean(tf.square(y_true - y_pred))
|
||||
model.compile(optimizer='adam', loss=custom_mse)
|
||||
```
|
||||
#### **(2) 多任务损失(加权组合)**
|
||||
```python
|
||||
def multi_task_loss(y_true, y_pred):
|
||||
# 假设有两个输出层:output1 和 output2
|
||||
loss1 = tf.keras.losses.mse(y_true[0], y_pred[0])
|
||||
loss2 = tf.keras.losses.binary_crossentropy(y_true[1], y_pred[1])
|
||||
return 0.7 * loss1 + 0.3 * loss2 # 加权组合
|
||||
model.compile(optimizer='adam', loss=multi_task_loss)
|
||||
```
|
||||
---
|
||||
### **5. 其他特殊损失函数**
|
||||
#### **(1) Poisson Loss**
|
||||
- **原理**:
|
||||
适用于计数数据(如用户点击率预测)。
|
||||
**公式**:
|
||||
$$\
|
||||
L = \sum_{i=1}^{N} \left( y_{\text{true}}^{(i)} \log(y_{\text{pred}}^{(i)}) - y_{\text{pred}}^{(i)} \right)
|
||||
\ $$
|
||||
- **适用场景**:
|
||||
推荐系统、自然语言处理中的词频预测。
|
||||
- **代码示例**:
|
||||
```python
|
||||
from tensorflow.keras.losses import Poisson
|
||||
model.compile(optimizer='adam', loss=Poisson())
|
||||
```
|
||||
---
|
||||
#### **(2) Contrastive Loss**
|
||||
- **原理**:
|
||||
通过对比正负样本的相似度来学习特征表示。
|
||||
**公式**:
|
||||
$$\
|
||||
L = y \cdot \log(d) + (1-y) \cdot \log(1-d)
|
||||
\ $$
|
||||
- \( d \): 正样本相似度,\( 1-d \): 负样本相似度。
|
||||
- **适用场景**:
|
||||
图像检索、相似性学习。
|
||||
- **代码示例**:
|
||||
```python
|
||||
# 需自定义实现或使用库(如 TensorFlow Addons)
|
||||
```
|
||||
---
|
||||
### **6. 如何选择损失函数?**
|
||||
| 任务类型 | 推荐损失函数 | 场景说明 |
|
||||
|----------|--------------|----------|
|
||||
| 二分类 | BinaryCrossentropy | 标签为 0/1 或 One-Hot 编码 |
|
||||
| 多分类 | SparseCategoricalCrossentropy | 标签为整数(未 One-Hot) |
|
||||
| 回归 | MeanSquaredError 或 Huber | 数据分布均匀或存在异常值 |
|
||||
| 序列标注 | CTC Loss | 语音识别、文本对齐 |
|
||||
| 多任务学习 | 加权组合损失(如 MSE + CrossEntropy) | 同时优化多个输出 |
|
||||
| 异常检测 | Huber Loss | 对离群值不敏感 |
|
||||
|
||||
### 7. 高级配置
|
||||
#### (1) 加权损失(Weighted Loss)
|
||||
用于为不同类别分配不同的损失权重。
|
||||
- 代码示例:
|
||||
```python
|
||||
# 为不同类别赋予不同权重
|
||||
model.compile(
|
||||
optimizer='adam',
|
||||
loss='sparse_categorical_crossentropy',
|
||||
loss_weights={'class_0': 1.0, 'class_1': 5.0} # 类别1的权重更高
|
||||
)
|
||||
```
|
||||
#### (2) 自定义梯度裁剪
|
||||
用于限制梯度的大小,防止梯度爆炸。
|
||||
>p.s. 梯度爆炸是指在训练深度学习模型时,梯度(即损失函数关于模型参数的导数)的值变得非常大,导致模型参数更新过大,从而使得模型无法收敛到一个稳定的解。
|
||||
- 代码示例:
|
||||
```python
|
||||
optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
|
||||
optimizer.clipnorm = 1.0 # 梯度范数不超过1.0
|
||||
model.compile(optimizer=optimizer, loss='mse')
|
||||
```
|
||||
---
|
||||
### 总结
|
||||
- **分类任务**:优先选择交叉熵或其变体(如 `SparseCategoricalCrossentropy` 或 `CategoricalCrossentropy`)。
|
||||
- **回归任务**:根据数据分布选择 `MeanSquaredError`(MSE)、`MeanAbsoluteError`(MAE)或 `Huber`。
|
||||
- **序列任务**:使用 `CTC Loss` 或自回归损失。
|
||||
- **自定义需求**:通过继承 `tf.keras.losses.Loss` 类实现灵活的损失函数。
|
||||
通过合理选择损失函数,可以显著提升模型性能。建议结合具体任务和数据特点进行对比实验,以确定最佳的损失函数。在实际应用中,损失函数的选择可能会影响模型的收敛速度和最终性能,因此需要根据具体情况进行调整。
|
396
teach_Pytorch.md
Normal file
396
teach_Pytorch.md
Normal file
@ -0,0 +1,396 @@
|
||||
# 深度学习的实现
|
||||
## 在Pytorch中实现
|
||||
```python
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
import torch.optim as optim
|
||||
from torchvision import transforms
|
||||
from torchvision import datasets
|
||||
from torch.utils.data import DataLoader
|
||||
import warnings
|
||||
|
||||
|
||||
# 数据加载与预处理
|
||||
transform = transforms.Compose([
|
||||
transforms.ToTensor(),
|
||||
transforms.Normalize((0.1307,), (0.3081,))
|
||||
])
|
||||
|
||||
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
|
||||
test_dataset = datasets.MNIST(root='./data', train=False, transform=transform)
|
||||
|
||||
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, num_workers=4, pin_memory=True)
|
||||
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False, num_workers=4, pin_memory=True)
|
||||
|
||||
class MNISTCNN(nn.Module):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.conv_layers = nn.Sequential(
|
||||
nn.Conv2d(1, 32, 3, padding=1),
|
||||
nn.ReLU(inplace=True),
|
||||
nn.MaxPool2d(2),
|
||||
nn.Conv2d(32, 64, 3, padding=1),
|
||||
nn.ReLU(inplace=True),
|
||||
nn.MaxPool2d(2),
|
||||
)
|
||||
self.fc_layers = nn.Sequential(
|
||||
nn.Linear(64 * 7 * 7, 128),
|
||||
nn.ReLU(inplace=True),
|
||||
nn.Dropout(0.5),
|
||||
nn.Linear(128, 10)
|
||||
)
|
||||
|
||||
def forward(self, x):
|
||||
x = self.conv_layers(x)
|
||||
x = x.view(x.size(0), -1)
|
||||
return self.fc_layers(x)
|
||||
|
||||
model = MNISTCNN().to('cuda')
|
||||
|
||||
optimizer = optim.AdamW(model.parameters(), lr=0.001, weight_decay=0.0001)
|
||||
loss_fn = nn.CrossEntropyLoss(reduction='mean')
|
||||
|
||||
num_epochs = 10
|
||||
|
||||
for epoch in range(num_epochs):
|
||||
model.train()
|
||||
train_loss = 0.0
|
||||
for images, labels in train_loader:
|
||||
images, labels = images.to('cuda'), labels.to('cuda')
|
||||
optimizer.zero_grad()
|
||||
outputs = model(images)
|
||||
loss = loss_fn(outputs, labels)
|
||||
loss.backward()
|
||||
optimizer.step()
|
||||
train_loss += loss.item() * images.size(0)
|
||||
|
||||
avg_train_loss = train_loss / len(train_dataset)
|
||||
|
||||
# 验证
|
||||
model.eval()
|
||||
correct = 0
|
||||
total = 0
|
||||
with torch.no_grad():
|
||||
for images, labels in test_loader:
|
||||
images, labels = images.to('cuda'), labels.to('cuda')
|
||||
outputs = model(images)
|
||||
_, predicted = torch.max(outputs, 1)
|
||||
total += labels.size(0)
|
||||
correct += (predicted == labels).sum().item()
|
||||
test_acc = 100 * correct / total
|
||||
|
||||
print(f'Epoch {epoch+1}/{num_epochs} | Train Loss: {avg_train_loss:.4f} | Test Acc: {test_acc:.2f}%')
|
||||
|
||||
torch.save(model.state_dict(), 'mnist_cnn_model.pth')
|
||||
print("Saved CNN model state!")
|
||||
```
|
||||
|
||||
### 在Pytorch中实现深度学习需要以下步骤:
|
||||
`数据准备`->`模型定义`->`定义优化器 & 损失函数`->`模型训练(自动/自定义)`->`模型评估`->`保存 & 部署`
|
||||
|
||||
### 模型定义
|
||||
#### 基础定义模板
|
||||
```python
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
|
||||
class MyModel(nn.Module):
|
||||
def __init__(self):
|
||||
super(MyModel, self).__init__() # 必须调用父类构造函数
|
||||
# 在这里定义网络层
|
||||
self.layer1 = nn.Linear(in_features=784, out_features=256)
|
||||
self.layer2 = nn.Linear(256, 10)
|
||||
self.relu = nn.ReLU()
|
||||
|
||||
def forward(self, x):
|
||||
# 定义前向传播逻辑
|
||||
x = self.relu(self.layer1(x))
|
||||
x = self.layer2(x)
|
||||
return x
|
||||
```
|
||||
- 他需要手动定义向前传播逻辑,即`forward`函数,并且需要手动调用父类的构造函数`super(MyModel, self).__init__()`
|
||||
- `nn.Module`是所有神经网络模块的基类,我们自己的模型需要继承这个类,并且实现`forward`函数
|
||||
- `nn.Linear`是全连接层,`in_features`是输入特征数,`out_features`是输出特征数
|
||||
- `nn.ReLU`是激活函数
|
||||
- `self.layer1 = nn.Linear(in_features=784, out_features=256)`表示定义一个全连接层,输入特征数为784,输出特征数为256
|
||||
- `self.layer2 = nn.Linear(256, 10)`表示定义一个全连接层,输入特征数为256,输出特征数为10
|
||||
- `self.relu = nn.ReLU()`表示定义一个激活函数
|
||||
- `x = self.relu(self.layer1(x))`表示先通过`layer1`层,再通过`relu`激活函数
|
||||
- `x = self.layer2(x)`表示通过`layer2`层
|
||||
- `return x`表示返回输出
|
||||
#### 使用 nn.Sequential 简化模型定义
|
||||
```python
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
|
||||
class MyModel(nn.Module):
|
||||
def __init__(self):
|
||||
super(MyModel, self).__init__()
|
||||
self.model = nn.Sequential(
|
||||
nn.Linear(in_features=784, out_features=256),
|
||||
nn.ReLU(),
|
||||
nn.Linear(256, 10)
|
||||
)
|
||||
|
||||
def forward(self, x):
|
||||
return self.model(x)
|
||||
```
|
||||
- `nn.Sequential`是一个容器,可以将多个层按顺序组合在一起,与tensorflow的`tf.keras.Sequential`类似
|
||||
- `self.model = nn.Sequential(nn.Linear(in_features=784, out_features=256), nn.ReLU(), nn.Linear(256, 10))`表示定义一个包含两个全连接层和一个激活函数的模型
|
||||
- `return self.model(x)`表示通过`self.model`模型进行前向传播
|
||||
#### 在torch中有超过50种类型的层,可以参考官方文档,使用方式都一样,不断的在`nn.Module`中添加层即可
|
||||
| 层类型 | 定义参数 | 作用 | 示例代码 | 典型用途 |
|
||||
|----------------------|-------------------------------------------|------------------------------------------|--------------------------------------|----------------------|
|
||||
| nn.Linear | in_features (输入维度), out_features (输出维度) | 全连接层:对输入数据进行线性变换。 | self.fc = nn.Linear(784, 256) | MLP、全连接网络 |
|
||||
| nn.Conv2d | in_channels, out_channels, kernel_size, stride=1, padding=0 | 二维卷积层:提取局部特征(图像处理)。 | self.conv1 = nn.Conv2d(3, 64, 3, padding=1) | CNN、图像分类 |
|
||||
| nn.ReLU | inplace=False (默认) | 非线性激活函数:缓解梯度消失,引入非线性。 | self.relu = nn.ReLU(inplace=True) | 所有神经网络层后 |
|
||||
| nn.BatchNorm2d | num_features (输出通道数) | 批量归一化:加速训练,稳定梯度。 | self.bn1 = nn.BatchNorm2d(64) | CNN、ResNet |
|
||||
| nn.MaxPool2d | kernel_size, stride=1, padding=0 | 最大池化:下采样,减少计算量,增加平移不变性。 | self.pool = nn.MaxPool2d(2, 2) | 图像特征提取 |
|
||||
| nn.Dropout | p=0.5 (丢弃概率,默认0.5) | 随机失活:防止过拟合。 | self.dropout = nn.Dropout(0.5) | MLP、RNN、CNN |
|
||||
| nn.Embedding | num_embeddings (嵌入维度), input_dim (词汇表大小) | 嵌入层:将离散类别映射为稠密向量。 | self.embedding = nn.Embedding(10000, 128) | NLP、词嵌入 |
|
||||
| nn.LSTM | input_size, hidden_size, num_layers, batch_first=True | 长短期记忆网络:处理序列数据,捕捉长期依赖。 | self.lstm = nn.LSTM(100, 64, 2, batch_first=True) | 文本分类、时间序列预测 |
|
||||
| nn.GRU | input_size, hidden_size, num_layers, batch_first=True | 门控循环单元:简化版 LSTM,计算更高效。 | self.gru = nn.GRU(100, 64, 2, batch_first=True) | 类似 LSTM 的应用场景 |
|
||||
| nn.TransformerEncoderLayer | d_model, nhead, dim_k, dim_v | Transformer 编码器层:自注意力机制,处理序列数据。 | self.encoder_layer = nn.TransformerEncoderLayer(512, 8) | NLP、机器翻译 |
|
||||
| nn.Upsample | scale_factor (上采样倍数), mode='nearest' | 上采样:图像超分辨率,扩大特征图尺寸。 | self.up = nn.Upsample(scale_factor=2, mode='nearest') | 图像分割、生成模型 |
|
||||
| nn.ConvTranspose2d | in_channels, out_channels, kernel_size, stride=1, padding=0 | 转置卷积:反卷积操作,用于生成对抗网络(GAN)的输出。 | self.deconv = nn.ConvTranspose2d(64, 3, 3, padding=1) | GAN、图像修复 |
|
||||
| nn.Softmax | dim=-1 (默认) | 概率分布:将输出转换为分类概率。 | self.softmax = nn.Softmax(dim=1) | 分类任务最终层 |
|
||||
| nn.CrossEntropyLoss | ignore_index=-1 (可选) | 结合 Softmax 和 Cross-Entropy 的损失函数,用于分类任务。 | criterion = nn.CrossEntropyLoss() | 分类任务(无需手动加 Softmax)|
|
||||
| nn.MSELoss | | 均方误差损失:回归任务。 | criterion = nn.MSELoss() | 回归、坐标预测 |
|
||||
### 定义优化器和损失函数
|
||||
一、定义优化器 (Optimizer)
|
||||
优化器用于更新模型的参数,常见的算法包括SGD、Adam、RMSProp等。PyTorch的torch.optim模块提供了多种优化器。
|
||||
1. 常用优化器示例
|
||||
```python
|
||||
import torch.optim as optim
|
||||
|
||||
# 定义优化器
|
||||
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
|
||||
optimizer = optim.Adam(model.parameters(), lr=0.001, betas=(0.9, 0.999))
|
||||
optimizer = optim.RMSprop(model.parameters(), lr=0.01, alpha=0.99)
|
||||
```
|
||||
2. 常用参数说明
|
||||
|
||||
| 参数名 | 含义 | 默认值 |
|
||||
|------------|----------------------------------|---------|
|
||||
| params | 需要优化的参数(通常是model.parameters()) | 必须参数 |
|
||||
| lr | 学习率(Learning Rate) | 1e-3 |
|
||||
| momentum | 动量项(仅SGD系列有效) | 0 |
|
||||
| weight_decay | 权重衰减(L2正则化) | 0 |
|
||||
| betas | Adam的β1和β2超参数(平衡梯度指数衰减率) | (0.9, 0.99) |
|
||||
| eps | Adam的极小值防止除零错误 | 1e-8(默认为1e-7) |
|
||||
|
||||
二、定义损失函数 (Loss Function)
|
||||
损失函数用于衡量模型的预测结果与真实标签之间的差异,常见的损失函数包括均方误差损失、交叉熵损失等。PyTorch的torch.nn模块提供了多种损失函数。
|
||||
1. 常用损失函数示例
|
||||
```python
|
||||
import torch.nn as nn
|
||||
|
||||
# 分类任务(如图像分类)
|
||||
criterion = nn.CrossEntropyLoss(
|
||||
reduction='mean' # 可选'mean'或'sum'
|
||||
)
|
||||
|
||||
# 回归任务(如房价预测)
|
||||
criterion = nn.MSELoss(
|
||||
reduction='mse' # 可选'mse', 'mae', 'sum', 'mean'
|
||||
)
|
||||
```
|
||||
2. 常用参数说明
|
||||
- reduction:指定损失函数的归约方式,可选值包括none(不聚合)、sum(求和)、mean(均值)、mse(均方误差)。默认为'mean'。
|
||||
- weight:指定每个类别的权重,用于加权交叉熵损失。
|
||||
- ignore_index:指定忽略的类别索引,用于多分类任务。
|
||||
### 模型训练
|
||||
#### 一、自动训练(标准流程)
|
||||
这是最常见的模式,基于 DataLoader 和 torch.nn 模块的高层抽象实现。
|
||||
|
||||
1. 核心 API
|
||||
|
||||
API | 作用 | 参数说明 |
|
||||
--- | --- | --- |
|
||||
torch.utils.data.DataLoader | 数据加载器,封装 Dataset 并分批次加载数据 | dataset: 自定义数据集对象, batch_size: 每次迭代的数据量 |
|
||||
model.train() | 将模型切换为训练模式(启用 Dropout/BatchNorm 等训练时行为) | 无参数 |
|
||||
optimizer.step() | 执行参数更新(基于梯度) | 无参数 |
|
||||
optimizer.zero_grad() | 清空梯度缓存,为下一次反向传播准备 | 无参数 |
|
||||
loss.backward() | 反向传播,计算梯度 | retain_graph=True 可保留梯度用于多次反向传播 |
|
||||
2. 代码示例
|
||||
```python
|
||||
# 定义模型、优化器、损失函数
|
||||
model = MyModel().to(device)
|
||||
optimizer = torch.optim.Adam(
|
||||
params=model.parameters(),
|
||||
lr=0.001, # 学习率(核心超参数)
|
||||
betas=(0.9, 0.999), # 动量参数
|
||||
eps=1e-8, # 数值稳定性保护
|
||||
weight_decay=0.01 # 权重衰减(正则化)
|
||||
)
|
||||
criterion = nn.CrossEntropyLoss()
|
||||
|
||||
# 训练循环
|
||||
for epoch in range(num_epochs):
|
||||
model.train() # 设置训练模式
|
||||
for inputs, labels in dataloader: ## 注意dataloader是迭代器,每次迭代返回一个batch的数据
|
||||
inputs, labels = inputs.to(device), labels.to(device)
|
||||
|
||||
# 前向传播
|
||||
outputs = model(inputs)
|
||||
loss = criterion(outputs, labels)
|
||||
|
||||
# 反向传播 + 参数更新
|
||||
optimizer.zero_grad() # 清空梯度
|
||||
loss.backward() # 计算梯度
|
||||
optimizer.step() # 更新参数
|
||||
|
||||
# 打印日志
|
||||
print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}")
|
||||
```
|
||||
#### 二、自定义训练(灵活控制)
|
||||
- 适用于需要特殊逻辑的场景(如动态修改学习率、梯度裁剪、多任务学习等)。
|
||||
1. 扩展功能 API
|
||||
|
||||
API | 作用 | 参数说明 |
|
||||
--------------------------- | ---------------------------------------------- | --------------------------------------------- |
|
||||
torch.optim.lr_scheduler | 学习率调度器(如 StepLR、ReduceLROnPlateau) | optimizer: 优化器对象,step_size调度步长
|
||||
torch.nn.utils.clip_grad_norm_ | 梯度裁剪,防止爆炸 | parameters: 模型参数,max_norm 最大梯度范数 |
|
||||
with torch.no_grad(): | 禁用梯度计算,节省内存(常用于推理或评估) | 无参数 |
|
||||
2. 代码示例
|
||||
```python
|
||||
# 添加学习率调度器和梯度裁剪
|
||||
scheduler = torch.optim.StepLR(optimizer, step_size=30, gamma=0.1)
|
||||
gradient_clip = 5.0
|
||||
|
||||
for epoch in range(num_epochs):
|
||||
model.train()
|
||||
for inputs, labels in dataloader:
|
||||
inputs, labels = inputs.to(device), labels.to(device)
|
||||
|
||||
# 前向传播
|
||||
outputs = model(inputs)
|
||||
loss = criterion(outputs, labels)
|
||||
|
||||
# 反向传播 + 梯度裁剪 + 参数更新
|
||||
optimizer.zero_grad()
|
||||
loss.backward()
|
||||
torch.nn.utils.clip_grad_norm_(model.parameters(), gradient_clip)
|
||||
optimizer.step()
|
||||
|
||||
# 动态调整学习率
|
||||
scheduler.step()
|
||||
|
||||
# 验证集评估(自定义逻辑)
|
||||
if batch_idx % 100 == 0:
|
||||
validate(model, val_dataloader, criterion)
|
||||
```
|
||||
#### 关键的参数
|
||||
1. DataLoader 参数
|
||||
```python
|
||||
DataLoader(
|
||||
dataset=MyDataset(),
|
||||
batch_size=64, # 批量大小
|
||||
shuffle=True, # 训练时打乱数据顺序
|
||||
num_workers=4, # 多线程加载数据
|
||||
pin_memory=True # GPU 数据传输加速
|
||||
)
|
||||
```
|
||||
#### 高级技巧
|
||||
1. 混合精度训练(Mixed Precision Training)
|
||||
```python
|
||||
# 混合精度训练
|
||||
scaler = torch.cuda.amp.GradScaler()
|
||||
model, optimizer = amp.initialize(model, optimizer, opt_level="O1")
|
||||
|
||||
for epoch in range(num_epochs):
|
||||
model.train()
|
||||
for inputs, labels in dataloader:
|
||||
inputs, labels = inputs.to(device), labels.to(device)
|
||||
|
||||
# 前向传播
|
||||
with torch.cuda.amp.autocast():
|
||||
outputs = model(inputs)
|
||||
loss = criterion(outputs, labels)
|
||||
|
||||
# 反向传播和优化
|
||||
optimizer.zero_grad()
|
||||
scaler.scale(loss).backward()
|
||||
scaler.step(optimizer)
|
||||
scaler.update()
|
||||
```
|
||||
2. 分布式训练(Distributed Training)
|
||||
```python
|
||||
# 分布式训练
|
||||
torch.distributed.init_process_group(backend='nccl')
|
||||
model = model.to(device)
|
||||
model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[device])
|
||||
|
||||
for epoch in range(num_epochs):
|
||||
model.train()
|
||||
for inputs, labels in dataloader:
|
||||
inputs, labels = inputs.to(device), labels.to(device)
|
||||
|
||||
# 前向传播
|
||||
outputs = model(inputs)
|
||||
loss = criterion(outputs, labels)
|
||||
|
||||
# 反向传播和优化
|
||||
optimizer.zero_grad()
|
||||
loss.backward()
|
||||
optimizer.step()
|
||||
```
|
||||
3. 梯度检查点(Gradient Checkpointing)
|
||||
```python
|
||||
# 梯度检查点
|
||||
from torch.utils.checkpoint import checkpoint
|
||||
|
||||
for epoch in range(num_epochs):
|
||||
model.train()
|
||||
for inputs, labels in dataloader:
|
||||
inputs, labels = inputs.to(device), labels.to(device)
|
||||
|
||||
# 前向传播
|
||||
def forward(inputs):
|
||||
return model(inputs)
|
||||
|
||||
outputs = checkpoint(forward, inputs)
|
||||
|
||||
# 反向传播和优化
|
||||
optimizer.zero_grad()
|
||||
loss = criterion(outputs, labels)
|
||||
loss.backward()
|
||||
optimizer.step()
|
||||
```
|
||||
### 模型评估
|
||||
```python
|
||||
import torch
|
||||
from sklearn.metrics import classification_report
|
||||
|
||||
def run_evaluation(model, test_loader, class_names):
|
||||
model.eval()
|
||||
all_preds = []
|
||||
all_labels = []
|
||||
|
||||
with torch.no_grad():
|
||||
for inputs, labels in test_loader:
|
||||
outputs = model(inputs)
|
||||
preds = torch.argmax(outputs, dim=1)
|
||||
|
||||
all_preds.extend(preds.cpu().numpy())
|
||||
all_labels.extend(labels.cpu().numpy())
|
||||
|
||||
# 打印报告
|
||||
print(classification_report(all_labels, all_preds, target_names=class_names))
|
||||
|
||||
# 返回字典格式结果
|
||||
return {
|
||||
'accuracy': sum(p == l for p, l in zip(all_preds, all_labels)) / len(all_labels),
|
||||
'classification_report': classification_report(all_labels, all_preds, target_names=class_names)
|
||||
}
|
||||
```
|
||||
### 模型保存与加载
|
||||
```python
|
||||
# 保存模型
|
||||
torch.save(model.state_dict(), 'model.pth')
|
||||
|
||||
# 加载模型
|
||||
model = YourModelClass()
|
||||
model.load_state_dict(torch.load('model.pth'))
|
||||
model.eval()
|
||||
```
|
419
teach_Tensorflow.md
Normal file
419
teach_Tensorflow.md
Normal file
@ -0,0 +1,419 @@
|
||||
# 深度学习的实现
|
||||
## 在TensorFlow中实现
|
||||
|
||||
```python
|
||||
import numpy as np
|
||||
import tensorflow as tf
|
||||
from keras import layers, models
|
||||
from keras.datasets import mnist
|
||||
from keras.utils import to_categorical
|
||||
# 加载MNIST数据集
|
||||
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
|
||||
|
||||
# 数据预处理
|
||||
train_images = train_images.reshape((60000, 28 * 28)).astype('float32') / 255
|
||||
test_images = test_images.reshape((10000, 28 * 28)).astype('float32') / 255
|
||||
|
||||
train_labels = to_categorical(train_labels)
|
||||
test_labels = to_categorical(test_labels)
|
||||
|
||||
# 定义模型
|
||||
model = models.Sequential()
|
||||
model.add(layers.Dense(64, activation='relu', input_shape=(28 * 28,)))
|
||||
model.add(layers.Dense(10, activation='softmax')) # 注意这里需要指定输出层的神经元数量
|
||||
|
||||
# 编译模型
|
||||
optimizer = tf.keras.optimizers.Adam() # 正确的导入方式
|
||||
loss = 'categorical_crossentropy'
|
||||
metrics = ['accuracy']
|
||||
model.compile(optimizer=optimizer, loss=loss, metrics=metrics)
|
||||
|
||||
# 训练模型
|
||||
model.fit(train_images, train_labels, epochs=5, batch_size=32)
|
||||
|
||||
# 评估模型
|
||||
test_loss, test_acc = model.evaluate(test_images, test_labels)
|
||||
print(f"Test accuracy: {test_acc}")
|
||||
|
||||
# 保存模型
|
||||
model.save('my_model.h5')
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
### 在TensorFlow中实现深度学习需要以下步骤:
|
||||
`数据准备 → 模型定义 → 编译 → 训练(自动/自定义) → 评估 → 保存/部署`
|
||||
|
||||
### 模型的定义
|
||||
- 在深度学习中,模型定义(Model Definition) 是构建神经网络的核心步骤,目的是明确模型的结构和数据流动方式。它决定了神经网络由哪些层组成、层与层之间如何连接,以及每层的计算逻辑。可以类比为设计一栋建筑的蓝图,需要明确房间(层)的布局、连接方式(数据流)和每个房间的功能(层的计算规则)。
|
||||
- 模型定义的三个核心问题
|
||||
- 模型的结构是什么?
|
||||
- 有多少层?每一层的类型(全连接层、卷积层等)是什么?
|
||||
- 层之间如何连接?
|
||||
- 是简单的线性堆叠(如Sequential模型),还是存在分支、跳跃连接等复杂拓扑?
|
||||
- 每层具体做什么?
|
||||
- 每层的参数(如神经元数量、滤波器大小)、激活函数、正则化方法等。
|
||||
- TensorFlow(尤其是其高层 API `tf.keras`)提供了多种定义模型的方法。
|
||||
- Sequential模型:适用于简单的线性堆叠结构,即每一层直接连接到下一层。
|
||||
```python
|
||||
import tensorflow as tf
|
||||
from tensorflow.keras import layers, models
|
||||
|
||||
# 定义模型
|
||||
model = models.Sequential() #创建了一个Sequential模型。Sequential模型允许我们一层一层地构建网络,每层都是顺序堆叠的。
|
||||
|
||||
model.add(layers.Dense(64, activation='relu', input_shape=(784,)))
|
||||
#添加第一个全连接层(Dense)到模型中:该层有64个神经元。使用的激活函数是ReLU(Rectified Linear Unit),它是一种常用的非线性激活函数。指定输入数据的形状。这里假设输入数据是784个特征,这对应于一个28x28像素的图像展平后的结果。
|
||||
|
||||
model.add(layers.Dense(64, activation='relu'))
|
||||
#添加第二个全连接层:这个层同样有64个神经元,并且使用ReLU激活函数。由于这是第二个层,不需要指定输入形状,因为它自动从上一层获取。
|
||||
|
||||
model.add(layers.Dense(10, activation='softmax'))
|
||||
#最后一个全连接层:这个层有10个神经元,通常用于分类任务,每个神经元对应一个类别。使用softmax激活函数,它将神经元的输出转换为概率分布,总和为1。它可以解释为每个类别的预测概率。
|
||||
```
|
||||
- 函数式API:适用于更复杂的模型结构,如非顺序的层连接、共享层、多输入多输出模型等。
|
||||
- 适用场景:复杂模型(多输入/输出、分支、跳跃连接、共享层)。
|
||||
- 特点:显式定义输入和输出,灵活构建层间连接关系。
|
||||
- 代码示例(多输入模型):
|
||||
```python
|
||||
# 定义输入层
|
||||
input1 = tf.keras.Input(shape=(32,), name="input_1")
|
||||
input2 = tf.keras.Input(shape=(64,), name="input_2")
|
||||
|
||||
# 合并两个输入
|
||||
concatenated = tf.keras.layers.Concatenate()([input1, input2])
|
||||
|
||||
# 定义中间层
|
||||
x = tf.keras.layers.Dense(128, activation='relu')(concatenated)
|
||||
x = tf.keras.layers.Dropout(0.5)(x)
|
||||
|
||||
# 定义输出层
|
||||
output = tf.keras.layers.Dense(1, activation='sigmoid')(x)
|
||||
|
||||
# 创建模型
|
||||
model = tf.keras.Model(inputs=[input1, input2], outputs=output)`
|
||||
```
|
||||
- 子类化API:适用于需要完全控制模型结构和训练过程的场景,可以自定义前向传播逻辑和训练循环。
|
||||
- 适用场 景:需要完全自定义的模型(如动态计算图、自定义前向逻辑)。
|
||||
- 特点:通过继承 tf.keras.Model 类,自由定义前向传播逻辑。适用于需要高度自定义的模型结构。
|
||||
- 代码示例(自定义模型):
|
||||
```python
|
||||
class CustomModel(tf.keras.Model):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
# 定义层
|
||||
self.dense1 = tf.keras.layers.Dense(64, activation='relu')
|
||||
self.dropout = tf.keras.layers.Dropout(0.2)
|
||||
self.dense2 = tf.keras.layers.Dense(10, activation='softmax')
|
||||
|
||||
def call(self, inputs, training=False):
|
||||
# 自定义前向传播逻辑
|
||||
x = self.dense1(inputs)
|
||||
if training: # 仅在训练时使用Dropout
|
||||
x = self.dropout(x)
|
||||
return self.dense2(x)
|
||||
|
||||
# 实例化模型并构建
|
||||
model = CustomModel()
|
||||
model.build(input_shape=(None, 784)) # 指定输入形状
|
||||
```
|
||||
- 优点:
|
||||
- 完全控制模型逻辑(如条件分支、循环操作)。
|
||||
- 支持动态计算(如根据输入数据调整结构)。
|
||||
- 缺点:
|
||||
- 代码复杂度高,需手动管理层和参数。
|
||||
- 模型结构不易可视化(如model.summary()需先调用build)。
|
||||
- 中间层都有不同的类型,例如:
|
||||
- Dense层:全连接层,每个神经元与前一层的所有神经元相连。
|
||||
- Dropout层:在训练过程中随机丢弃一部分神经元,以防止过拟合。
|
||||
- Flatten层:将输入展平为一维向量,通常用于从卷积层到全连接层的转换。
|
||||
- Conv2D层:二维卷积层,用于处理图像数据。
|
||||
- MaxPooling2D层:最大池化层,用于降低特征图的维度。
|
||||
- BatchNormalization层:批量归一化层,用于加速训练并提高模型的稳定性。
|
||||
- Activation层:激活函数层,用于引入非线性变换。
|
||||
|
||||
- activation里面指的是使用什么激活函数,比如relu、sigmoid、softmax等
|
||||
|
||||
| 任务类型 | 推荐激活函数 | 理由 |
|
||||
|------------------|----------------|--------------------------------|
|
||||
| 二分类输出层 | Sigmoid、Softmax | 输出概率形式。 |
|
||||
| 多分类输出层 | Softmax | 强制归一化为概率分布。 |
|
||||
| 隐藏层(通用) | ReLU、Leaky ReLU、Swish | 平衡性能与计算效率。 |
|
||||
| RNN/序列模型 | Tanh、ELU | 稳定梯度传播,缓解长程依赖问题。|
|
||||
| 需要平滑输出 | Softsign、Softmax | 输出连续且可解释。 |
|
||||
| 嵌入式设备 | Hard Sigmoid、ReLU6 | 计算快速,硬件友好。 |
|
||||
详情请见[激活函数](./激活函数.md)
|
||||
|
||||
### 模型的编译
|
||||
- 在TensorFlow中,编译阶段的核心API是 tf.keras.Model.compile(),它允许你配置模型的训练参数。
|
||||
- **1.核心API:model.compile()**
|
||||
```python
|
||||
optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
|
||||
loss = SparseCategoricalCrossentropy(from_logits=True)
|
||||
model.compile(
|
||||
optimizer=optimizer,
|
||||
loss=loss,
|
||||
metrics=['accuracy'], #模型评估时使用的指标列表,在 model.fit() 的输出中,会实时显示这些指标的训练/验证值。model.evaluate() 会返回所有指标的值。
|
||||
|
||||
# 其他可选参数
|
||||
)
|
||||
```
|
||||
| 参数 | 说明 |
|
||||
| ------------ | ------------------------------------------------ |
|
||||
| optimizer | 优化器对象(字符串或实例),控制梯度下降策略。 |
|
||||
| loss | 损失函数(字符串、可调用对象或损失类实例)。 |
|
||||
| metrics | 评估指标列表(字符串、可调用对象或指标类实例)。 |
|
||||
| loss_weights | 字典或列表,为不同输出指定损失权重。 |
|
||||
| run_eagerly | 布尔值,启用急切执行模式(默认False)。 |
|
||||
|
||||
- **2.优化器(optimizer)**
|
||||
- 优化器决定了模型如何更新其参数以最小化损失函数。具体请见[优化器](./Tensorflow的优化器.md)。
|
||||
|
||||
- **3.损失函数(loss)**
|
||||
- 损失函数衡量模型预测值与真实值之间的差异。具体请见[损失函数](./Tensorflow的损失函数.md)。
|
||||
|
||||
### 模型的训练
|
||||
- 在TensorFlow中训练深度学习模型的核心API可分为以下几类:
|
||||
|
||||
#### **1. 自动训练 API**
|
||||
- **`model.fit()`**
|
||||
- **作用**: 简化训练流程,自动处理数据迭代、前向传播、反向传播和参数更新。
|
||||
- **示例**:
|
||||
```python
|
||||
model.fit(train_dataset, epochs=10, validation_data=val_dataset,
|
||||
callbacks=[TensorBoard(log_dir='./logs')])
|
||||
```
|
||||
- **关键参数**: `epochs`, `batch_size`, `validation_split`, `callbacks`。
|
||||
1. `epochs`(训练轮数)**
|
||||
- **定义**: 每次遍历全部训练数据称为一个 Epoch。
|
||||
- **目的**: 控制模型的学习次数,防止欠拟合(训练不足)或过拟合(训练过度)。
|
||||
- **调整策略**
|
||||
- **推荐范围**:
|
||||
- 初期实验: `5~50`(根据数据量调整)。
|
||||
- 复杂任务(如 ImageNet): `100~300`。
|
||||
- **注意**:
|
||||
- 数据量小时(如 MNIST),`epochs=10~20` 可能已过拟合。
|
||||
- 使用 **早停回调**(`EarlyStopping`)动态终止训练。
|
||||
- 示例:
|
||||
```python
|
||||
model.fit(..., epochs=100, callbacks=[EarlyStopping(patience=10)])
|
||||
```
|
||||
**“数据不够,正则来凑;模型太深,Dropout 伺候;早停法防过拟,Epoch 要看数据够不够!”**
|
||||
2. `batch_size`(批量大小
|
||||
- **定义**: 每次梯度更新使用的样本数量。
|
||||
- **影响**:
|
||||
- **内存消耗**: `batch_size` 越大,占用的 GPU/TPU 内存越多。
|
||||
- **收敛速度**: 较大的 `batch_size` 可能加速训练,但梯度更新更粗糙。
|
||||
- **泛化性能**: 小批量(如 32~128)通常泛化效果更好。
|
||||
- **默认值**
|
||||
- `32`
|
||||
- **调整策略**
|
||||
- **硬件限制**:
|
||||
- GPU 内存充足时,可尝试 `batch_size=256` 或更大。
|
||||
- 内存不足时,降低至 `batch_size=16` 或 `32`。
|
||||
- **经验规则**:
|
||||
- **小批量**: `32~128`(适合大多数场景,平衡速度与泛化)。
|
||||
- **大批量**: `256~1024`(需搭配学习率调整,如线性 warmup)。
|
||||
- **示例**:
|
||||
```python
|
||||
model.fit(..., batch_size=64) # 使用 64 个样本更新一次权重
|
||||
```
|
||||
|
||||
- ##### **高级技巧**
|
||||
- **动态调整**: 使用 `tf.data.Dataset` 的 `prefetch` 和 `cache` 加速数据管道。
|
||||
|
||||
3. `validation_split`(验证集划分比例)**
|
||||
- **功能**: 在训练数据中按比例自动划分验证集,无需手动拆分 `X_train` 和 `y_train`。
|
||||
- **默认值**: `0.0`(不划分验证集)。
|
||||
- **调整策略**
|
||||
- **推荐值**:
|
||||
- `0.1`~`0.2`(常用 20% 数据作为验证集)。
|
||||
- **适用场景**:
|
||||
- **小型数据集**: 避免划分过多验证数据导致训练不足。
|
||||
- **大型数据集**: 可结合 `validation_data` 参数指定独立验证集。
|
||||
- **示例**:
|
||||
```python
|
||||
model.fit(..., validation_split=0.2) # 20% 训练数据作为验证集
|
||||
```
|
||||
4. `callbacks`(回调函数列表)**
|
||||
|
||||
- **功能**: 在训练过程中插入自定义操作(如保存模型、监控指标、动态调整参数)。
|
||||
- **默认值**: `None`(不启用任何回调)。
|
||||
|
||||
- **常用回调及场景**
|
||||
|
||||
| 回调类 | 作用 | 示例代码 |
|
||||
|-----------------------|---------------------------------------|-------------------------------------------|
|
||||
| `ModelCheckpoint` | 保存最佳模型 | `ModelCheckpoint('best_model.keras', save_best_only=True)` |
|
||||
| `EarlyStopping` | 根据验证指标提前终止训练 | `EarlyStopping(monitor='val_loss', patience=3)` |
|
||||
| `TensorBoard` | 可视化训练过程 | `TensorBoard(log_dir='./logs')` |
|
||||
| `ReduceLROnPlateau` | 动态降低学习率(当指标不再提升时) | `ReduceLROnPlateau(factor=0.1, patience=2)` |
|
||||
| `CSVLogger` | 记录训练日志到 CSV 文件 | `CSVLogger('training.log')` |
|
||||
- **自定义回调**
|
||||
- **实现方式**: 继承 `tf.keras.callbacks.Callback` 类并重写 `on_epoch_end` 等方法。
|
||||
```python
|
||||
class CustomCallback(tf.keras.callbacks.Callback):
|
||||
def on_epoch_end(self, epoch, logs=None):
|
||||
print(f"Epoch {epoch}: Custom action here")
|
||||
```
|
||||
- **参数综合配置示例**
|
||||
```python
|
||||
model.fit(
|
||||
train_dataset,
|
||||
epochs=100,
|
||||
batch_size=64,
|
||||
validation_split=0.2,
|
||||
callbacks=[
|
||||
EarlyStopping(monitor='val_loss', patience=10),
|
||||
ModelCheckpoint('best_model.keras', save_best_only=True),
|
||||
TensorBoard(log_dir='./logs')
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
#### **2. 自定义训练控制**
|
||||
- 自定义训练控制的核心逻辑
|
||||
- 1. 继承 tf.keras.Model 类
|
||||
- Keras 的 Model 类封装了神经网络的前向传播、损失计算、梯度更新等核心逻辑。通过继承它,保留这些自动化功能,同时插入自定义代码。
|
||||
|
||||
- 关键方法:
|
||||
- `__init__`: 初始化模型结构(如层)。
|
||||
- `call(self, inputs, training=None)`: 定义前向传播逻辑。
|
||||
- `train_step(self, data)`: 重写此方法以控制单步训练流程。
|
||||
- 2. 重写 train_step 方法
|
||||
- 默认行为:
|
||||
```txt
|
||||
1. 执行前向传播(self.call())
|
||||
2. 计算损失(self.compiled_loss)
|
||||
3. 记录梯度(tf.GradientTape)
|
||||
4. 应用优化器(self.optimizer.apply_gradients)
|
||||
5. 更新指标(self.metrics.update_state)
|
||||
```
|
||||
- 自定义点:
|
||||
- 在重写时,可以插入额外操作(如梯度裁剪、动态权重更新、自定义损失计算)。
|
||||
---
|
||||
|
||||
#### **3. 分布式训练**
|
||||
- **`tf.distribute` 模块**
|
||||
- **作用**: 在多设备(GPU/TPU)或多节点上并行训练。
|
||||
- **常用策略**:
|
||||
◦ `MirroredStrategy`: 单机多GPU同步训练。
|
||||
```python
|
||||
strategy = tf.distribute.MirroredStrategy()
|
||||
with strategy.scope():
|
||||
model = build_model()
|
||||
```
|
||||
◦ `MultiWorkerMirroredStrategy`: 多机多GPU异步训练。
|
||||
|
||||
---
|
||||
|
||||
#### **4. 高级训练工具**
|
||||
- **`tf.keras.callbacks`**
|
||||
- **作用**: 在训练过程中注入额外操作(如保存模型、早停、可视化)。
|
||||
- **常用回调类**:
|
||||
◦ `ModelCheckpoint`: 保存最佳模型。
|
||||
◦ `EarlyStopping`: 根据验证指标提前终止训练。
|
||||
◦ `TensorBoard`: 可视化训练过程。
|
||||
- **示例**:
|
||||
- ```python
|
||||
callbacks = [
|
||||
ModelCheckpoint('best_model.keras', save_best_only=True),
|
||||
EarlyStopping(monitor='val_loss', patience=3)
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
#### **5. 数据管道优化**
|
||||
- **`tf.data.Dataset` API**
|
||||
- **作用**: 高效加载和处理数据,支持并行数据预处理和缓存。
|
||||
- **常用方法**:
|
||||
◦ `map()`: 并行应用数据转换函数。
|
||||
◦ `shuffle()`: 打乱数据顺序。
|
||||
◦ `batch()`: 分批次处理数据。
|
||||
- **示例**:
|
||||
- ```python
|
||||
dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
|
||||
dataset = dataset.shuffle(buffer_size=10000).batch(32).prefetch(tf.data.AUTOTUNE)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### **总结表**
|
||||
| **API** | **用途** | **典型场景** |
|
||||
|------------------------|------------------------------|--------------------------------|
|
||||
| `model.fit()` | 自动训练流程 | 快速原型开发 |
|
||||
| `model.train_step()` | 自定义单步训练逻辑 | 特殊损失函数或梯度操作 |
|
||||
| `tf.distribute` | 多设备/多节点分布式训练 | 大规模模型或硬件资源充足的环境 |
|
||||
| `tf.keras.callbacks` | 训练过程增强 | 模型保存、早停、可视化 |
|
||||
| `tf.data.Dataset` | 数据加载与预处理 | 高效数据管道构建 |
|
||||
|
||||
### 模型的评估
|
||||
#### **1. 核心评估API**
|
||||
##### **(1) `model.evaluate()`**
|
||||
- **功能**:对模型在指定数据集上的性能进行综合评估。
|
||||
- **示例**:
|
||||
```python
|
||||
# 假设 model 是已编译的模型,test_dataset 是测试数据集
|
||||
results = model.evaluate(test_dataset, verbose=2)
|
||||
print(f"Test loss: {results[0]}, Test accuracy: {results[1]}")
|
||||
```
|
||||
- **参数**:
|
||||
- `x`/`y`:输入数据和标签(适用于小批量数据)。
|
||||
- `dataset`:`tf.data.Dataset`对象(推荐大数据集)。
|
||||
- `callbacks`:训练回调函数(如TensorBoard)。
|
||||
- `verbose`:控制输出详细程度。
|
||||
|
||||
---
|
||||
|
||||
#### **2. 预定义评估指标**
|
||||
TensorFlow内置了多种评估指标,可直接在模型编译或单独调用中使用。
|
||||
|
||||
##### **(1) 在模型编译中添加指标**
|
||||
```python
|
||||
from tensorflow.keras import metrics
|
||||
|
||||
model.compile(
|
||||
optimizer='adam',
|
||||
loss='sparse_categorical_crossentropy',
|
||||
metrics=[metrics.Accuracy(), metrics.Precision(name='precision'), metrics.Recall(name='recall')]
|
||||
)
|
||||
```
|
||||
- **常用指标**:
|
||||
- `Accuracy`(准确率)
|
||||
- `Precision`(精确率)
|
||||
- `Recall`(召回率)
|
||||
- `AUC`(ROC曲线下面积)
|
||||
- `MeanSquaredError`(均方误差)
|
||||
|
||||
##### **(2) 单独计算指标**
|
||||
通过`tf.keras.metrics`动态计算指标:
|
||||
```python
|
||||
# 计算预测结果
|
||||
predictions = model.predict(test_dataset, verbose=0)
|
||||
|
||||
# 计算准确率
|
||||
accuracy = metrics.Accuracy()
|
||||
accuracy.update_state(y_true, y_pred)
|
||||
print(f"Custom Accuracy: {accuracy.result().numpy()}")
|
||||
```
|
||||
|
||||
|
||||
#### Keras 是什么?
|
||||
- Keras 是一个高级神经网络API,最初由 François Chollet 于2015年独立开发,旨在简化深度学习模型的构建和训练过程。2017年,TensorFlow 官方将其整合为 tf.keras,成为 TensorFlow 的核心高阶接口。他的优势是:
|
||||
- 提供直观的接口(如 Sequential 和 Functional API),无需手动编写复杂的前向传播或反向传播代码。
|
||||
- 内置大量预训练模型和预训练权重,方便迁移学习和微调。
|
||||
- 支持多种硬件加速,包括 GPU 和 TPU。
|
||||
- 模型训练和评估的代码简洁易读,便于调试和优化。
|
||||
|
||||
#### Keras 的核心概念
|
||||
- 模型(Model):神经网络的基本结构,可以是顺序模型(Sequential)或函数式模型(Functional)。
|
||||
- 层(Layer):神经网络的基本单元,如全连接层(Dense)、卷积层(Conv2D)、池化层(MaxPooling2D)等。
|
||||
- 激活函数(Activation Function):引入非线性,如 ReLU、sigmoid、softmax 等。
|
||||
- 损失函数(Loss Function):衡量模型预测与真实值之间的差异,如均方误差(MSE)、交叉熵(Cross-Entropy)等。
|
||||
- 优化器(Optimizer):调整模型参数以最小化损失函数,如 SGD、Adam、RMSprop 等。
|
||||
|
||||
|
206
激活函数.md
Normal file
206
激活函数.md
Normal file
@ -0,0 +1,206 @@
|
||||
### **1. 传统激活函数**
|
||||
#### **(1) Sigmoid**
|
||||
• **公式**:
|
||||
$$\
|
||||
\sigma(x) = \frac{1}{1 + e^{-x}}
|
||||
\ $$
|
||||
• **输出范围**:`(0, 1)`
|
||||
• **特点**:
|
||||
• 将输入压缩到概率区间,常用于二分类输出层。
|
||||
• **缺点**:
|
||||
◦ 梯度消失问题(输入绝对值较大时,导数趋近于0)。
|
||||
◦ 计算复杂,不适合深层网络。
|
||||
• **代码示例**:
|
||||
```python
|
||||
layers.Dense(64, activation='sigmoid')
|
||||
```
|
||||
|
||||
#### **(2) Tanh(双曲正切函数)**
|
||||
• **公式**:
|
||||
$$\
|
||||
\tanh(x) = \frac{e^{x} - e^{-x}}{e^{x} + e^{-x}} = \frac{e^{2x}}{e^{2x} + 1} - 1
|
||||
\ $$
|
||||
• **输出范围**:`(-1, 1)`
|
||||
• **特点**:
|
||||
• 输出对称分布,中心化数据更易训练。
|
||||
• 梯度消失问题仍存在,但比 Sigmoid 好。
|
||||
• **适用场景**:
|
||||
• 循环神经网络(RNN)、双向 LSTM。
|
||||
• **代码示例**:
|
||||
```python
|
||||
layers.LSTM(128, activation='tanh')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **2. 改进型 ReLU 系列**
|
||||
#### **(1) Leaky ReLU**
|
||||
• **公式**:
|
||||
$$\
|
||||
f(x) = \begin{cases}
|
||||
x & \text{if } x > 0 \\
|
||||
\alpha x & \text{if } x \leq 0
|
||||
\end{cases}
|
||||
\ $$
|
||||
• \( \alpha \):泄漏系数(通常取 `0.1`)。
|
||||
• **特点**:
|
||||
• 解决 ReLU 的“死亡神经元”问题,允许负值区域有微小梯度。
|
||||
• **代码示例**:
|
||||
```python
|
||||
class LeakyReLU(tf.keras.layers.Layer):
|
||||
def __init__(self, alpha=0.1, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.alpha = alpha
|
||||
def call(self, inputs):
|
||||
return tf.maximum(inputs, self.alpha * inputs)
|
||||
|
||||
model.add(LeakyReLU(alpha=0.2))
|
||||
```
|
||||
|
||||
#### **(2) Parametric ReLU(PReLU)**
|
||||
• **公式**:
|
||||
$$\
|
||||
f(x) = \max(0, x + a \cdot x)
|
||||
\ $$
|
||||
• \( a \):可学习的参数(而非固定系数)。
|
||||
• **特点**:
|
||||
• 自动调整负区间的斜率,增强模型表达能力。
|
||||
• **代码示例**:
|
||||
```python
|
||||
from tensorflow.keras.layers import PReLU
|
||||
model.add(PReLU())
|
||||
```
|
||||
|
||||
#### **(3) ELU(指数线性单元)**
|
||||
• **公式**:
|
||||
$$\
|
||||
f(x) = \begin{cases}
|
||||
x & \text{if } x > 0 \\
|
||||
\alpha (e^{x} - 1) & \text{if } x \leq 0
|
||||
\end{cases}
|
||||
\ $$
|
||||
• \( \alpha \):平滑系数(通常取 `1`)。
|
||||
• **特点**:
|
||||
• 在负区间输出平滑曲线,减少梯度噪声。
|
||||
• **代码示例**:
|
||||
```python
|
||||
layers.ELU(alpha=1.0)
|
||||
```
|
||||
|
||||
#### **(4) Swish**
|
||||
• **公式**:
|
||||
$$\
|
||||
f(x) = x \cdot \sigma(x) = \frac{x}{1 + e^{-x}}
|
||||
\ $$
|
||||
• **特点**:
|
||||
• 自动归一化输出,类似于 Sigmoid,但梯度更平滑。
|
||||
• 在 Google 的多项任务中表现优异。
|
||||
• **代码示例**:
|
||||
```python
|
||||
layers.Swish()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **3. 平滑型激活函数**
|
||||
#### **(1) Softmax**
|
||||
• **公式**:
|
||||
$$\
|
||||
\text{Softmax}(x_i) = \frac{e^{x_i}}{\sum_{j} e^{x_j}}
|
||||
\ $$
|
||||
• **输出范围**:`(0, 1)`(概率分布)。
|
||||
• **特点**:
|
||||
• 常用于多分类输出层,强制输出为概率形式。
|
||||
• **代码示例**:
|
||||
```python
|
||||
layers.Dense(10, activation='softmax')
|
||||
```
|
||||
|
||||
#### **(2) Softsign**
|
||||
• **公式**:
|
||||
$$\
|
||||
f(x) = \frac{x}{1 + |x|}
|
||||
\ $$
|
||||
• **输出范围**:`(-1, 1)`。
|
||||
• **特点**:
|
||||
• 输出对称且平滑,比 Sigmoid 计算更快。
|
||||
• **代码示例**:
|
||||
```python
|
||||
layers.Softsign()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **4. 循环网络专用激活函数**
|
||||
#### **(1) Tanh(已介绍)**
|
||||
• **适用场景**:
|
||||
• RNN、LSTM、GRU 的隐藏层,输出范围 `(-1, 1)` 有助于稳定训练。
|
||||
|
||||
#### **(2) Hard Sigmoid**
|
||||
• **公式**:
|
||||
$$\
|
||||
f(x) = \max(0, \min(1, \frac{x + 1}{2}))
|
||||
\ $$
|
||||
• **特点**:
|
||||
• 计算高效,近似 Sigmoid,常用于嵌入式设备。
|
||||
|
||||
---
|
||||
|
||||
### **5. 其他特殊激活函数**
|
||||
#### **(1) Softmax Cross-Entropy with Logits**
|
||||
• **公式**:
|
||||
$$\
|
||||
H(y, \hat{y}) = -\sum_{i} y_i \log(\hat{y}_i)
|
||||
\ $$
|
||||
• **特点**:
|
||||
• 结合 Softmax 和交叉熵,数值稳定且高效。
|
||||
• **代码示例**:
|
||||
```python
|
||||
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy')
|
||||
```
|
||||
|
||||
#### **(2) SiLU(Sigmoid Linear Unit)**
|
||||
• **公式**:
|
||||
$$\
|
||||
f(x) = x \cdot \sigma(x)
|
||||
\ $$
|
||||
• **特点**:
|
||||
• 线性和非线性的平滑结合,类似 Swish。
|
||||
|
||||
---
|
||||
|
||||
### **6. 激活函数选择指南**
|
||||
| **任务类型** | **推荐激活函数** | **理由** |
|
||||
|--------------------|--------------------------------------|----------------------------------------|
|
||||
| **二分类输出层** | Sigmoid、Softmax | 输出概率形式。 |
|
||||
| **多分类输出层** | Softmax | 强制归一化为概率分布。 |
|
||||
| **隐藏层(通用)** | ReLU、Leaky ReLU、Swish | 平衡性能与计算效率。 |
|
||||
| **RNN/序列模型** | Tanh、ELU | 稳定梯度传播,缓解长程依赖问题。 |
|
||||
| **需要平滑输出** | Softsign、Softmax | 输出连续且可解释。 |
|
||||
| **嵌入式设备** | Hard Sigmoid、ReLU6 | 计算快速,硬件友好。 |
|
||||
|
||||
---
|
||||
|
||||
### **7. 高级技巧**
|
||||
#### **(1) 自定义激活函数**
|
||||
```python
|
||||
class CustomActivation(tf.keras.layers.Layer):
|
||||
def __init__(self, name='custom_act', **kwargs):
|
||||
super().__init__(name=name, **kwargs)
|
||||
|
||||
def call(self, inputs):
|
||||
return tf.nn.relu(inputs) * 0.5 + 0.5 # 示例:缩放 ReLU
|
||||
|
||||
model.add(CustomActivation())
|
||||
```
|
||||
|
||||
#### **(2) 混合激活函数**
|
||||
在复杂模型中,不同层使用不同激活函数(如 CNN 使用 ReLU,RNN 使用 Tanh)。
|
||||
|
||||
---
|
||||
|
||||
### **总结**
|
||||
• **ReLU 及其变种**(如 Leaky ReLU、Swish)是大多数深层网络的首选。
|
||||
• **Sigmoid/Tanh** 适用于特定场景(如分类输出层、循环网络)。
|
||||
• **平滑函数**(如 Softmax)在需要概率输出时必不可少。
|
||||
• 根据任务需求、数据分布和网络结构灵活选择激活函数,并通过实验验证效果。
|
Loading…
x
Reference in New Issue
Block a user