深度学习

### **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. 总结**

- 梯度是函数在某一点的变化率最大的方向。

- 在深度学习中,梯度用于更新模型参数,以最小化损失函数。

- 通过反向传播算法,可以高效地计算梯度。


---

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容