Google Research Activation Clustering:基于无监督聚类的深度神经网络可解释性实战指南
2026/9/20 4:01:53 网站建设 项目流程

Google Research Activation Clustering:基于无监督聚类的深度神经网络可解释性实战指南

【免费下载链接】google-researchGoogle Research项目地址: https://gitcode.com/gh_mirrors/go/google-research

导读

本文围绕 google-research 仓库中的activation_clustering项目,讲解如何利用"激活聚类"(Activation Clustering)技术,对已训练好的深度分类模型进行解释:通过无监督聚类模型学习网络中间层激活的潜在结构,进而得到可替代原模型的白盒"代理模型"(surrogate model),并据此检索与测试样本相似的训练样本、提炼网络内部"概念"(concept)。读完本文,你将掌握该模型的完整安装启动流程、训练与可视化配置方法,以及其核心实现原理。

项目定位与核心思想

activation_clustering是论文 Explaining Deep Neural Networks using Unsupervised Clustering(arXiv:2007.07477)的官方实现。其核心思想可概括为:

  • 深度网络分类模型可以视为"特征提取器 + 线性分类头"的组合,其中间层激活(activation)编码了从低级视觉特征到高级语义特征的多层次信息;
  • 对每个指定层的激活分别执行无监督聚类(本项目使用 Deep Embedding Clustering,即 DEC),使激活空间被划分为若干簇;
  • 每个簇可视为该层网络学习到的"概念",聚类结果再与类别标签建立经验后验概率映射,从而构成一个可解释的代理模型。

从仓库结构看,activation_clustering目录下包含三个主要部分:

  • 核心实现:ac_model.py(ACModel 类)、utils.py(激活提取与可视化工具)、__init__.py
  • CIFAR-10 示例:train.ipynb(训练代理模型)、similar_images_concepts.ipynb(相似样本与概念可视化);
  • Dockerfile 与 setup.py:一键构建含示例模型与数据的环境。

安装与运行:Docker 一键启动 Jupyter

仓库 README 给出了完整的 5 步上手流程,全程基于 Docker,包含示例模型与数据下载,无需手工配置 Python 环境。

步骤 1:克隆仓库

git clone https://github.com/google-research/google-research.git --depth=1

使用--depth=1只拉取最新提交,可显著减小克隆体积;这是官方 README 推荐的用法。

步骤 2:构建 Docker 镜像

cd google-research/activation_clustering && docker build -t activation_clustering .

结合 Dockerfile 可以看到该镜像构建时自动完成的关键工作:

  • 基于python:3.6基础镜像,并安装git与 Google Cloud SDK(用于gsutil/gcloud storage下载数据);
  • 克隆仓库后,从gs://cloud-samples-data/research/activation_clustering/下载两类数据:
    • work_dir(预训练好的激活聚类模型工作目录,供similar_images_concepts.ipynb直接使用);
    • model.h5(在 CIFAR-10 上训练好的 ResNet 基线分类模型);
  • 执行pip install -e .安装本项目及其依赖;
  • 预下载 CIFAR-10 数据集(通过tensorflow_datasets)并缓存进镜像。

依赖清单在 setup.py 中可查:scikit-learn==0.19.2tensorflow-gpu==2.1.0tensorflow-datasets==2.1.0matplotlib==2.2.4scipy==1.2.2PyYaml==5.3jupyter==1.0.0,以及从 GitHub 指定 commit 安装的dec_da(DEC-DA 聚类库,提供ConvIDEC卷积聚类模型)。注意:依赖锁定在较老的 TensorFlow 2.1 与 Python 3.6 时代,因此官方以 Docker 作为推荐的运行方式,以隔离版本冲突。

步骤 3:启动容器内 Jupyter 服务

docker run -it -p 8888:8888 activation_clustering

镜像的ENTRYPOINT为:

jupyter notebook --ip=0.0.0.0 --no-browser --allow-root --notebook-dir=google-research/activation_clustering/examples/cifar10

即容器启动后直接在examples/cifar10/目录下开启 Jupyter Notebook,监听所有网卡,并通过-p 8888:8888将 8888 端口映射到宿主机。

步骤 4:浏览器访问

在浏览器中打开docker run输出的地址,形如:

http://127.0.0.1:8888/?token=1234abcd...

token 由 Jupyter 启动时自动生成并打印在终端中,注意完整复制。

步骤 5:跟随示例 Notebook

按 examples/cifar10/ 下的两个 Notebook 依次操作:先用train.ipynb从基线模型训练激活聚类模型,再用similar_images_concepts.ipynb做相似图像检索与概念可视化,具体用法见下文。

训练激活聚类模型:train.ipynb 详解

examples/cifar10/train.ipynb 展示了如何从已训练好的 Keras 基线模型(CIFAR-10 ResNet,即model.h5)出发训练激活聚类模型。

