首页 > 其他分享 >神经网络与深度学习基础教程笔记(附案例讲解)

神经网络与深度学习基础教程笔记(附案例讲解)

时间:2024-10-12 13:20:43浏览次数:12  
标签:plt 函数 label test 神经网络 基础教程 讲解 images

神经网络与深度学习基础教程笔记(附案例讲解)

引言

神经网络和深度学习是人工智能领域中最重要的技术之一,它们在图像识别、自然语言处理、语音识别等领域取得了巨大的成功。本教程将从基础概念出发,逐步深入到高级主题,帮助你全面理解并掌握这些强大的工具。本文是神经网络与深度学习笔记,要想深入了解相关理论和算法知识请参考神经网络从入门到精通matlab从入门到精通教程matlab2020从入门到精通ACM入门教程资料MATLAB语言常用算法程序集matlab通俗讲讲“小波变换”精通MATLAB最优化计算源码MATLAB小波分析高级技术基于MATLAB的系统分析与设计-小波分析小波分析基础时间序列的小波分析

目录
  1. 神经网络基础
    • 什么是神经网络?
    • 感知机
    • 多层感知机(MLP)
  2. 激活函数
  3. 损失函数
  4. 优化算法
  5. 反向传播算法
  6. 卷积神经网络(CNN)
  7. 循环神经网络(RNN)
  8. 长短期记忆网络(LSTM)
  9. 生成对抗网络(GAN)
  10. 迁移学习
  11. 实战项目:手写数字识别

1. 神经网络基础

什么是神经网络?

神经网络是一种模拟人脑神经元结构的计算模型。它由多个节点(或称为神经元)组成,这些节点通过连接权重相互连接。每个节点接收输入信号,经过处理后传递给下一层节点。神经网络通过调整连接权重来学习数据中的模式。

感知机

感知机是最简单的神经网络形式,由 Frank Rosenblatt 在 1957 年提出。它只有一个输入层和一个输出层,没有隐藏层。感知机用于解决二分类问题。

数学表示
[ y = f(\sum_{i=1}^{n} w_i x_i + b) ]
其中,( y ) 是输出,( w_i ) 是权重,( x_i ) 是输入,( b ) 是偏置项,( f ) 是激活函数(通常是阶跃函数)。

训练过程

  • 初始化权重 ( w_i ) 和偏置 ( b )。
  • 对于每个训练样本,计算输出 ( y )。
  • 如果预测错误,更新权重和偏置:
    [ w_i = w_i + \eta (t - y) x_i ]
    [ b = b + \eta (t - y) ]
    其中,( \eta ) 是学习率,( t ) 是目标值。
多层感知机(MLP)

多层感知机(MLP)是包含一个或多个隐藏层的前馈神经网络。每个隐藏层可以有多个神经元,每个神经元都使用非线性激活函数(如 Sigmoid 或 ReLU)。

结构

  • 输入层:接收原始数据。
  • 隐藏层:对数据进行特征提取。
  • 输出层:产生最终结果。

数学表示
假设有一个 MLP,输入层有 ( n ) 个节点,第一个隐藏层有 ( h_1 ) 个节点,第二个隐藏层有 ( h_2 ) 个节点,输出层有 ( m ) 个节点。

对于第 ( l ) 层的第 ( j ) 个节点:
[ z_j^{(l)} = \sum_{i=1}^{n_l} w_{ij}^{(l)} a_i^{(l-1)} + b_j^{(l)} ]
[ a_j^{(l)} = f(z_j^{(l)}) ]

其中,( z_j^{(l)} ) 是加权输入,( a_j^{(l)} ) 是激活值,( w_{ij}^{(l)} ) 是从第 ( l-1 ) 层的第 ( i ) 个节点到第 ( l ) 层的第 ( j ) 个节点的权重,( b_j^{(l)} ) 是偏置项,( f ) 是激活函数。

2. 激活函数

激活函数为神经网络引入非线性,使得网络能够学习复杂的模式。常见的激活函数包括:

  • Sigmoid 函数
    [ f(x) = \frac{1}{1 + e^{-x}} ]

    • 输出范围:(0, 1)
    • 缺点:容易导致梯度消失。
  • Tanh 函数
    [ f(x) = \tanh(x) = \frac{e^x - e{-x}}{ex + e^{-x}} ]

    • 输出范围:(-1, 1)
    • 缺点:同样容易导致梯度消失。
  • ReLU 函数
    [ f(x) = \max(0, x) ]

    • 输出范围:[0, +∞)
    • 优点:计算简单,有效缓解梯度消失问题。
  • Leaky ReLU 函数
    [ f(x) = \begin{cases}
    x & \text{if } x > 0 \
    \alpha x & \text{if } x \leq 0
    \end{cases} ]

    • 输出范围:(-∞, +∞)
    • 优点:解决了 ReLU 的“死神经元”问题。
  • Softmax 函数
    [ \text{softmax}(z)_i = \frac{e{z_i}}{\sum_{j=1}K e^{z_j}} ]

    • 输出范围:(0, 1)
    • 通常用于多分类任务的输出层,确保输出的概率之和为 1。

