深度学习:Matplotlib篇

一、简介

1.1 什么是 Matplotlib?

Matplotlib 是一个广泛使用的 2D 绘图库,它可以用来在 Python 中创建各种静态、动态和交互式的图表。无论是科学计算、数据可视化,还是深度学习模型的训练与评估,Matplotlib 都能提供强大的图形展示功能。在深度学习领域,Matplotlib 通常用于可视化训练过程中的损失函数、准确率曲线以及各种训练结果

1.2 为什么会在深度学习中使用 Matplotlib?

在深度学习中,使用 Matplotlib 可以帮助开发者和研究人员更直观地理解模型的性能。常见的应用包括:

  • 绘制训练过程中的损失和精度曲线,以监控模型是否过拟合或欠拟合
  • 展示分类模型的混淆矩阵,以可视化分类错误类型
  • 可视化图像特征或特征图,以深入理解卷积神经网络(CNN)内部的工作机制

二、基本使用方法

2.1 导入

在使用之前,需要先导入其主要模块。一般来说我们会将 Matplotlib.pyplot 模块导入并简写为 plt,为了代码看起来简洁

import matplotlib.pyplot as plt

2.2 基本绘图操作

这里以折线图为例

# 创建一些数据
x = [1, 2, 3, 4, 5]
y = [1, 4, 9, 16, 25]

# 绘制折线图
plt.plot(x, y)

# 显示图像
plt.show()

2.3 标题、标签与图例

添加标题、轴标签以及图例让图表更具信息性

plt.plot(x, y, label='y = x^2')
plt.title('Example of a Line Plot')
plt.xlabel('X Axis')
plt.ylabel('Y Axis')
plt.legend()
plt.show()

2.4 调整图像样式

Matplotlib 支持多种样式的图表,如折线图、柱状图、散点图等。在绘图时,我们也可以调整线条颜色、样式以及图形的其他参数

plt.plot(x, y, color='green', linestyle='--', marker='o', label='y = x^2')
plt.title('Customized Line Plot')
plt.xlabel('X Axis')
plt.ylabel('Y Axis')
plt.legend()
plt.show()

三、在深度学习中的应用

3.1 可视化训练过程

在深度学习模型训练过程中,最常见的做法是通过 Matplotlib 绘制训练和验证集上的损失曲线及准确率曲线。这些图表能够帮助我们判断模型的表现,分析是否存在过拟合或欠拟合的现象

import matplotlib.pyplot as plt

# 假设有训练和验证的损失和准确率数据 随便取的
epochs = range(1, 11)
train_loss = [0.8, 0.6, 0.4, 0.3, 0.2, 0.15, 0.1, 0.08, 0.06, 0.04]
val_loss = [0.9, 0.7, 0.5, 0.4, 0.3, 0.25, 0.22, 0.21, 0.2, 0.19]

# 绘制损失曲线
plt.plot(epochs, train_loss, 'bo-', label='Training loss')
plt.plot(epochs, val_loss, 'ro-', label='Validation loss')
plt.title('Training and Validation Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()

通过这种方法,我们就可以很直观地观察模型在每个 epoch 训练后的损失变化趋势,尤其是训练集和验证集的差异可以帮助判断是否发生过拟合

3.2 可视化卷积神经网络的特征图

在深度学习中,卷积神经网络(CNN)可以学习到图像的层次化特征。在某些场景下,我们希望可视化这些特征图,以更好地理解网络的工作机制。这时就可以通过 Matplotlib 将卷积层的输出特征图绘制出来

import torch
import matplotlib.pyplot as plt

# 假设我们有一个 CNN 模型和一张输入图像
model = ...
image = ...

# 获取卷积层的输出
features = model.conv1(image)

# 可视化第一层卷积后的特征图
fig, axarr = plt.subplots(1, 4)
for idx in range(4):
    axarr[idx].imshow(features[0, idx].detach().numpy(), cmap='gray')
plt.show()

给你们补全一下

import torch  
import torch.nn as nn  
import torchvision.transforms as transforms  
from PIL import Image  
import matplotlib.pyplot as plt  
  
# 定义一个简单的 CNN 模型  
class SimpleCNN(nn.Module):  
    def __init__(self):  
        super(SimpleCNN, self).__init__()  
        self.conv1 = nn.Conv2d(in_channels=3, out_channels=4, kernel_size=3, stride=1, padding=1)  
        # 添加其他层如果需要的话,这里仅作为示例  
  
    def forward(self, x):  
        x = self.conv1(x)  
        # x = ... 其他操作  
        return x  
  
# 实例化模型  
model = SimpleCNN()  
  
# 将模型移动到 GPU(如果可用),或者保持在 CPU 上  
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")  
model.to(device)  
  
# 加载并预处理一张图像  
# 假设我们使用一张 RGB 图像,尺寸为 224x224(根据模型需求调整)  
transform = transforms.Compose([  
    transforms.Resize((224, 224)),  
    transforms.ToTensor(),  # 将图像转换为 PyTorch 张量,并归一化到 [0, 1]  
])  
  
# 这里我们加载一个示例图像,你需要提供实际的图像路径  
image_path = 'path_to_your_image.jpg'  # 替换为你的图像路径  
image = Image.open(image_path).convert('RGB')  
image = transform(image).unsqueeze(0)  # 增加一个 batch 维度  
image = image.to(device)  # 确保图像在正确的设备上  
  
# 获取卷积层的输出  
with torch.no_grad():  # 我们不需要计算梯度  
    features = model.conv1(image)  
  
# 可视化第一层卷积后的特征图  
features = features.squeeze(0).cpu()  # 移除 batch 维度,并移动到 CPU  
fig, axarr = plt.subplots(1, 4, figsize=(12, 3))  
for idx in range(4):  
    axarr[idx].imshow(features[idx, :, :].numpy(), cmap='gray')  # 注意这里的索引可能需要根据实际的输出形状调整  
    axarr[idx].axis('off')  # 关闭坐标轴  
plt.show()

 看看效果:

原图:

3.3 混淆矩阵的可视化

混淆矩阵用于衡量分类模型性能,它、可以直观展示模型在不同类别上的分类正确率和错误率

import seaborn as sns
from sklearn.metrics import confusion_matrix

# 假设我们有预测值和真实值
y_true = [0, 1, 2, 2, 0, 1, 1, 2]
y_pred = [0, 0, 2, 2, 0, 2, 1, 2]

# 计算混淆矩阵
cm = confusion_matrix(y_true, y_pred)

# 可视化混淆矩阵
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
plt.title('Confusion Matrix')
plt.xlabel('Predicted')
plt.ylabel('True')
plt.show()

这种可视化方法可以帮助我们深入分析模型在哪些类别上分类错误较多,进而做出相应的改进措施

四、进阶技巧

4.1 子图与多图显示

在深度学习中,往往需要同时观察多个图表(如损失和准确率),这时可以通过 subplot 函数来实现多个子图的排列显示

import matplotlib.pyplot as plt  
import numpy as np  
  
# 假设我们已经有了一些训练数据  
# 这些数据通常是在训练循环中收集的  
  
# 示例数据(您应该使用您的实际数据替换这些)  
epochs = np.arange(1, 21)  # 假设我们训练了20个epoch  
train_loss = np.linspace(0.5, 0.1, 20)  # 假设训练损失从0.5线性降低到0.1  
val_loss = np.linspace(0.55, 0.15, 20)  # 假设验证损失从0.55线性降低到0.15  
train_acc = np.linspace(0.5, 0.9, 20)   # 假设训练准确率从0.5线性增加到0.9  
val_acc = np.linspace(0.45, 0.85, 20)   # 假设验证准确率从0.45线性增加到0.85  
  
# 创建子图  
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))  
  
