```
import numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout
import matplotlib.pyplot as plt
import cv2
tf.random.set_seed(42)
# 定义路径
train_dir = r'C:\Users\29930\Desktop\结构参数图'
validation_dir = r'C:\Users\29930\Desktop\测试集路径' # 需要实际路径
# 图像参数
img_width, img_height = 150, 150
batch_size = 32
# 数据生成器
train_datagen = ImageDataGenerator(
rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
train_dir, # 修改为实际路径
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
validation_dir, # 修改为实际路径
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='binary')
# 模型构建
model = Sequential([
Conv2D(32, (3,3), activation='relu', input_shape=(img_width, img_height, 3)),
MaxPooling2D(2,2),
Conv2D(64, (3,3), activation='relu'),
MaxPooling2D(2,2),
Flatten(),
Dense(128, activation='relu'),
Dropout(0.5),
Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
# 训练模型
history = model.fit(
train_generator,
steps_per_epoch=len(train_generator),
epochs=20,
validation_data=validation_generator,
validation_steps=len(validation_generator))
# Grad-CAM函数修正版
def generate_grad_cam(model, img_array, layer_name):
# 创建梯度模型
grad_model = tf.keras.models.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 = tf.reduce_sum(conv_outputs * pooled_grads, axis=-1)
# 归一化处理
heatmap = np.maximum(heatmap, 0)
heatmap /= np.max(heatmap)
return heatmap
# 可视化部分
X, y = next(validation_generator)
sample_image = X[0]
img_array = np.expand_dims(sample_image, axis=0)
# 获取最后一个卷积层(根据模型结构调整索引)
last_conv_layer = model.layers[2] # 第二个Conv2D层
heatmap = generate_grad_cam(model, img_array, last_conv_layer.name)
# 调整热力图尺寸
heatmap = cv2.resize(heatmap, (img_width, img_height))
heatmap = np.uint8(255 * heatmap)
# 颜色映射
jet = plt.colormaps.get_cmap('jet')
jet_colors = jet(np.arange(256))[:, :3]
jet_heatmap = jet_colors[heatmap]
# 叠加显示
superimposed_img = jet_heatmap * 0.4 + sample_image
superimposed_img = np.clip(superimposed_img, 0, 1)
# 绘制结果
plt.figure(figsize=(12, 4))
plt.subplot(131)
plt.imshow(sample_image)
plt.title('原始图像')
plt.axis('off')
plt.subplot(132)
plt.imshow(heatmap, cmap='jet')
plt.title('热力图')
plt.axis('off')
plt.subplot(133)
plt.imshow(superimposed_img)
plt.title('叠加效果')
plt.axis('off')
plt.tight_layout()
plt.show()```完善代码使在构建模型后,调用模型初始化各层形状,随后指定输入形状并通过实际数据前向传播来触发形状推断.输出完整代码
最新发布