3. 损失函数

损失函数衡量模型预测值与真实值之间的差异。常见的损失函数包括:

  • 均方误差(MSE)
    [ L = \frac{1}{N} \sum_{i=1}^{N} (y_i - \hat{y}_i)^2 ]

    • 适用于回归任务。
  • 交叉熵损失(Cross-Entropy Loss)
    [ L = -\frac{1}{N} \sum_{i=1}^{N} \left[ y_i \log(\hat{y}_i) + (1 - y_i) \log(1 - \hat{y}_i) \right] ]

    • 适用于二分类任务。
  • 多类交叉熵损失(Categorical Cross-Entropy Loss)
    [ L = -\frac{1}{N} \sum_{i=1}^{N} \sum_{k=1}^{K} y_{ik} \log(\hat{y}_{ik}) ]

    • 适用于多分类任务。

4. 优化算法

优化算法用于更新神经网络的权重,以最小化损失函数。常见的优化算法包括:

  • 梯度下降法(Gradient Descent, GD)
    [ w_{t+1} = w_t - \eta \nabla L(w_t) ]

    • 优点:简单直观。
    • 缺点:收敛速度慢,容易陷入局部极小值。
  • 随机梯度下降法(Stochastic Gradient Descent, SGD)
    [ w_{t+1} = w_t - \eta \nabla L(w_t; x_i, y_i) ]

    • 优点:每次只用一个样本更新权重,速度快。
    • 缺点:参数更新不稳定,可能不收敛。
  • Mini-Batch 梯度下降法
    [ w_{t+1} = w_t - \eta \nabla L(w_t; X_b, Y_b) ]

    • 优点:结合了批量梯度下降和随机梯度下降的优点。
    • 缺点:需要选择合适的批大小。
  • 动量法(Momentum)
    [ v_{t+1} = \gamma v_t + \eta \nabla L(w_t) ]
    [ w_{t+1} = w_t - v_{t+1} ]

    • 优点:加速收敛,减少振荡。
  • Adagrad
    [ G_t = \sum_{\tau=1}^{t} g_\tau g_\tau^T ]
    [ w_{t+1} = w_t - \frac{\eta}{\sqrt{\text{diag}(G_t) + \epsilon}} \odot g_t ]

    • 优点:自适应学习率,适合稀疏数据。
  • RMSProp
    [ E[g^2]t = \gamma E[g^2]{t-1} + (1 - \gamma) g_t^2 ]
    [ w_{t+1} = w_t - \frac{\eta}{\sqrt{E[g^2]_t + \epsilon}} g_t ]

    • 优点:改进了 Adagrad 的单调递减学习率问题。
  • Adam(Adaptive Moment Estimation)
    [ m_t = \beta_1 m_{t-1} + (1 - \beta_1) g_t ]
    [ v_t = \beta_2 v_{t-1} + (1 - \beta_2) g_t^2 ]
    [ \hat{m}_t = \frac{m_t}{1 - \beta_1^t} ]
    [ \hat{v}t = \frac{v_t}{1 - \beta_2^t} ]
    [ w
    {t+1} = w_t - \frac{\eta}{\sqrt{\hat{v}_t} + \epsilon} \hat{m}_t ]

    • 优点:结合了动量法和 RMSProp 的优点,收敛速度快且稳定。

5. 反向传播算法

反向传播算法(Backpropagation)是神经网络中最常用的训练方法,它通过计算损失函数对各层权重的梯度来更新权重。具体步骤如下:

  1. 前向传播

    • 计算每一层的激活值 ( a^{(l)} ) 和加权输入 ( z^{(l)} )。
    • 计算最终的损失 ( L )。
  2. 反向传播

    • 计算输出层的误差 ( \delta^{(L)} ):
      [ \delta^{(L)} = \nabla_a C \odot \sigma’(z^{(L)}) ]
      其中,( \nabla_a C ) 是损失函数对输出层激活值的梯度,( \sigma’ ) 是激活函数的导数。
    • 逐层向前计算每层的误差 ( \delta^{(l)} ):
      [ \delta^{(l)} = ((W{(l+1)})T \delta^{(l+1)}) \odot \sigma’(z^{(l)}) ]
    • 计算权重的梯度 ( \nabla W^{(l)} ) 和偏置的梯度 ( \nabla b^{(l)} ):
      [ \nabla W^{(l)} = \delta^{(l)} (a{(l-1)})T ]
      [ \nabla b^{(l)} = \delta^{(l)} ]
  3. 权重更新

    • 使用优化算法更新权重和偏置。

