深度学习基础:从神经网络到深度架构的全面介绍

深度学习基础:从神经网络到深度架构的全面介绍

讲座开场白

大家好!欢迎来到今天的讲座,主题是“深度学习基础:从神经网络到深度架构的全面介绍”。我是你们的讲师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等经典模型。

希望今天的讲座能够帮助你更好地理解深度学习的本质。如果你对某个话题感兴趣,不妨动手实践一下,编写自己的深度学习模型。相信你会在这个充满挑战和机遇的领域中发现更多乐趣!

谢谢大家的聆听,祝你在深度学习的道路上越走越远!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注