深度学习基础:从神经网络到深度架构的全面介绍
讲座开场白
大家好!欢迎来到今天的讲座,主题是“深度学习基础:从神经网络到深度架构的全面介绍”。我是你们的讲师Qwen。今天我们将一起探讨深度学习的核心概念,从最基础的神经网络开始,逐步深入到现代的深度架构。我们会用轻松诙谐的语言,结合一些代码和表格,帮助你更好地理解这些复杂的概念。
为什么选择深度学习?
在过去的十年里,深度学习已经彻底改变了人工智能领域。从图像识别到自然语言处理,再到自动驾驶,深度学习的应用无处不在。它之所以如此强大,是因为它能够自动从数据中学习复杂的模式,而不需要人工设计特征。这使得它在处理大规模、复杂的数据时表现出色。
那么,深度学习到底是什么呢?简单来说,深度学习是一种基于神经网络的机器学习方法。它通过多层非线性变换来提取数据的高级特征,并最终做出预测或分类。接下来,我们从最基础的神经网络开始,一步步深入了解这个神奇的技术。
第一部分:神经网络的基础
1.1 神经元与激活函数
神经网络的基本单元是神经元(也叫感知器)。每个神经元接收多个输入,对它们进行加权求和,然后通过一个激活函数来决定输出。激活函数的作用是引入非线性,使得神经网络能够处理更复杂的问题。
常见的激活函数有:
- Sigmoid:$f(x) = frac{1}{1 + e^{-x}}$
- ReLU(Rectified Linear Unit):$f(x) = max(0, x)$
- Tanh:$f(x) = frac{e^x – e^{-x}}{e^x + e^{-x}}$
其中,ReLU是最常用的激活函数之一,因为它计算简单且能有效避免梯度消失问题。
1.2 神经网络的结构
神经网络通常由多个层次组成,每一层包含多个神经元。最常见的结构是全连接层,即每一层的神经元都与下一层的所有神经元相连。一个典型的神经网络结构如下:
- 输入层:接收原始数据。
- 隐藏层:中间层,负责提取数据的特征。
- 输出层:给出最终的预测结果。
假设我们有一个简单的二分类问题,输入是一个二维向量,输出是一个标量(0或1)。我们可以构建一个两层的神经网络,代码如下:
import numpy as np
# 定义激活函数
def sigmoid(x):
return 1 / (1 + np.exp(-x))
# 定义前向传播
def forward_propagation(X, W1, b1, W2, b2):
# 第一层
z1 = np.dot(X, W1) + b1
a1 = sigmoid(z1)
# 第二层
z2 = np.dot(a1, W2) + b2
a2 = sigmoid(z2)
return a2
# 初始化权重和偏置
W1 = np.random.randn(2, 3) # 输入层到隐藏层的权重
b1 = np.zeros((1, 3)) # 隐藏层的偏置
W2 = np.random.randn(3, 1) # 隐藏层到输出层的权重
b2 = np.zeros((1, 1)) # 输出层的偏置
# 输入数据
X = np.array([[0.5, 0.8]])
# 前向传播
output = forward_propagation(X, W1, b1, W2, b2)
print("输出:", output)
1.3 损失函数与反向传播
神经网络的目标是通过调整权重和偏置,使预测结果尽可能接近真实值。为此,我们需要定义一个损失函数,用于衡量预测值与真实值之间的差异。常见的损失函数有:
- 均方误差(MSE):$text{MSE} = frac{1}{n} sum_{i=1}^{n} (y_i – hat{y}_i)^2$
- 交叉熵损失:$text{CE} = -frac{1}{n} sum_{i=1}^{n} [y_i log(hat{y}_i) + (1 – y_i) log(1 – hat{y}_i)]$
为了最小化损失函数,我们使用反向传播算法。它通过链式法则计算损失函数对每个参数的梯度,然后使用梯度下降法更新参数。以下是反向传播的伪代码:
# 反向传播
def backward_propagation(X, Y, a1, a2, W2):
# 计算输出层的误差
dZ2 = a2 - Y
dW2 = np.dot(a1.T, dZ2)
db2 = np.sum(dZ2, axis=0, keepdims=True)
# 计算隐藏层的误差
dZ1 = np.dot(dZ2, W2.T) * a1 * (1 - a1)
dW1 = np.dot(X.T, dZ1)
db1 = np.sum(dZ1, axis=0, keepdims=True)
return dW1, db1, dW2, db2
# 更新参数
def update_parameters(W1, b1, W2, b2, dW1, db1, dW2, db2, learning_rate):
W1 -= learning_rate * dW1
b1 -= learning_rate * db1
W2 -= learning_rate * dW2
b2 -= learning_rate * db2
return W1, b1, W2, b2
第二部分:从浅层到深层
2.1 卷积神经网络(CNN)
当我们处理图像数据时,全连接神经网络的参数数量会非常庞大,导致过拟合和训练困难。为了解决这个问题,卷积神经网络(CNN)应运而生。CNN通过局部感知野和共享权重的方式,大幅减少了参数数量,并且能够捕捉图像中的空间结构。
CNN的核心操作是卷积,它通过滑动滤波器(kernel)在输入图像上进行逐像素计算。每次卷积操作都会生成一个新的特征图(feature map),反映了输入图像的某些特定特征。常见的卷积操作包括:
- 卷积层:用于提取局部特征。
- 池化层:用于降维,减少计算量。
- 全连接层:用于最终的分类或回归。
以下是一个简单的CNN结构,使用了两个卷积层和一个全连接层:
import torch
import torch.nn as nn
class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN, self).__init__()
# 卷积层
self.conv1 = nn.Conv2d(in_channels=1, out_channels=16, kernel_size=3, stride=1, padding=1)
self.conv2 = nn.Conv2d(in_channels=16, out_channels=32, kernel_size=3, stride=1, padding=1)
# 池化层
self.pool = nn.MaxPool2d(kernel_size=2, stride=2, padding=0)
# 全连接层
self.fc1 = nn.Linear(in_features=32 * 7 * 7, out_features=128)
self.fc2 = nn.Linear(in_features=128, out_features=10)
def forward(self, x):
# 第一层卷积 + 激活 + 池化
x = self.pool(torch.relu(self.conv1(x)))
# 第二层卷积 + 激活 + 池化
x = self.pool(torch.relu(self.conv2(x)))
# 展平
x = x.view(-1, 32 * 7 * 7)
# 全连接层 + 激活
x = torch.relu(self.fc1(x))
# 输出层
x = self.fc2(x)
return x
2.2 循环神经网络(RNN)
当处理序列数据(如文本、语音等)时,传统的神经网络无法捕捉时间上的依赖关系。为了解决这个问题,循环神经网络(RNN)被提出。RNN通过引入循环结构,使得信息可以在时间步之间传递。
然而,标准的RNN存在梯度消失和梯度爆炸的问题,导致难以训练长序列。为此,长短期记忆网络(LSTM)和门控循环单元(GRU)被提出。它们通过引入门控机制,有效地解决了这些问题。
以下是一个简单的LSTM模型,用于处理序列数据:
import torch
import torch.nn as nn
class LSTMModel(nn.Module):
def __init__(self, input_size, hidden_size, num_layers, output_size):
super(LSTMModel, self).__init__()
self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
# LSTM输出
out, _ = self.lstm(x)
# 取最后一个时间步的输出
out = out[:, -1, :]
# 全连接层
out = self.fc(out)
return out
第三部分:现代深度架构
3.1 ResNet:残差网络
随着神经网络的层数不断增加,训练难度也随之增大。为了解决这一问题,He等人提出了残差网络(ResNet)。ResNet通过引入残差块,使得网络可以更容易地学习恒等映射,从而缓解了梯度消失问题。
残差块的结构如下:
$$
y = F(x) + x
$$
其中,$F(x)$ 是一个非线性变换,$x$ 是输入。通过这种方式,网络可以直接将输入传递到输出,减少了信息丢失的风险。
3.2 Transformer:注意力机制
近年来,Transformer架构在自然语言处理领域取得了巨大的成功。与传统的RNN不同,Transformer完全基于自注意力机制,能够并行处理序列数据,大大提高了训练效率。
Transformer的核心是多头自注意力机制,它允许模型在不同的子空间中关注不同的位置。此外,Transformer还引入了位置编码,以保留序列的顺序信息。
以下是一个简单的Transformer模型,用于处理文本分类任务:
import torch
import torch.nn as nn
import torch.nn.functional as F
class TransformerModel(nn.Module):
def __init__(self, vocab_size, embed_size, num_heads, num_layers, output_size):
super(TransformerModel, self).__init__()
self.embedding = nn.Embedding(vocab_size, embed_size)
self.positional_encoding = PositionalEncoding(embed_size)
self.transformer = nn.TransformerEncoder(
encoder_layer=nn.TransformerEncoderLayer(d_model=embed_size, nhead=num_heads),
num_layers=num_layers
)
self.fc = nn.Linear(embed_size, output_size)
def forward(self, x):
# 嵌入层
x = self.embedding(x)
# 位置编码
x = self.positional_encoding(x)
# Transformer编码器
x = self.transformer(x)
# 取平均池化
x = torch.mean(x, dim=1)
# 全连接层
x = self.fc(x)
return x
结语
今天我们从神经网络的基础出发,逐步深入到了现代的深度架构。通过代码和表格,我们详细介绍了神经元、激活函数、损失函数、反向传播等核心概念,并探讨了卷积神经网络、循环神经网络、ResNet和Transformer等经典模型。
希望今天的讲座能够帮助你更好地理解深度学习的本质。如果你对某个话题感兴趣,不妨动手实践一下,编写自己的深度学习模型。相信你会在这个充满挑战和机遇的领域中发现更多乐趣!
谢谢大家的聆听,祝你在深度学习的道路上越走越远!