### **Day 1: 深度学习基础——什么是神经网络?**
#### **1. 核心概念**
- **神经网络**:一种模仿生物神经系统(如大脑)的计算模型,由多个“神经元”组成,用于从数据中学习模式。
- **神经元**:神经网络的基本单元,接收输入信号,进行加权求和并通过激活函数输出结果。
- **层(Layer)**:
- **输入层**:接收原始数据(如图像像素、文本向量)。
- **隐藏层**:通过权重和激活函数提取特征。
- **输出层**:生成最终结果(如分类标签、回归值)。
#### **2. 数学表示**
- 一个神经元的输出可以表示为:
\[
y = f\left(\sum_{i=1}^n w_i x_i + b\right)
\]
- \(x_i\):输入值
- \(w_i\):权重
- \(b\):偏置
- \(f\):激活函数(如ReLU、Sigmoid)
#### **3. 激活函数的作用**
- **ReLU(Rectified Linear Unit)**:
\[
f(x) = \max(0, x)
\]
- 优点:计算简单,缓解梯度消失问题。
- **Sigmoid**:
\[
f(x) = \frac{1}{1 + e^{-x}}
\]
- 优点:输出范围(0,1),适合二分类问题。
#### **4. 简单代码示例(Python + PyTorch)**
```python
import torch
import torch.nn as nn
# 定义一个简单的神经网络
class SimpleNN(nn.Module):
def __init__(self):
super(SimpleNN, self).__init__()
self.fc1 = nn.Linear(10, 5) # 输入10维,输出5维
self.relu = nn.ReLU() # 激活函数
self.fc2 = nn.Linear(5, 1) # 输出1维(如回归值)
def forward(self, x):
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
return x
# 初始化模型
model = SimpleNN()
# 输入数据(10维向量)
input_data = torch.randn(1, 10) # 1个样本,10个特征
output = model(input_data)
print(output)
```
#### **5. 今日任务**
1. **理解神经元的工作原理**:尝试手动计算一个神经元的输出(给定输入、权重、偏置和激活函数)。
2. **运行代码**:安装PyTorch并运行上述代码,观察输出结果。
3. **扩展思考**:如果增加隐藏层的神经元数量,模型会有什么变化?
---
当然可以!激活函数是神经网络中非常重要的组成部分,它的作用不仅仅是简单地将输入信号传递到下一层,而是赋予神经网络**非线性能力**,使其能够学习复杂的模式。下面我会详细解释激活函数的作用、常见类型以及为什么它们如此重要。
---
### **1. 为什么需要激活函数?**
#### **(1)线性模型的局限性**
如果没有激活函数,神经网络只是多个线性变换的组合(即矩阵乘法),最终仍然是一个线性模型。例如:
\[
y = W_2(W_1x + b_1) + b_2
\]
无论有多少层,最终都可以简化为一个线性函数:
\[
y = W'x + b'
\]
线性模型只能解决简单的线性可分问题(如用一条直线分类数据),无法处理复杂的非线性问题(如图像分类、自然语言处理)。
#### **(2)激活函数的作用**
激活函数在神经元的输出上引入**非线性**,使得神经网络可以拟合任意复杂的函数。例如:
\[
y = f(Wx + b)
\]
其中 \(f\) 是激活函数。通过叠加多个非线性层,神经网络可以学习到数据中的复杂模式。
---
### **2. 激活函数的常见类型**
以下是几种常见的激活函数及其特点:
#### **(1)ReLU(Rectified Linear Unit)**
- **公式**:
\[
f(x) = \max(0, x)
\]
- **特点**:
- 计算简单,速度快。
- 缓解梯度消失问题(在正区间梯度恒为1)。
- 输出不是零中心化的(可能影响收敛速度)。
- **适用场景**:大多数深度学习模型的首选激活函数。
#### **(2)Sigmoid**
- **公式**:
\[
f(x) = \frac{1}{1 + e^{-x}}
\]
- **特点**:
- 输出范围在 (0,1),适合二分类问题。
- 容易导致梯度消失问题(在输入值较大或较小时,梯度接近0)。
- **适用场景**:输出层的二分类问题。
#### **(3)Tanh(双曲正切函数)**
- **公式**:
\[
f(x) = \tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}}
\]
- **特点**:
- 输出范围在 (-1,1),零中心化。
- 比Sigmoid梯度更强,但仍存在梯度消失问题。
- **适用场景**:隐藏层或输出层的回归问题。
#### **(4)Softmax**
- **公式**:
\[
f(x_i) = \frac{e^{x_i}}{\sum_{j=1}^n e^{x_j}}
\]
- **特点**:
- 将输入转换为概率分布(输出总和为1)。
- 适合多分类问题。
- **适用场景**:输出层的多分类问题。
---
### **3. 激活函数的作用示例**
假设我们有一个简单的神经网络,输入为 \(x\),权重为 \(w\),偏置为 \(b\),激活函数为 ReLU:
\[
y = \text{ReLU}(w \cdot x + b)
\]
- **输入**:\(x = 2\),\(w = 1.5\),\(b = -1\)
- **计算**:
\[
z = w \cdot x + b = 1.5 \times 2 + (-1) = 2
\]
\[
y = \text{ReLU}(z) = \max(0, 2) = 2
\]
- **结果**:输出为 2。
如果输入为 \(x = -1\):
\[
z = 1.5 \times (-1) + (-1) = -2.5
\]
\[
y = \text{ReLU}(z) = \max(0, -2.5) = 0
\]
- **结果**:输出为 0。
通过 ReLU,神经网络可以过滤掉负值,只保留正值,从而引入非线性。
---
### **4. 激活函数的梯度**
激活函数的梯度在反向传播中非常重要,它决定了权重更新的幅度。
#### **(1)ReLU 的梯度**
\[
f'(x) = \begin{cases}
1 & \text{if } x > 0 \\
0 & \text{if } x \leq 0
\end{cases}
\]
- 在正区间梯度为1,反向传播时梯度不会衰减。
- 在负区间梯度为0,可能导致“神经元死亡”(永远输出0)。
#### **(2)Sigmoid 的梯度**
\[
f'(x) = f(x) \cdot (1 - f(x))
\]
- 当输入值较大或较小时,梯度接近0,导致梯度消失问题。
---
### **5. 如何选择激活函数?**
- **隐藏层**:通常选择 ReLU,计算简单且效果好。
- **输出层**:
- 二分类问题:Sigmoid。
- 多分类问题:Softmax。
- 回归问题:Tanh 或线性激活函数。
---
### **6. 代码示例**
以下是一个使用 ReLU 激活函数的简单神经网络:
```python
import torch
import torch.nn as nn
# 定义一个简单的神经网络
class SimpleNN(nn.Module):
def __init__(self):
super(SimpleNN, self).__init__()
self.fc1 = nn.Linear(10, 5) # 输入10维,输出5维
self.relu = nn.ReLU() # 激活函数
self.fc2 = nn.Linear(5, 1) # 输出1维(如回归值)
def forward(self, x):
x = self.fc1(x)
x = self.relu(x) # 应用ReLU激活函数
x = self.fc2(x)
return x
# 初始化模型
model = SimpleNN()
# 输入数据(10维向量)
input_data = torch.randn(1, 10) # 1个样本,10个特征
output = model(input_data)
print(output)
```
---
### **7. 今日任务**
1. **手动计算**:给定输入 \(x = [1, -2, 3]\),权重 \(w = [0.5, -1, 0.8]\),偏置 \(b = 1\),使用 ReLU 激活函数计算输出。
2. **修改代码**:将上述代码中的 ReLU 替换为 Sigmoid 或 Tanh,观察输出结果的变化。
3. **思考问题**:为什么 ReLU 在深度学习中比 Sigmoid 更常用?
---
梯度是深度学习和优化问题中的一个核心概念,它表示函数在某一点的变化率或方向。为了帮助你更好地理解梯度,我会从基础概念出发,逐步解释它的定义、计算方法以及在深度学习中的作用。
---
### **1. 梯度的定义**
- **梯度**是一个向量,表示函数在某一点的变化率最大的方向。
- 对于一个多元函数 \(f(x_1, x_2, \dots, x_n)\),梯度是所有偏导数组成的向量:
\[
\nabla f = \left( \frac{\partial f}{\partial x_1}, \frac{\partial f}{\partial x_2}, \dots, \frac{\partial f}{\partial x_n} \right)
\]
- **偏导数**:表示函数在某一变量方向上的变化率。
---
### **2. 梯度的几何意义**
- 梯度指向函数值增长最快的方向。
- 梯度的模(长度)表示函数值变化的速率。
- 在优化问题中,我们通常希望找到函数的最小值,因此会沿着梯度的**反方向**更新参数。
---
### **3. 梯度在深度学习中的作用**
在深度学习中,梯度用于**反向传播**(Backpropagation)算法中,通过计算损失函数对模型参数的梯度,更新参数以最小化损失。
#### **(1)损失函数**
- 损失函数(Loss Function)衡量模型预测值与真实值之间的差距。
- 例如,均方误差(MSE):
\[
L = \frac{1}{N} \sum_{i=1}^N (y_i - \hat{y}_i)^2
\]
其中,\(y_i\) 是真实值,\(\hat{y}_i\) 是模型预测值。
#### **(2)参数更新**
- 假设模型参数为 \(w\),学习率为 \(\eta\),梯度为 \(\nabla L\),则参数更新公式为:
\[
w_{\text{new}} = w_{\text{old}} - \eta \cdot \nabla L
\]
- 通过不断迭代更新参数,模型逐渐逼近最优解。
---
### **4. 梯度的计算示例**
#### **(1)简单函数示例**
假设有一个函数:
\[
f(x, y) = x^2 + y^2
\]
- 梯度计算:
\[
\nabla f = \left( \frac{\partial f}{\partial x}, \frac{\partial f}{\partial y} \right) = (2x, 2y)
\]
- 在点 \((1, 2)\) 的梯度为:
\[
\nabla f(1, 2) = (2 \times 1, 2 \times 2) = (2, 4)
\]
#### **(2)深度学习中的梯度计算**
假设有一个简单的线性模型:
\[
\hat{y} = w \cdot x + b
\]
损失函数为均方误差:
\[
L = \frac{1}{2} (y - \hat{y})^2
\]
- 计算损失对参数 \(w\) 和 \(b\) 的梯度:
\[
\frac{\partial L}{\partial w} = (y - \hat{y}) \cdot (-x)
\]
\[
\frac{\partial L}{\partial b} = (y - \hat{y}) \cdot (-1)
\]
- 梯度向量为:
\[
\nabla L = \left( \frac{\partial L}{\partial w}, \frac{\partial L}{\partial b} \right)
\]
---
### **5. 代码示例**
以下是一个使用 PyTorch 计算梯度的简单示例:
```python
import torch
# 定义模型参数
w = torch.tensor(2.0, requires_grad=True) # 权重
b = torch.tensor(1.0, requires_grad=True) # 偏置
# 输入数据
x = torch.tensor(3.0) # 输入
y_true = torch.tensor(10.0) # 真实值
# 前向传播
y_pred = w * x + b # 模型预测
loss = (y_true - y_pred) ** 2 # 损失函数
# 反向传播
loss.backward() # 计算梯度
# 输出梯度
print("梯度 w:", w.grad) # dL/dw
print("梯度 b:", b.grad) # dL/db
```
#### **运行结果**
- 梯度 \(w\):\(dL/dw = -24.0\)
- 梯度 \(b\):\(dL/db = -8.0\)
---
### **6. 今日任务**
1. **手动计算梯度**:
- 给定函数 \(f(x, y) = 3x^2 + 2y^3\),计算在点 \((1, 1)\) 的梯度。
2. **运行代码**:
- 运行上述代码,观察梯度计算结果。
3. **思考问题**:
- 如果学习率 \(\eta\) 过大或过小,参数更新会有什么影响?
---
### **7. 总结**
- 梯度是函数在某一点的变化率最大的方向。
- 在深度学习中,梯度用于更新模型参数,以最小化损失函数。
- 通过反向传播算法,可以高效地计算梯度。
---