对B站up同济子豪兄的图像分类系列的学习(大佬的完整代码在GitHub开源)
2022年人工智能依旧飞速发展,从传统机器学习模型到如今以“炼丹”为主的深度神经网络,代表着模型拟合度与模型可解释性各自的发展趋势。至此,深刻体会并成功解释NN为何能取得更优的效果成为各行各业的新目标,而可解释性机器学习便应运而生。
感想:愈发感受到自己基础的薄弱了,今天的任务涉及的算法较多且深,短时间内恐怕是只能当个调包侠了,如果有和我一样基础薄弱的朋友可以一同前往子豪大佬的B站视频学习:
同济子豪兄的个人空间-同济子豪兄个人主页-哔哩哔哩视频
可解释性分析-论文集
大白话讲解卷积神经网络工作原理_哔哩哔哩_bilibili
CAM可解释性分析-算法讲解_哔哩哔哩_bilibili
torch-cam的安装方式如下:
# 下载安装 torch-cam
git clone https://github.com/frgfm/torch-cam.git
pip install -e torch-cam/.
安装之后在jupyterlab中充气内核,导入torchcam检查是否安装成功。
torchcam有两种使用方式,一种是直接通过命令行使用,另一种是在代码中导入。
python torch-cam/scripts/cam_example.py --help
--help参数查看torch-cam的基本用法。
usage: cam_example.py [-h] [--arch ARCH] [--img IMG] [--class-idx CLASS_IDX] [--device DEVICE] [--savefig SAVEFIG] [--method METHOD] [--alpha ALPHA] [--rows ROWS] [--noblock] Saliency Map comparison optional arguments: -h, --help show this help message and exit --arch ARCH Name of the architecture (default: resnet18) --img IMG The image to extract CAM from (default: https://www.woopets.fr/assets/races/000/066/big- portrait/border-collie.jpg) --class-idx CLASS_IDX Index of the class to inspect (default: 232) --device DEVICE Default device to perform computation on (default: None) --savefig SAVEFIG Path to save figure (default: None) --method METHOD CAM method to use (default: None) --alpha ALPHA Transparency of the heatmap (default: 0.5) --rows ROWS Number of rows for the layout (default: 1) --noblock Disables blocking visualization (default: False)
下面是通过命令行的使用方式
python torch-cam/scripts/cam_example.py \
--img test_img/border-collie.jpg \
--savefig output/B1_border_collie.jpg \
--arch resnet18 \
--class-idx 232 \
--rows 2
如图参数如同字面意思好理解。运行torchcam中的CAM范例文件,读如一张图片(img),处理后保存到(savefig)路径下arch就是architecture,在此处表示针对哪种模型,class-idx表示针对的类别,rows表示行数。
“CAM会对网络最后的特征图进行加权求和,就可以得到一个注意力的机制(就是卷积神经网络更关注图片的什么地方)。”通过这个有助于我们人类研究人工智能(机器学习、深度学习)的思考方式,从而着手处理。
比较常见的例子是区分雪豹和阿拉伯豹的任务中,分类器的注意力实际上集中在背景上,通过生活的背景区分豹子而不是豹子本身。子豪大佬的视频中也提到了给熊猫图片加上噪声之后,被识别为长臂猿的例子。这些例子表明,我们有需要通过了解人工智能的思维方式来对人工智能算法进行进一步的优化。
下面的步骤使得我们得到了一个CAM的矩阵。这里用的是SmoothGradCAMpp的算法,它的速度较慢,效果较好。而速度相对较快的是CAM和Grad_CAM算法。
from torchcam.methods import SmoothGradCAMpp
# CAM GradCAM GradCAMpp ISCAM LayerCAM SSCAM ScoreCAM SmoothGradCAMpp XGradCAM
cam_extractor = SmoothGradCAMpp(model)
activation_map = cam_extractor(pred_id, pred_logits)
activation_map = activation_map[0][0].detach().cpu().numpy()
得到了矩阵之后若将他进行可视化,得到的是一个7*7的图像,得到的矩阵是多少更选择的模型有关,这里是7*7是由于resnet18这个模型的某一层(好像可解释性学习在去年12月份专门作为系列任务出现,那时我没有参加,现在想在一个任务中完成还是太勉强了,还是继续学习吧,悲)
然后我们通过torchcam库自带的一个函数就可以把它投射到原图上。
rom torchcam.utils import overlay_mask
result = overlay_mask(img_pil, Image.fromarray(activation_map), alpha=0.7)
alpha的值仍然是透明度,在这里直观地表现为原图的亮暗程度。
pip install grad-cam torchcam
git clone https://github.com/jacobgil/pytorch-grad-cam.git
还是通过import pytorch_grad_cam来验证安装成功。
grad-CAM:利用梯度作为特征图的权重。
CAM最重要的是两部分,一是特征图,一是特征图所对应的权重。grad-CAM就是利用梯度的方法找权重。
这样,Grad-CAM就不像CAM算法那样需要网络上有一个全局平均池化层,具有更大的适用范围。
由于Grad-CAM存在的一些缺点,如“浅层权重方差变化大,不能使用梯度均值为特征图每个像素赋予同等重要度”,衍生出了一系列算法,比如LayerCAM。
LayerCAM:基于元素的,每一张特征图中每一个元素都有一个对应的权重。
此外还有 Grad-CAMpp,ScoreCAM等衍生算法。
对单张图像,进行Guided Grad-CAM可解释性分析,绘制既具有类别判别性(Class-Discriminative),又具有高分辨率的细粒度热力图。
效果展示:
如果去看了源码的话可以知道实际上我们期望的是只显示出狗头,而这个Guided Backpropagation算法还显示出了猫头,所以采用了该图像和Grad-CAM热力图逐元素相乘的方式,结果如下:
这里子豪大佬给出了一个思考题:
Guided Backpropagation确实兼顾了高分辨率和class-discriminative,唯一美中不足的就是可视化效果太不锐利
是否可以进行进一步的图像处理,更适合人眼来看
说实话,我感到这个图像已经很适合人眼来看了,也不太明白可视化效果不太锐利是什么意思。是增加锐度的话可以做个卷积核,但显然不是这个意思。如果是要更突出的话,那么是不是要把狗头着一块(颜色波动明显)用原图覆盖呢。
对单张图像,进行Deep Feature Factorization可解释性分析,展示Concept Discovery概念发现图。参考阅读如下:
GitHub - jacobgil/pytorch-grad-cam: Advanced AI Explainability for computer vision. Support for CNNs, Vision Transformers, Classification, Object detection, Segmentation, Image similarity and more.
Deep Feature Factorizations for better model explainability — Advanced AI explainability with pytorch-gradcam
https://arxiv.org/abs/1806.10206
通过获取每个concept对应的类别来做到这张图像。
我是越来越觉得可解释性分析和语义分割有关系了,似乎都是弱监督,但我很菜没学过,我还是表达以下期待吧。
封装函数如下:
def dff_show(img_path='test_img/cat_dog.jpg', n_components=5, top_k=2, hstack=False):
img, rgb_img_float, input_tensor = get_image_from_path(img_path)
dff = DeepFeatureFactorization(model=model,
target_layer=model.layer4,
computation_on_concepts=classifier)
concepts, batch_explanations, concept_outputs = dff(input_tensor, n_components)
concept_outputs = torch.softmax(torch.from_numpy(concept_outputs), axis=-1).numpy()
concept_label_strings = create_labels(concept_outputs, top_k=top_k)
visualization = show_factorization_on_image(rgb_img_float,
batch_explanations[0],
image_weight=0.3, # 原始图像透明度
concept_labels=concept_label_strings)
if hstack:
result = np.hstack((img, visualization))
else:
result = visualization
display(Image.fromarray(result))
直接使用pip安装这个包即可。
遮挡可解释性分析
在输入图像上,用遮挡滑块,滑动遮挡不同区域,探索哪些区域被遮挡后会显著影响模型的分类决策。
提示:因为每次遮挡都需要分别单独预测,因此代码运行可能需要较长时间。
我们可以改变遮挡滑块的大小。
下面代码以小滑块为例。
# 更改遮挡滑块的尺寸
attributions_occ = occlusion.attribute(input_tensor,
strides = (3, 2, 2), # 遮挡滑动移动步长
target=pred_id, # 目标类别
sliding_window_shapes=(3, 4, 4), # 遮挡滑块尺寸
baselines=0)
# 转为 224 x 224 x 3的数据维度
attributions_occ_norm = np.transpose(attributions_occ.detach().cpu().squeeze().numpy(), (1,2,0))
viz.visualize_image_attr_multiple(attributions_occ_norm, # 224 224 3
rc_img_norm, # 224 224 3
["original_image", "heat_map"],
["all", "positive"],
show_colorbar=True,
outlier_perc=2)
plt.show()
Integrated Gradients 原理
输入图像像素由空白变为输入图像像素的过程中,
模型预测为某一特定类别的概率
相对于输入图像像素
的梯度积分。
noise_tunnel = NoiseTunnel(integrated_gradients)
# 获得输入图像每个像素的 IG 值
attributions_ig_nt = noise_tunnel.attribute(input_tensor, nt_samples=12, nt_type='smoothgrad_sq', target=pred_id)
# 转为 224 x 224 x 3的数据维度
attributions_ig_nt_norm = np.transpose(attributions_ig_nt.squeeze().cpu().detach().numpy(), (1,2,0))
# 设置配色方案
default_cmap = LinearSegmentedColormap.from_list('custom blue',
[(0, '#ffffff'),
(0.25, '#000000'),
(1, '#000000')], N=256)
viz.visualize_image_attr_multiple(attributions_ig_nt_norm, # 224 224 3
rc_img_norm, # 224 224 3
["original_image", "heat_map"],
["all", "positive"],
cmap=default_cmap,
show_colorbar=True)
plt.show()
QAQ我是在是弄不明白了,真应该在过年那段时间提前做任务的。看看视频吧。
可解释机器学习公开课_哔哩哔哩_bilibili
根据实例分割标注图,分别除去图像中的不同语义分组区域,观察对模型预测结果的影响。
feature group 特征分组
在实例分割标注图中,每一个类别都被划为一类 feature group。
Feature Ablation 就是分析每个 feature group 存在(或者不存在)的影响。
参考教程:Captum · Model Interpretability for PyTorch
直接pip安装即可。
预备知识
图像分类全流程:构建数据集、训练模型、预测新图、测试集评估、可解释性分析、终端部署
视频教程:构建自己的图像分类数据集【两天搞定AI毕设】_哔哩哔哩_bilibili
代码教程:GitHub - TommyZihao/Train_Custom_Dataset: 标注自己的数据集,训练、评估、测试、部署自己的人工智能算法
UCI心脏病二分类+可解释性分析:【子豪兄Kaggle】玩转UCI心脏病二分类数据集_哔哩哔哩_bilibili
shap工具包相关
shap工具包:GitHub - slundberg/shap: A game theoretic approach to explain the output of any machine learning model.
shap工具包论文:https://proceedings.neurips.cc/paper/2017/file/8a20a8621978632d76c43dfd28b67767-Paper.pdf
DataWhale公众号推送【6个机器学习可解释性框架!】:6个机器学习可解释性框架!
直接pip安装即可。
推荐视频¶
LIME论文逐句精读:同济子豪兄的个人空间-同济子豪兄个人主页-哔哩哔哩视频
图像分类可解释性分析实战-shap工具包:图像分类可解释性分析实战-shap工具包_哔哩哔哩_bilibili
UCI心脏病二分类+可解释性分析:【子豪兄Kaggle】玩转UCI心脏病二分类数据集_哔哩哔哩_bilibili
公开课
【同济子豪兄“两天搞定AI毕业设计之【图像分类】”公开课】
图像分类全流程:构建数据集、训练模型、预测新图、测试集评估、可解释性分析、终端部署
视频合集:同济子豪兄的个人空间-同济子豪兄个人主页-哔哩哔哩视频
代码:GitHub - TommyZihao/Train_Custom_Dataset: 标注自己的数据集,训练、评估、测试、部署自己的人工智能算法
【同济子豪兄可解释机器学习公开课】
包含人工智能可解释性、显著性分析领域的导论、算法综述、经典论文精读、代码实战、前沿讲座。
课程主页:zihao_course/XAI at main · TommyZihao/zihao_course · GitHub
博客链接
lime工具包:https://github.com/marcotcr/lime
DataWhale公众号推送【6个机器学习可解释性框架!】:6个机器学习可解释性框架!
https://towardsdatascience.com/lime-how-to-interpret-machine-learning-models-with-python-94b0e7e4432e
代码运行云GPU平台:Featurize