数据预处理与激活缓存

Notebook 先定义与基线模型训练一致的预处理函数(图像归一化到[0,1]),随后加载基线模型:

model = tf.keras.models.load_model('model.h5')

关键一步是缓存激活:对训练集与测试集分别调用cache_activations,把指定层的激活写入磁盘,便于后续迭代训练而不必反复前向传播:

batch_size = 500 ds = input_fn(batch_size, train_ds) new_acm.cache_activations(ds, tag='train')

在源码 ac_model.py 中,cache_activations将激活写入{work_dir}/activations/activations_{tag}.npz,每个文件以npz格式保存以激活名为 key 的 numpy 数组字典;之后用load_activations_dict读取:

activations_dict = new_acm.load_activations_dict( activations_filename=work_dir + '/activations/activations_train.npz')

聚类配置与模型构建

聚类配置是一组(激活层名, 配置字典)对。Notebook 中的完整示例:

clustering_config = [ ('activation', {'n_clusters': 15}), ('activation_18', {'n_clusters': 15}), ('activation_36', {'n_clusters': 15}), ('activation_54', {'n_clusters': 15}) ]

其中第一项是基线模型中的层名(activationactivation_18activation_36activation_54是 ResNet 各阶段的激活层),其输出激活将被聚类;第二项中的n_clusters指定该层聚类的簇数(即概念数)。Notebook 也给出了一段供调试/测试用的精简配置注释:

# clustering_config = [ # ('activation', {'n_clusters': 10}), # ('activation_54', {'n_clusters': 10, 'filters': [16, 16, 16, 8]}) # ]

创建 ACModel 并构建聚类模型:

new_acm = ac_model.ACModel(model, clustering_config, work_dir=work_dir) new_acm.build_clustering_models()

从源码看,build_clustering_models(ac_model.py)会为每个激活层实例化一个ConvIDEC(来自 dec_da 库的卷积 DEC 模型),自动读取该层激活的input_shape,并用 Adam 优化器、loss=['kld', 'mse']loss_weights=[0.1, 1.0]编译——其中kld对应 DEC 的 KL 散度聚类损失,mse对应自编码器重构损失。

训练循环

epochs = 15 maxiter = 980 new_acm.fit(activations_dict=activations_dict, epochs=epochs, maxiter=maxiter)

fit(ac_model.py)依次完成三件事:

  1. 拟合各层聚类模型:对每个激活执行 DEC 的两阶段训练——先用自编码器以epochs个 epoch 预训练(pretrain),再以maxiter次迭代做聚类精调(fit),batch_size 固定为 32,模型保存到{work_dir}/clustering_{activation_name}/
  2. 拟合经验后验概率:将训练样本的簇分配与真实类别做计数统计并归一化,得到(n_clusters, n_classes)的经验后验矩阵,存入{work_dir}/empirical_posteriors/
  3. 缓存训练嵌入:用训练好的聚类编码器将所有训练样本映射为嵌入向量,保存为{work_dir}/training_embeddings.npz,供后续最近邻查询使用。

Notebook 注释也提示:epochs=2, maxiter=280可用于缩短训练时间做调试;该实现基于 DEC,dec_da 库中还有其他参数,可通过修改activation_clustering库暴露后配置。

相似样本与概念可视化:similar_images_concepts.ipynb 详解

examples/cifar10/similar_images_concepts.ipynb 直接复用镜像中预下载的work_dir恢复已训练模型:

acm = ac_model.ACModel.restore('work_dir')

restore(ac_model.py)会按顺序恢复:clustering_config.yaml配置 →baseline_model.h5(及可选的activation_model.h5)→ 各层聚类模型权重model_final.h5→ 经验后验empirical_posteriors.joblib→ 训练嵌入training_embeddings.npz

作为代理模型评估

Notebook 首先验证激活聚类模型可作为基线模型的代理:

# 代理模型自身精度 print('surrogate model accuracy: ', acm.evaluate(features=test_features, y=test_labels)) # 保真度:代理模型与基线模型预测的一致性 baseline_labels = np.argmax(acm.baseline_model.predict(test_features), axis=-1) print('fidelity: ', acm.evaluate(features=test_features, y=baseline_labels))

源码中evaluate通过predict得到代理模型预测的类别,再与y计算准确率:当y为真实标签时得到代理模型精度;当y为基线模型预测时得到保真度(fidelity)。predict_proba的实现(ac_model.py)说明其原理:将各层簇分配的软分数s与该层经验后验矩阵h做矩阵乘法得到该层对类别的概率贡献,再按权重w加权平均。

查询相似训练样本

Notebook 随机抽取 10 个测试样本,用query检索嵌入空间中最近的训练样本:

equal = [1.0, 1.0, 1.0, 1.0] low = [2.0, 1.0, 0.0, 0.0] high = [0.0, 0.0, 1.0, 2.0] ind = acm.query(features=test_feat, weights=equal) train_image_arrays_list = train_features[ind] utils.visualize_similar( test_image_arrays=test_feat, train_image_arrays_list=train_image_arrays_list, test_labels=test_labels[test_indices].tolist(), train_labels=train_labels[ind].tolist())

weights列表与clustering_config一一对应,控制各层嵌入在距离计算中的相对权重。源码query(ac_model.py)先对各层提取测试嵌入,再用scipy.spatial.distance.cdist计算与训练嵌入的欧氏距离矩阵,按权重求和后取最近的前k个(默认k=10)训练样本索引。示例表明:偏重浅层(低权重给高层)会得到视觉上更相似的图像,偏重深层则更强调语义相似。

Notebook 还对比了"仅用最后一层原始激活距离"检索的效果,结论是它无法捕捉低级视觉特征——这正是激活聚类在嵌入空间中做最近邻的优势所在。

提取与可视化概念

将每个聚类簇视作一个"概念",用距各簇质心最近的训练图像代表该概念:

concept_indices = acm.concept_indices() activation_index = 0 print('Concepts based on {}'.format(acm.activation_names[activation_index])) train_image_arrays_list = train_features[concept_indices[activation_index]] utils.visualize_concepts(train_image_arrays_list)

concept_indices(ac_model.py)先从各聚类模型的clustering层取出簇质心(get_centroids_list),再对每个质心返回训练嵌入中最近的前k个样本索引,形状为(n_clusters, k)。Notebook 依次可视化第 0、2、3 个激活层的概念,并明确指出:越早的激活层捕捉低级视觉特征,越深的层则对应更高级的语义概念。可视化函数(visualize_similarvisualize_concepts)实现在 utils.py,后者会为每行图片标注 "Top N training images of concept i"。

核心参数与自定义说明

综合源码与 Notebook,可自定义的关键参数如下:

参数所属位置含义与取值默认值
activation_namesclustering_config基线模型待聚类激活的层名列表无(必填)
n_clustersclustering_config每项该层激活划分的簇/概念数无(必填)
filtersclustering_config每项(可选)内部卷积自编码器各层滤波器数与嵌入维度,必须为长度为 4 的正整数列表,最后一位为嵌入维度;违反时抛出NotImplementedError[32, 64, 128, 20]
work_dirACModel构造参数缓存激活、聚类模型、经验后验与训练嵌入的工作目录/tmp/acmodel
restoreACModel构造参数是否从work_dir恢复模型False
activation_modelACModel构造参数用于提取激活的模型,缺省时即基线模型baseline_model
epochsfitDEC 自编码器预训练 epoch 数3
maxiterfitDEC 聚类精调的最大迭代次数280
weightsquery/predict_proba各激活层距离/概率的加权系数,无需归一化1.0(等权)
kquery/concept_indices返回最近邻样本数量10

工作原理与适用限制

从实现结构看,整个激活聚类模型是一条"可解释代理流水线":

  1. 激活提取utils.get_activations通过tf.keras.backend.function将模型输入占位符映射到指定层的输出张量,按 1024 的 batch 分批前向计算(utils.py);
  2. 聚类建模:每个激活层对应一个ConvIDEC(卷积 DEC),自编码器负责降维嵌入,聚类层负责将嵌入划分到n_clusters个簇;build_clustering_models还会用batched_predict_on_batch(batch_size=1024)monkey-patch 各模型的predict方法,规避大数组推理的内存压力;
  3. 经验后验:簇分配经训练标签统计归一化后,构成从簇到类别的概率映射(ac_model.py);
  4. 推理与解释predict_proba输出代理模型的类别概率;query/concept_indices在训练嵌入空间中做加权欧氏最近邻,分别回答"与某测试样本相似的训练样本有哪些"与"某概念的代表图像是什么"。

需要注意的是:本项目以 TensorFlow 2.1、Python 3.6 及固定版本依赖运行,且示例仅覆盖 CIFAR-10 图像分类场景,迁移到其他数据集/模型时需要自行准备基线模型与层名清单;filters必须为 4 个正整数(最后一个为嵌入维度),这是 dec_da 库的硬性约束。

结语

activation_clustering提供了一个完整的"无监督聚类解释深度网络"参考实现:从 Docker 一键环境、CIFAR-10 端到端训练,到相似样本检索与概念可视化,再到ACModel/utils的源码级机制,均可直接在 examples/cifar10/ 的 Notebook 中复现。对于希望在图像分类模型上获得白盒式解释、检索训练数据证据或提炼概念原型的开发者,这套实现是值得直接上手与二次开发的基线。

【免费下载链接】google-researchGoogle Research项目地址: https://gitcode.com/gh_mirrors/go/google-research

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询