类别预测正确但特征图异常的问题求助
特征图可视化异常问题排查与平台适配建议
问题背景
基于ResNet50实现特征图可视化,模型类别预测结果正确,但生成的特征图存在异常:无论输入哪张图像,特征图都会在图像中部产生最强响应,且存在多区域异常响应。
实现代码
from torchvision.models.feature_extraction import create_feature_extractor # Data processing preprocess = transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize( mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225] )]) image_path = './data/test_images/anemone.jpg' image = Image.open(image_path).convert('RGB') img_processed = preprocess(image) batch_img_cat_tensor = torch.unsqueeze(img_processed, 0) # Model initialization resnet50_model = resnet50(weights=ResNet50_Weights.IMAGENET1K_V2) # Eval model for predictions resnet50_model.eval() # Creating feature extractor feature_extractor = create_feature_extractor(resnet50_model, return_nodes=['layer4.2.conv3', 'fc']) # Forward pass out = feature_extractor(batch_img_cat_tensor) pred = torch.argmax(out['fc']) # Transforming last conv output to numpy and reshaping it so that the channels would be last last_conv_output = torch.squeeze(out['layer4.2.conv3']) last_conv_output = torch.reshape(last_conv_output, (7, 7, -1)) last_conv_output = last_conv_output.detach().numpy() last_conv_output = last_conv_output.astype(np.uint8) # Calculating the upscale factors for last conv output width_factor = int(image.size[0] / last_conv_output.shape[0]) height_factor = int(image.size[1] / last_conv_output.shape[1]) # Getting the shapes of the last conv output last_conv_w, last_conv_h, n_channels = last_conv_output.shape # Calculate the upscaled_h = last_conv_h * height_factor upscaled_w = last_conv_w * width_factor # Upscaling the last_conv_output so that it could be "masked" with original image upsampled_last_conv_output = np.zeros((upscaled_h, upscaled_w, n_channels)) upsampled_last_conv_output = [] for x in range(0, n_channels, 512): upsampled_last_conv_output.append(cv2.resize(last_conv_output[:, :, x:x+512], (upscaled_w, upscaled_h), cv2.INTER_CUBIC)) upsampled_last_conv_output = np.concatenate(upsampled_last_conv_output, axis=2) # Getting the weights of the predicted class last_layer_weights = resnet50_model.fc.weight.T last_layer_weights_for_pred = last_layer_weights[:, pred] # Dot multiplying the upsampled_last_conv_output with last_layer_weights_for_pred upsampled_last_conv_output = upsampled_last_conv_output.reshape((-1, 2048)) heat_map = np.dot(upsampled_last_conv_output, last_layer_weights_for_pred.detach().numpy()).reshape(upscaled_h, upscaled_w) # Plotting the results fig, ax = plt.subplots() ax.imshow(image) ax.imshow(heat_map, cmap='jet', alpha=0.5) ax.set_title(prediction)
异常原因排查方向
- 特征值截断错误:代码中将卷积层输出直接转换为
np.uint8,但ResNet卷积层ReLU后的输出数值通常远小于255,强制转换会导致大量特征值被截断为0,丢失有效信息,进而导致热力图响应异常。 - 热力图未归一化:生成的
heat_map未做0-1或0-255范围的归一化处理,直接叠加到原图上时,数值范围异常会导致响应区域显示偏差。 - 冗余代码干扰:先初始化
upsampled_last_conv_output为数组后又重新赋值为空列表,虽不影响运行,但可能增加调试复杂度,建议简化逻辑。
平台适配建议
该问题属于深度学习模型可视化的代码调试类问题,涉及PyTorch特征提取、热力图生成的技术细节,完全适合发布到AI Stack Exchange。发布时需附上完整代码、异常效果截图、已确认的正确预测结果,以便其他开发者快速定位问题。
内容的提问来源于stack exchange,提问作者artas2357
相关产品推荐
相关产品推荐

