打卡Day43

Dogs vs. Cats(猫狗大战)项目

数据预处理

import numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator

# 数据集路径(注意 Windows 路径需用双反斜杠或原始字符串)
train_dir = r"D:\python训练营\dogs-vs-cats\train"

# 数据增强与归一化
train_datagen = ImageDataGenerator(
    rescale=1./255,
    validation_split=0.2,  # 80% 训练,20% 验证
    rotation_range=20,
    zoom_range=0.2,
    horizontal_flip=True
)

# 加载数据
train_generator = train_datagen.flow_from_directory(
    train_dir,
    target_size=(224, 224),  # 调整图像尺寸(根据数据集选择)
    batch_size=32,
    class_mode='binary',  # 二分类(猫 vs 狗)
    subset='training'
)

val_generator = train_datagen.flow_from_directory(
    train_dir,
    target_size=(224, 224),
    batch_size=32,
    class_mode='binary',
    subset='validation'
)

构建并训练 CNN 模型

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense

# 定义 CNN 模型
model = Sequential([
    Conv2D(32, (3,3), activation='relu', input_shape=(224,224,3)),
    MaxPooling2D((2,2)),
    Conv2D(64, (3,3), activation='relu'),
    MaxPooling2D((2,2)),
    Conv2D(128, (3,3), activation='relu'),
    MaxPooling2D((2,2)),
    Flatten(),
    Dense(512, activation='relu'),
    Dense(1, activation='sigmoid')  # 二分类输出
])

# 编译模型
model.compile(
    optimizer='adam',
    loss='binary_crossentropy',
    metrics=['accuracy']
)

# 训练模型
history = model.fit(
    train_generator,
    epochs=10,
    validation_data=val_generator
)

Grad-CAM 可视化

实现 Grad-CAM

import cv2
import matplotlib.pyplot as plt
from tensorflow.keras.models import Model

def grad_cam(model, img_array, layer_name, eps=1e-8):
    # 获取模型和特定卷积层
    grad_model = Model(
        inputs=[model.inputs],
        outputs=[model.get_layer(layer_name).output, model.output]
    )
    
    # 计算梯度
    with tf.GradientTape() as tape:
        conv_outputs, predictions = grad_model(img_array)
        loss = predictions[:, 0]  # 适用于二分类
    
    # 计算梯度
    grads = tape.gradient(loss, conv_outputs)
    pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
    
    # 生成热力图
    conv_outputs = conv_outputs[0]
    heatmap = conv_outputs @ pooled_grads[..., tf.newaxis]
    heatmap = tf.squeeze(heatmap)
    heatmap = tf.maximum(heatmap, 0) / (tf.math.reduce_max(heatmap) + eps)
    return heatmap.numpy()

def overlay_heatmap(img, heatmap, alpha=0.5):
    # 调整热力图颜色
    heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0]))
    heatmap = np.uint8(255 * heatmap)
    heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
    superimposed_img = cv2.addWeighted(img, alpha, heatmap, 1-alpha, 0)
    return superimposed_img

加载测试图像并生成热力图

# 加载单张图像
img_path = 'dataset/test/dog.1234.jpg'  # 替换为你的测试图像路径
img = tf.keras.preprocessing.image.load_img(img_path, target_size=(224, 224))
img_array = tf.keras.preprocessing.image.img_to_array(img)
img_array = np.expand_dims(img_array, axis=0) / 255.0  # 归一化

# 选择最后一个卷积层(根据模型结构)
layer_name = 'conv2d_2'  # 替换为你的模型中最后一个卷积层名称

# 生成热力图
heatmap = grad_cam(model, img_array, layer_name)

# 可视化
plt.figure(figsize=(10, 6))
plt.subplot(1, 2, 1)
plt.imshow(img_array[0])
plt.title('Original Image')

plt.subplot(1, 2, 2)
plt.imshow(heatmap, cmap='jet')
plt.title('Grad-CAM Heatmap')
plt.show()

# 叠加热力图到原图
img = cv2.imread(img_path)
img = cv2.resize(img, (224, 224))
superimposed_img = overlay_heatmap(img, heatmap)

plt.imshow(cv2.cvtColor(superimposed_img, cv2.COLOR_BGR2RGB))
plt.title('Grad-CAM Overlay')
plt.axis('off')
plt.show()

需要注意的主要有两点:
(1)确保路径与代码中一致
(2)注意内存,可采取减小 batch_size 或使用更小的输入尺寸(如 (128, 128))。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值