DAY 43 复习日

发布于:2025-06-27 ⋅ 阅读:(18) ⋅ 点赞:(0)

@浙大疏锦行https://blog.csdn.net/weixin_45655710

第一步:寻找并准备图像数据集

在Kaggle等平台上,你可以找到大量用于图像分类任务的数据集,例如英特尔图像分类数据集 (Intel Image Classification) 或手写数字识别数据集 (Digit Recognizer) 。

对于初学者,一个更便捷的选择是使用像TensorFlow或PyTorch这样深度学习框架内置的数据集,例如CIFAR-10。这个数据集包含了10个类别的60,000张32x32彩色图像,非常适合用于学习和实验3

数据加载与预处理

使用TensorFlow的Keras API可以轻松加载并准备CIFAR-10数据集。主要步骤包括加载数据和将像素值归一化到0到1的范围内,这有助于模型更快、更稳定地收敛。

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

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

# 将像素值归一化到0和1之间
train_images, test_images = train_images / 255.0, test_images / 255.0

# 类别名称
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',
               'dog', 'frog', 'horse', 'ship', 'truck']

第二步:构建并训练CNN模型

CNN是处理图像数据的核心工具。一个基础的CNN模型通常由卷积层(Conv2D)和池化层(MaxPooling2D)交替堆叠而成,最后连接全连接层进行分类。

构建模型

以下是一个简单的CNN模型结构示例,它包含三个卷积层,用于从输入图像中提取特征。

model = models.Sequential()
# 第一个卷积-池化层
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)))
model.add(layers.MaxPooling2D((2, 2)))
# 第二个卷积-池化层
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
# 第三个卷积层
model.add(layers.Conv2D(64, (3, 3), activation='relu'))

# 添加全连接层进行分类
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10)) # 输出层有10个节点,对应10个类别

model.summary()

编译与训练

模型构建完成后,需要进行编译,指定优化器、损失函数和评估指标。然后,使用fit方法在训练数据上进行训练。

# 编译模型
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))

第三步:使用Grad-CAM进行可视化

Grad-CAM(梯度加权类激活图)是一种可视化技术,它能生成一个热力图(heatmap),显示出图像中哪些区域对于模型的特定预测贡献最大。这对于理解和调试“黑箱”一样的深度学习模型非常有帮助。

Grad-CAM实现原理

  1. 选择目标层: 通常选择模型中最后一个卷积层的输出作为目标。

  2. 计算梯度: 计算模型对于某个类别的预测得分相对于目标层输出特征图(feature maps)的梯度。

  3. 权重计算: 对梯度图进行全局平均池化,得到每个特征图通道的“重要性”权重。

  4. 生成热力图: 将特征图与对应的权重相乘并求和,然后通过ReLU激活函数(只保留正值部分)生成最终的热力图。

  5. 叠加显示: 将标准化的热力图缩放到原始图像大小,并与原图叠加显示。

import numpy as np
import tensorflow as tf
import cv2

def make_gradcam_heatmap(img_array, model, last_conv_layer_name, pred_index=None):
    # 创建一个子模型,输出最后一个卷积层的激活图和模型的最终预测
    grad_model = tf.keras.models.Model(
        [model.inputs], [model.get_layer(last_conv_layer_name).output, model.output]
    )

    # 使用GradientTape记录梯度计算过程
    with tf.GradientTape() as tape:
        last_conv_layer_output, preds = grad_model(img_array)
        if pred_index is None:
            pred_index = tf.argmax(preds[0])
        class_channel = preds[:, pred_index]

    # 计算预测类别对于最后一个卷积层输出的梯度
    grads = tape.gradient(class_channel, last_conv_layer_output)
    
    # 计算每个通道的平均梯度,作为权重
    pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))

    # 将权重与特征图相乘,得到热力图
    last_conv_layer_output = last_conv_layer_output[0]
    heatmap = last_conv_layer_output @ pooled_grads[..., tf.newaxis]
    heatmap = tf.squeeze(heatmap)

    # 归一化热力图
    heatmap = tf.maximum(heatmap, 0) / tf.math.reduce_max(heatmap)
    return heatmap.numpy()

def display_gradcam(img, heatmap, alpha=0.4):
    # 将热力图调整为图像大小
    heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0]))
    heatmap = np.uint8(255 * heatmap)
    heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)

    # 将热力图叠加到原始图像上
    superimposed_img = heatmap * alpha + img * (1-alpha)
    superimposed_img = np.clip(superimposed_img, 0, 255).astype(np.uint8)

    return superimposed_img

通过调用这些函数,你可以看到模型在进行预测时,究竟“关注”了图像的哪个部分。例如,在识别一只猫时,热力图可能会高亮显示猫的脸部和耳朵区域。

进阶:将代码拆分成多个文件

当项目变得复杂时,将所有代码放在一个文件中会变得难以阅读和维护。将代码按功能拆分到不同文件中是一种良好的编程实践,这能提高代码的可读性、复用性和组织性。

为什么要拆分文件?

  • 关注点分离: 每个文件专注于一个特定功能,如数据处理、模型定义或可视化。

  • 提高可读性: 小而专注的文件更容易理解和导航。

  • 易于复用: 可以轻松地在项目的不同部分导入和重用特定功能的代码。

如何拆分?

你可以创建一个项目文件夹,并在其中创建多个.py文件。Python允许你使用import语句从同一目录下的其他文件中导入函数、类或变量。

一个典型的项目结构可能如下:

  • main.py: 项目主入口,负责调用其他模块,协调整个训练和评估流程。

  • data_loader.py: 包含加载和预处理数据的函数。

  • model.py: 定义CNN模型的结构。

  • gradcam.py: 包含make_gradcam_heatmap等可视化相关的函数。

  • train.py: 包含模型训练的逻辑。

  • visualize.py: 用于加载已训练好的模型,并对指定图像生成Grad-CAM可视化。

# model.py
from tensorflow.keras import layers, models

def create_cnn_model():
    model = models.Sequential([...]) # 省略模型定义代码
    return model
# train.py
from model import create_cnn_model
from data_loader import load_cifar10_data

# 加载数据
(train_images, train_labels), _ = load_cifar10_data()

# 创建并训练模型
model = create_cnn_model()
model.compile(...)
model.fit(...)
model.save('cifar10_cnn.h5')

网站公告

今日签到

点亮在社区的每一天
去签到