6. 卷积神经网络(CNN)

卷积神经网络(Convolutional Neural Network, CNN)主要用于处理具有空间层次结构的数据,如图像。CNN 包含以下关键组件:

  • 卷积层(Convolutional Layer)

    • 使用卷积核(滤波器)对输入数据进行卷积操作,提取局部特征。
    • 参数共享:同一滤波器在整个输入上共享相同的权重。
  • 激活函数

    • 通常使用 ReLU 激活函数。
  • 池化层(Pooling Layer)

    • 通过降维操作(如最大池化或平均池化)减少特征图的空间尺寸,提高平移不变性。
  • 全连接层(Fully Connected Layer)

    • 将卷积层和池化层提取的特征整合成最终的输出。
  • Dropout 层

    • 通过随机丢弃一部分神经元来防止过拟合。

典型架构

  • LeNet-5
  • AlexNet
  • VGGNet
  • GoogLeNet/Inception
  • ResNet

7. 循环神经网络(RNN)

循环神经网络(Recurrent Neural Network, RNN)用于处理序列数据,如文本、时间序列等。RNN 通过引入循环连接来保留先前时间步的信息。

基本结构

  • 每个时间步的输入 ( x_t ) 与前一时间步的隐藏状态 ( h_{t-1} ) 结合,生成当前时间步的隐藏状态 ( h_t ) 和输出 ( y_t )。
  • 更新公式:
    [ h_t = f(W_{hx} x_t + W_{hh} h_{t-1} + b_h) ]
    [ y_t = g(W_{hy} h_t + b_y) ]
    其中,( f ) 和 ( g ) 是激活函数,( W ) 和 ( b ) 是权重和偏置。

常见变体

  • 长短时记忆网络(LSTM)

    • 解决了传统 RNN 的梯度消失和梯度爆炸问题。
    • 通过引入细胞状态和门控机制来控制信息的流动。
  • 门控循环单元(GRU)

    • 简化了 LSTM 的结构,合并了遗忘门和输入门。

8. 长短期记忆网络(LSTM)

LSTM 是一种特殊的 RNN,通过引入细胞状态和门控机制来更好地处理长期依赖问题。

基本结构

  • 输入门:决定哪些信息需要更新到细胞状态。
  • 遗忘门:决定哪些信息需要从细胞状态中丢弃。
  • 输出门:决定哪些信息需要作为输出。

更新公式

  • 输入门:
    [ i_t = \sigma(W_{xi} x_t + W_{hi} h_{t-1} + b_i) ]
  • 遗忘门:
    [ f_t = \sigma(W_{xf} x_t + W_{hf} h_{t-1} + b_f) ]
  • 细胞状态更新:
    [ \tilde{C}t = \tanh(W{xc} x_t + W_{hc} h_{t-1} + b_c) ]
    [ C_t = f_t \odot C_{t-1} + i_t \odot \tilde{C}_t ]
  • 输出门:
    [ o_t = \sigma(W_{xo} x_t + W_{ho} h_{t-1} + b_o) ]
  • 输出隐藏状态:
    [ h_t = o_t \odot \tanh(C_t) ]

9. 生成对抗网络(GAN)

生成对抗网络(Generative Adversarial Networks, GAN)是一种无监督学习方法,用于生成新的数据实例。GAN 由两个部分组成:生成器(Generator)和判别器(Discriminator)。

工作原理

  • 生成器:生成新的数据实例,试图欺骗判别器认为这些实例是真实的。
  • 判别器:区分生成的数据和真实数据。

训练过程

  • 生成器的目标是最小化判别器的正确率。
  • 判别器的目标是最大化其正确率,即正确区分生成的数据和真实数据。

损失函数

  • 生成器的损失:
    [ L_G = -\mathbb{E}_{z \sim p_z(z)}[\log(D(G(z)))] ]
  • 判别器的损失:
    [ L_D = -\mathbb{E}{x \sim p{data}(x)}[\log(D(x))] - \mathbb{E}_{z \sim p_z(z)}[\log(1 - D(G(z)))] ]

10. 迁移学习

迁移学习是指将在一个任务上学到的知识迁移到另一个相关任务上。这种方法可以显著减少新任务所需的数据量和训练时间。

应用场景

  • 图像分类:预训练的 CNN 模型(如 VGG、ResNet)可以在新数据集上微调。
  • 自然语言处理:预训练的语言模型(如 BERT、GPT)可以在特定任务上进行微调。

