神经网络与深度学习基础教程笔记(附案例讲解)
引言
神经网络和深度学习是人工智能领域中最重要的技术之一,它们在图像识别、自然语言处理、语音识别等领域取得了巨大的成功。本教程将从基础概念出发,逐步深入到高级主题,帮助你全面理解并掌握这些强大的工具。本文是神经网络与深度学习笔记,要想深入了解相关理论和算法知识请参考神经网络从入门到精通、matlab从入门到精通教程、matlab2020从入门到精通、ACM入门教程资料、MATLAB语言常用算法程序集、matlab通俗讲讲“小波变换”、精通MATLAB最优化计算源码、MATLAB小波分析高级技术、基于MATLAB的系统分析与设计-小波分析、小波分析基础、时间序列的小波分析。
目录
- 神经网络基础
- 什么是神经网络?
- 感知机
- 多层感知机(MLP)
- 激活函数
- 损失函数
- 优化算法
- 反向传播算法
- 卷积神经网络(CNN)
- 循环神经网络(RNN)
- 长短期记忆网络(LSTM)
- 生成对抗网络(GAN)
- 迁移学习
- 实战项目:手写数字识别
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)是神经网络中最常用的训练方法,它通过计算损失函数对各层权重的梯度来更新权重。具体步骤如下:
-
前向传播:
- 计算每一层的激活值 ( a^{(l)} ) 和加权输入 ( z^{(l)} )。
- 计算最终的损失 ( L )。
-
反向传播:
- 计算输出层的误差 ( \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)} ]
- 计算输出层的误差 ( \delta^{(L)} ):
-
权重更新:
- 使用优化算法更新权重和偏置。
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)可以在特定任务上进行微调。
步骤:
- 加载预训练模型:加载在大规模数据集上预训练的模型。
- 冻结部分层:冻结预训练模型的部分层,防止其权重被更新。
- 添加新层:根据新任务的需求,在预训练模型的基础上添加新的层。
- 微调:在新数据集上进行训练,更新新层和未冻结的旧层的权重。
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