# 绘制第一个图(损失曲线)  
ax1.plot(epochs, train_loss, 'b-', label='Training loss')  
ax1.plot(epochs, val_loss, 'r-', label='Validation loss')  
ax1.set_title('Loss Over Epochs')  
ax1.set_xlabel('Epochs')  
ax1.set_ylabel('Loss')  
ax1.legend()  
ax1.grid(True)  # 可选:添加网格线  
  
# 绘制第二个图(准确率曲线)  
ax2.plot(epochs, train_acc, 'b-', label='Training accuracy')  
ax2.plot(epochs, val_acc, 'r-', label='Validation accuracy')  
ax2.set_title('Accuracy Over Epochs')  
ax2.set_xlabel('Epochs')  
ax2.set_ylabel('Accuracy')  
ax2.legend()  
ax2.grid(True)  # 可选:添加网格线  
  
# 显示图形  
plt.tight_layout()  # 可选:调整子图之间的间距  
plt.show()

4.2 动态绘图

在深度学习训练过程中,有时我们希望能实时查看训练的进展。这时可以利用 Matplotlib 的动态绘图功能,通过 plt.ion() 实现图表的实时更新

import matplotlib.pyplot as plt  
import random  # 用于生成模拟数据  
  
# 初始化列表  
epochs = []  
train_loss = []  
val_loss = []  
  
# 开启交互模式  
plt.ion()  
  
# 模拟10个epoch的训练过程  
for epoch in range(10):  
    # 更新epochs列表(虽然在这种情况下,我们可以直接使用range(11)来绘制,但为了与您的代码一致,我们还是更新这个列表)  
    epochs.append(epoch + 1)  
      
    # 模拟新的训练损失和验证损失(在实际应用中,这些值将来自您的训练循环)  
    new_train_loss = random.uniform(0.1, 1.0)  # 生成一个0.1到1.0之间的随机浮点数  
    new_val_loss = random.uniform(0.1, 1.0)    # 生成另一个0.1到1.0之间的随机浮点数  
      
    # 将新的损失值添加到列表中  
    train_loss.append(new_train_loss)  
    val_loss.append(new_val_loss)  
      
    # 清除上一帧图像  
    plt.clf()  
      
    # 绘制新的曲线  
    plt.plot(epochs, train_loss, 'b-', label='Training loss')  
    plt.plot(epochs, val_loss, 'r-', label='Validation loss')  
    plt.xlabel('Epoch')  
    plt.ylabel('Loss')  
    plt.title('Loss Over Epochs')  
    plt.legend()  
    plt.grid(True)  # 可选:添加网格线  
      
    # 暂停一段时间以更新图形(0.1秒)  
    plt.pause(0.1)  
  
# 关闭交互模式(在显示最终图形之前通常不需要这样做,因为plt.show()会处理它)  
# 但为了与您的代码一致,我们还是包含了这个调用  
plt.ioff()  
  
# 显示最终图形(在交互模式下,这通常不是必需的,因为图形已经在循环中更新了)  
# 但由于我们包含了plt.ioff(),所以我们需要调用plt.show()来确保图形显示出来  
plt.show()

上一篇:【Linux】Package Manager Instructions


下一篇:基于YOLOv8深度学习的智能道路裂缝检测与分析系统【python源码+Pyqt5界面+数据集+训练代码】