步骤

  1. 加载预训练模型:加载在大规模数据集上预训练的模型。
  2. 冻结部分层:冻结预训练模型的部分层,防止其权重被更新。
  3. 添加新层:根据新任务的需求,在预训练模型的基础上添加新的层。
  4. 微调:在新数据集上进行训练,更新新层和未冻结的旧层的权重。

11. 实战项目:手写数字识别

下面是一个使用 TensorFlow 和 Keras 实现的手写数字识别项目的示例代码。

数据准备

我们将使用 MNIST 数据集,这是一个常用的手写数字数据集。

import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt

# 加载 MNIST 数据集
(train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data()

# 归一化像素值到 [0, 1] 范围
train_images, test_images = train_images / 255.0, test_images / 255.0

# 增加颜色通道维度
train_images = train_images[..., tf.newaxis]
test_images = test_images[..., tf.newaxis]

# 查看数据
print("Train images shape:", train_images.shape)
print("Train labels shape:", train_labels.shape)
print("Test images shape:", test_images.shape)
print("Test labels shape:", test_labels.shape)

# 显示一些样本
plt.figure(figsize=(10, 10))
for i in range(25):
    plt.subplot(5, 5, i + 1)
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(train_images[i], cmap=plt.cm.binary)
    plt.xlabel(train_labels[i])
plt.show()
构建模型

我们构建一个简单的卷积神经网络(CNN)。

model = models.Sequential([
    layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(64, (3, 3), activation='relu'),
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(64, (3, 3), activation='relu'),
    layers.Flatten(),
    layers.Dense(64, activation='relu'),
    layers.Dense(10, activation='softmax')
])

# 打印模型概要
model.summary()
编译模型

配置模型的优化器、损失函数和评估指标。

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])
训练模型

训练模型并在测试集上进行评估。

history = model.fit(train_images, train_labels, epochs=10,
                    validation_data=(test_images, test_labels))

# 评估模型
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print(f'\nTest accuracy: {test_acc}')
可视化训练过程

绘制训练和验证的准确率和损失曲线。

import matplotlib.pyplot as plt

# 绘制训练和验证的准确率
plt.plot(history.history['accuracy'], label='accuracy')
plt.plot(history.history['val_accuracy'], label='val_accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.ylim([0, 1])
plt.legend(loc='lower right')
plt.show()

# 绘制训练和验证的损失
plt.plot(history.history['loss'], label='loss')
plt.plot(history.history['val_loss'], label='val_loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend(loc='upper right')
plt.show()
保存和加载模型

保存训练好的模型,并在需要时加载。

# 保存模型
model.save('mnist_model.h5')

# 加载模型
loaded_model = tf.keras.models.load_model('mnist_model.h5')
预测

使用加载的模型进行预测。

predictions = loaded_model.predict(test_images)

# 显示预测结果
def plot_image(i, predictions_array, true_label, img):
    predictions_array, true_label, img = predictions_array[i], true_label[i], img[i]
    plt.grid(False)
    plt.xticks([])
    plt.yticks([])

    plt.imshow(img, cmap=plt.cm.binary)

    predicted_label = np.argmax(predictions_array)
    if predicted_label == true_label:
        color = 'blue'
    else:
        color = 'red'

    plt.xlabel(f"{predicted_label} ({100 * np.max(predictions_array):.2f}%)", color=color)

def plot_value_array(i, predictions_array, true_label):
    predictions_array, true_label = predictions_array[i], true_label[i]
    plt.grid(False)
    plt.xticks([])
    plt.yticks([])
    thisplot = plt.bar(range(10), predictions_array, color="#777777")
    plt.ylim([0, 1])
    predicted_label = np.argmax(predictions_array)

    thisplot[predicted_label].set_color('red')
    thisplot[true_label].set_color('blue')

num_rows = 5
num_cols = 3
num_images = num_rows * num_cols
plt.figure(figsize=(2 * 2 * num_cols, 2 * num_rows))
for i in range(num_images):
    plt.subplot(num_rows, 2 * num_cols, 2 * i + 1)
    plot_image(i, predictions, test_labels, test_images)
    plt.subplot(num_rows, 2 * num_cols, 2 * i + 2)
    plot_value_array(i, predictions, test_labels)
plt.tight_layout()
plt.show()

总结

通过本教程,你应该已经掌握了神经网络和深度学习的基础知识,并了解了如何使用 TensorFlow 和 Keras 构建和训练一个简单的手写数字识别模型。你可以继续探索更多高级主题,如更复杂的网络架构、正则化技术、超参数调优等,以进一步提升你的技能。

标签:plt,函数,label,test,神经网络,基础教程,讲解,images
From: https://blog.csdn.net/ashyyyy/article/details/142729596

相关文章