特征图可视化:验证阶段前向传播时为何显示为灰度图?
为什么你的特征图可视化是灰度的?解决方案在这里
嘿,我仔细看了你的代码和问题,一下子就找到根源了——你现在输出灰度图,完全是因为你的可视化逻辑把多通道特征图给压缩成了单通道的统计值,之后再重复成三通道时,三个通道的像素值完全一致,自然就显示成灰度了。来给你一步步拆解:
问题根源
你的代码里这两行是关键:
mean = np.repeat(data.mean(-1, keepdims=True),3 ,2) max = np.repeat(data.max(-1, keepdims=True), 3, 2)
data.mean(-1)是对每个像素的所有通道取平均值,直接把原本的多通道特征图(H,W,C)压缩成了单通道的均值图(H,W,1),之后用repeat扩展成三通道时,每个像素的R、G、B值都一样,这可不就是灰度图嘛!同理,取通道最大值的操作也是一样的逻辑,哪怕你加了cmap='plasma',但因为三通道值相同,配色表也发挥不了作用。
而且本质上,你现在可视化的根本不是特征图本身,而是特征图的通道统计值,这和你想要看特征图的目标完全偏离了。
针对性解决方案
根据你想要非灰度特征图的需求,分两种情况给你调整方案:
情况1:你的特征图是多通道(比如CNN中间层的多通道特征)
如果特征图本身有多个通道,我们可以直接可视化通道信息:
方案A:查看单个通道的特征分布(带彩色配色)
如果你想聚焦某一个通道的特征,可以直接选择这个通道,搭配彩色配色表来显示:
def vis_tensor(data): data = data.data.cpu().numpy() # 取出batch里的第一个样本,转成(H, W, 通道数)的格式 data = data[0].transpose((1, 2, 0)) # 归一化到0-255范围,加1e-8避免除零错误 data = (data - data.min()) / (data.max() - data.min() + 1e-8) data = (data * 255).astype('uint8') # 可视化第0个通道,用plasma彩色配色 pylab.imshow(data[..., 0], cmap='plasma') pylab.colorbar() # 可选,显示颜色对应的数值范围 pylab.savefig('single_channel_feat.png') pylab.close() # 一定要关闭画布,避免后续图像叠加
方案B:将多通道特征映射到RGB空间(适合通道数较多的情况)
如果特征通道数很多(比如几十上百个),可以用PCA把高维通道压缩到3通道,转换成RGB图像可视化:
from sklearn.decomposition import PCA def vis_tensor(data): data = data.data.cpu().numpy() # 取出第一个样本,把(channels, H, W)转成(H*W, channels)的格式 feat_flatten = data[0].reshape(data[0].shape[0], -1).T # PCA降维到3通道 pca = PCA(n_components=3) feat_rgb = pca.fit_transform(feat_flatten) # 归一化并转回(H, W, 3)的图像格式 feat_rgb = (feat_rgb - feat_rgb.min()) / (feat_rgb.max() - feat_rgb.min() + 1e-8) feat_rgb = (feat_rgb * 255).astype('uint8').reshape(data[0].shape[1], data[0].shape[2], 3) pylab.imshow(feat_rgb) pylab.savefig('pca_rgb_feat.png') pylab.close()
情况2:你的特征图本身是单通道
如果特征图就是单通道,想要彩色显示,只需要在imshow时指定彩色配色表就行,完全不需要重复通道:
def vis_tensor(data): data = data.data.cpu().numpy() data = data[0].transpose((1, 2, 0)) # 此时shape是(H,W,1) # 归一化处理 data = (data - data.min()) / (data.max() - data.min() + 1e-8) data = (data * 255).astype('uint8') # 直接用彩色配色表可视化单通道特征 pylab.imshow(data[..., 0], cmap='viridis') pylab.colorbar() pylab.savefig('single_channel_color.png') pylab.close()
额外小提醒
每次调用pylab.savefig后一定要记得调用pylab.close(),不然后续的图像会叠加到之前的画布上,导致显示出来的图乱掉哦!
内容的提问来源于stack exchange,提问作者Y0shimitsu
相关产品推荐
相关产品推荐

