[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"similar-marcoancona--DeepExplain":3,"tool-marcoancona--DeepExplain":61},[4,18,26,36,44,53],{"id":5,"name":6,"github_repo":7,"description_zh":8,"stars":9,"difficulty_score":10,"last_commit_at":11,"category_tags":12,"status":17},4358,"openclaw","openclaw\u002Fopenclaw","OpenClaw 是一款专为个人打造的本地化 AI 助手，旨在让你在自己的设备上拥有完全可控的智能伙伴。它打破了传统 AI 助手局限于特定网页或应用的束缚，能够直接接入你日常使用的各类通讯渠道，包括微信、WhatsApp、Telegram、Discord、iMessage 等数十种平台。无论你在哪个聊天软件中发送消息，OpenClaw 都能即时响应，甚至支持在 macOS、iOS 和 Android 设备上进行语音交互，并提供实时的画布渲染功能供你操控。\n\n这款工具主要解决了用户对数据隐私、响应速度以及“始终在线”体验的需求。通过将 AI 部署在本地，用户无需依赖云端服务即可享受快速、私密的智能辅助，真正实现了“你的数据，你做主”。其独特的技术亮点在于强大的网关架构，将控制平面与核心助手分离，确保跨平台通信的流畅性与扩展性。\n\nOpenClaw 非常适合希望构建个性化工作流的技术爱好者、开发者，以及注重隐私保护且不愿被单一生态绑定的普通用户。只要具备基础的终端操作能力（支持 macOS、Linux 及 Windows WSL2），即可通过简单的命令行引导完成部署。如果你渴望拥有一个懂你",349277,3,"2026-04-06T06:32:30",[13,14,15,16],"Agent","开发框架","图像","数据工具","ready",{"id":19,"name":20,"github_repo":21,"description_zh":22,"stars":23,"difficulty_score":10,"last_commit_at":24,"category_tags":25,"status":17},3808,"stable-diffusion-webui","AUTOMATIC1111\u002Fstable-diffusion-webui","stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面，旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点，将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。\n\n无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师，还是想要深入探索模型潜力的开发者与研究人员，都能从中获益。其核心亮点在于极高的功能丰富度：不仅支持文生图、图生图、局部重绘（Inpainting）和外绘（Outpainting）等基础模式，还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外，它内置了 GFPGAN 和 CodeFormer 等人脸修复工具，支持多种神经网络放大算法，并允许用户通过插件系统无限扩展能力。即使是显存有限的设备，stable-diffusion-webui 也提供了相应的优化选项，让高质量的 AI 艺术创作变得触手可及。",162132,"2026-04-05T11:01:52",[14,15,13],{"id":27,"name":28,"github_repo":29,"description_zh":30,"stars":31,"difficulty_score":32,"last_commit_at":33,"category_tags":34,"status":17},1381,"everything-claude-code","affaan-m\u002Feverything-claude-code","everything-claude-code 是一套专为 AI 编程助手（如 Claude Code、Codex、Cursor 等）打造的高性能优化系统。它不仅仅是一组配置文件，而是一个经过长期实战打磨的完整框架，旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。\n\n通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能，everything-claude-code 能显著提升 AI 在复杂任务中的表现，帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略，使得模型响应更快、成本更低，同时有效防御潜在的攻击向量。\n\n这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库，还是需要 AI 协助进行安全审计与自动化测试，everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目，它融合了多语言支持与丰富的实战钩子（hooks），让 AI 真正成长为懂上",159636,2,"2026-04-17T23:33:34",[14,13,35],"语言模型",{"id":37,"name":38,"github_repo":39,"description_zh":40,"stars":41,"difficulty_score":32,"last_commit_at":42,"category_tags":43,"status":17},2271,"ComfyUI","Comfy-Org\u002FComfyUI","ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎，专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式，采用直观的节点式流程图界面，让用户通过连接不同的功能模块即可构建个性化的生成管线。\n\n这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景，也能自由组合模型、调整参数并实时预览效果，轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性，不仅支持 Windows、macOS 和 Linux 全平台，还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构，并率先支持 SDXL、Flux、SD3 等前沿模型。\n\n无论是希望深入探索算法潜力的研究人员和开发者，还是追求极致创作自由度的设计师与资深 AI 绘画爱好者，ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能，使其成为当前最灵活、生态最丰富的开源扩散模型工具之一，帮助用户将创意高效转化为现实。",108322,"2026-04-10T11:39:34",[14,15,13],{"id":45,"name":46,"github_repo":47,"description_zh":48,"stars":49,"difficulty_score":32,"last_commit_at":50,"category_tags":51,"status":17},6121,"gemini-cli","google-gemini\u002Fgemini-cli","gemini-cli 是一款由谷歌推出的开源 AI 命令行工具，它将强大的 Gemini 大模型能力直接集成到用户的终端环境中。对于习惯在命令行工作的开发者而言，它提供了一条从输入提示词到获取模型响应的最短路径，无需切换窗口即可享受智能辅助。\n\n这款工具主要解决了开发过程中频繁上下文切换的痛点，让用户能在熟悉的终端界面内直接完成代码理解、生成、调试以及自动化运维任务。无论是查询大型代码库、根据草图生成应用，还是执行复杂的 Git 操作，gemini-cli 都能通过自然语言指令高效处理。\n\n它特别适合广大软件工程师、DevOps 人员及技术研究人员使用。其核心亮点包括支持高达 100 万 token 的超长上下文窗口，具备出色的逻辑推理能力；内置 Google 搜索、文件操作及 Shell 命令执行等实用工具；更独特的是，它支持 MCP（模型上下文协议），允许用户灵活扩展自定义集成，连接如图像生成等外部能力。此外，个人谷歌账号即可享受免费的额度支持，且项目基于 Apache 2.0 协议完全开源，是提升终端工作效率的理想助手。",100752,"2026-04-10T01:20:03",[52,13,15,14],"插件",{"id":54,"name":55,"github_repo":56,"description_zh":57,"stars":58,"difficulty_score":32,"last_commit_at":59,"category_tags":60,"status":17},4721,"markitdown","microsoft\u002Fmarkitdown","MarkItDown 是一款由微软 AutoGen 团队打造的轻量级 Python 工具，专为将各类文件高效转换为 Markdown 格式而设计。它支持 PDF、Word、Excel、PPT、图片（含 OCR）、音频（含语音转录）、HTML 乃至 YouTube 链接等多种格式的解析，能够精准提取文档中的标题、列表、表格和链接等关键结构信息。\n\n在人工智能应用日益普及的今天，大语言模型（LLM）虽擅长处理文本，却难以直接读取复杂的二进制办公文档。MarkItDown 恰好解决了这一痛点，它将非结构化或半结构化的文件转化为模型“原生理解”且 Token 效率极高的 Markdown 格式，成为连接本地文件与 AI 分析 pipeline 的理想桥梁。此外，它还提供了 MCP（模型上下文协议）服务器，可无缝集成到 Claude Desktop 等 LLM 应用中。\n\n这款工具特别适合开发者、数据科学家及 AI 研究人员使用，尤其是那些需要构建文档检索增强生成（RAG）系统、进行批量文本分析或希望让 AI 助手直接“阅读”本地文件的用户。虽然生成的内容也具备一定可读性，但其核心优势在于为机器",93400,"2026-04-06T19:52:38",[52,14],{"id":62,"github_repo":63,"name":64,"description_en":65,"description_zh":66,"ai_summary_zh":66,"readme_en":67,"readme_zh":68,"quickstart_zh":69,"use_case_zh":70,"hero_image_url":71,"owner_login":72,"owner_name":73,"owner_avatar_url":74,"owner_bio":75,"owner_company":76,"owner_location":77,"owner_email":78,"owner_twitter":79,"owner_website":80,"owner_url":81,"languages":82,"stars":87,"forks":88,"last_commit_at":89,"license":90,"difficulty_score":91,"env_os":92,"env_gpu":93,"env_ram":93,"env_deps":94,"category_tags":99,"github_topics":78,"view_count":32,"oss_zip_url":78,"oss_zip_packed_at":78,"status":17,"created_at":101,"updated_at":102,"faqs":103,"releases":132},8722,"marcoancona\u002FDeepExplain","DeepExplain","A unified framework of perturbation and gradient-based attribution methods for Deep Neural Networks interpretability. DeepExplain also includes support for Shapley Values sampling. (ICLR 2018)","DeepExplain 是一个专为深度神经网络可解释性设计的统一框架，旨在帮助开发者与研究人员深入理解模型内部的决策逻辑。它通过计算“归因图”，量化输入特征（如图像中的像素）对模型输出结果的具体贡献度，从而直观展示哪些因素促成了预测，哪些产生了抑制作用，有效解决了深度学习模型“黑盒”难以诊断误判原因的问题。\n\n该工具集成了多种前沿的归因算法，既包含基于梯度的方法（如显著性图、积分梯度、DeepLIFT），也支持基于扰动的方法（如遮挡测试、Shapley 值采样）。其独特亮点在于将各类算法统一在简洁的接口下，并针对部分梯度方法采用了改进的链式法则实现，提升了理论一致性。DeepExplain 原生支持 TensorFlow 及后端为 TensorFlow 的 Keras，特别适合需要评估模型可靠性、进行算法基准测试或调试复杂网络的研究人员与工程师使用，让模型行为变得更加透明可信。","DeepExplain: attribution methods for Deep Learning\n[![Build Status](https:\u002F\u002Ftravis-ci.org\u002Fmarcoancona\u002FDeepExplain.svg?branch=master)](https:\u002F\u002Ftravis-ci.org\u002Fmarcoancona\u002FDeepExplain)\n===\nDeepExplain provides a unified framework for state-of-the-art gradient *and* perturbation-based attribution methods.\nIt can be used by researchers and practitioners for better undertanding the recommended existing models, as well for benchmarking other attribution methods.\n\nIt supports **Tensorflow** as well as **Keras** with Tensorflow backend. **Only Tensorflow V1 is supported. For V2, there is an open pull-request, that works if eager execution is disabled.**\n\nImplements the following methods:\n\n**Gradient-based attribution methods**\n- [**Saliency maps**](https:\u002F\u002Farxiv.org\u002Fabs\u002F1312.6034)\n- [**Gradient * Input**](https:\u002F\u002Farxiv.org\u002Fabs\u002F1605.01713)\n- [**Integrated Gradients**](https:\u002F\u002Farxiv.org\u002Fabs\u002F1703.01365)\n- [**DeepLIFT**](https:\u002F\u002Farxiv.org\u002Fabs\u002F1704.02685), in its first variant with Rescale rule (*)\n- [**ε-LRP**](http:\u002F\u002Fjournals.plos.org\u002Fplosone\u002Farticle?id=10.1371\u002Fjournal.pone.0130140) (*)\n\nMethods marked with (*) are implemented as modified chain-rule, as better explained in [Towards better understanding of gradient-based attribution methods for Deep Neural Networks](https:\u002F\u002Fopenreview.net\u002Fforum?id=Sy21R9JAW), Ancona *et al*, ICLR 2018. As such, the result might be slightly different from the original implementation.\n\n**Pertubration-based attribution methods**\n- [**Occlusion**](https:\u002F\u002Farxiv.org\u002Fabs\u002F1311.2901), as an extension\nof the [grey-box method by Zeiler *et al*](https:\u002F\u002Farxiv.org\u002Fabs\u002F1311.2901).\n- [**Shapley Value sampling**](https:\u002F\u002Fwww.sciencedirect.com\u002Fscience\u002Farticle\u002Fpii\u002FS0305054808000804)\n\n## What are attributions?\nConsider a network and a specific input to this network (eg. an image, if the network is trained for image classification). The input is multi-dimensional, made of several features. In the case of images, each pixel can be considered a feature. The goal of an attribution method is to determine a real value `R(x_i)` for each input feature, with respect to a target neuron of interest (for example, the activation of the neuron corresponsing to the correct class). \n\nWhen the attributions of all input features are arranged together to have the same shape of the input sample we talk about *attribution maps* (as in the picture below), where red and blue colors indicate respectively features that contribute positively to the activation of the target output and features having a suppressing effect on it.\n![Attribution methods comparison on InceptionV3](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fmarcoancona_DeepExplain_readme_a8a7e957f09f.png)\n\nThis can help to better understand the network behavior, which features mostly contribute to the output and possible reasons for missclassification.\n\n\nDeepExplain Quickstart\n===\n## Installation\n```unix\npip install -e git+https:\u002F\u002Fgithub.com\u002Fmarcoancona\u002FDeepExplain.git#egg=deepexplain\n```\n\nNotice that DeepExplain assumes you already have installed `Tensorflow > 1.0` and (optionally) `Keras > 2.0`.\n\n## Usage\n\nWorking examples for Tensorflow and Keras can be found in the `example` folder of the repository. DeepExplain\nconsists of a single method: `explain(method_name, target_tensor, input_tensor, samples, ...args)`.\n\n\nParameter name | Short name | Type | Description\n---------------|------|------|------------\n`method_name` | | string, required | Name of the method to run (see [Which method to use?](#which-method-to-use)).\n`target_tensor` | `T` | Tensor, required | Tensorflow Tensor object representing the output of the model for which attributions are seeked (see [Which tensor to target?](#which-neuron-to-target)).\n`input_tensor` | `X` | Tensor, required | Symbolic input to the network.\n`input_data` | `xs` | numpy array, required | Batch of input samples to be fed to `X` and for which attributions are seeked. Notice that the first dimension must always be the batch size.\n`target_weights` | `ys` | numpy array, optional | Batch of weights to be applied to `T` if this has more than one output. Usually necessary on classification problems where there are multiple output units and we need to target a specific one to generate explanations for. In this case, `ys` can be provided with the one-hot encoding of the desired unit.\n`batch_size` | |int, optional| By default, DeepExplain will try to evaluate the model using all data in `xs` at the same time. If `xs` contains many samples, it might be necessary to split the processing in batches. In this case, providing a `batch_size` greater than zero will automatically split the evaluation into chunks of the given size.\n`...args` | | various, optional | Method-specific parameters (see below).\n\nThe method `explain` must be called within a DeepExplain context:\n\n```python\n# Pseudo-code\nfrom deepexplain.tensorflow import DeepExplain\n\n# Option 1. Create and train your model within a DeepExplain context\n\nwith DeepExplain(session=...) as de:  # \u003C enter DeepExplain context\n    model = init_model()  # \u003C construct the model\n    model.fit()           # \u003C train the model\n\n    attributions = de.explain(...)  # \u003C compute attributions\n\n# Option 2. First create and train your model, then apply DeepExplain.\n# IMPORTANT: in order to work correctly, the graph to analyze\n# must always be (re)constructed within the context!\n\nmodel = init_model()  # \u003C construct the model\nmodel.fit()           # \u003C train the model\n\nwith DeepExplain(session=...) as de:  # \u003C enter DeepExplain context\n    new_model = init_model()  # \u003C assumes init_model() returns a *new* model with the weights of `model`\n    attributions = de.explain(...)  # \u003C compute attributions\n```\n\nWhen initializing the context, make sure to pass the `session` parameter:\n\n```python\n# With Tensorflow\nimport tensorflow as tf\n# ...build model\nsess = tf.Session()\n# ... use session to train your model if necessary\nwith DeepExplain(session=sess) as de:\n    ...\n\n# With Keras\nimport keras\nfrom keras import backend as K\n\nmodel = Sequential()  # functional API is also supported\n# ... build model and train\n\nwith DeepExplain(session=K.get_session()) as de:\n    ...\n```\n\nSee concrete examples [here](https:\u002F\u002Fgithub.com\u002Fmarcoancona\u002FDeepExplain\u002Ftree\u002Fmaster\u002Fexamples).\n\n## Which method to use?\nDeepExplain supports several methods. The main partition is between *gradient-based methods* and *perturbation-based methods*. The former are faster, given that they estimate attributions with a few forward and backward iterations through the network. The latter perturb the input and measure the change in output with respect to the original input. This requires to sequentially test each feature (or group of features) and therefore takes more time, but tends to produce smoother results.\n\nCooperative game theory suggests [**Shapley Values**](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FShapley_value) as a unique way to distribute attribution to features such that some important theoretical properties are satisfied. Unfortunately, computing Shapley Values exactly is prohibitively expensive, therefore DeepExplain provides a sampling-based approximation. By changing the `samples` parameters, one can adjust the trade-off between performance and error. Notice that this method will still be significantly slower than other methods in this library.\n\nSome methods allow tunable parameters. See the table below.\n\nMethod | `method_name` | Optional parameters | Notes\n---------------|:------|:------------|-----\nSaliency | `saliency` |  | [*Gradient*] Only positive attributions.\nGradient * Input | `grad*input` |  | [*Gradient*] Fast. May be affected by noisy gradients and saturation of the nonlinerities.\nIntegrated Gradients | `intgrad` |`steps`, `baseline` | [*Gradient*] Similar to Gradient * Input, but performs `steps` iterations (default: 100) though the network, varying the input from `baseline` (default: zero) to the actual provided sample. When provided, `baseline` must be a numpy array with the size of the input (but no batch dimension since the same baseline will be used for all inputs in the batch).\nepsilon-LRP | `elrp` | `epsilon` | [*Gradient*]Computes Layer-wise Relevance Propagation. Only recommanded with ReLU or Tanh nonlinearities. Value for `epsilon` must be greater than zero (default: .0001).\nDeepLIFT (Rescale) | `deeplift` | `baseline` |  [*Gradient*] In most cases a faster approximation of Integrated Gradients. Do not apply to networks with multiplicative units (ie. LSTM or GRU). When provided, `baseline` must be a numpy array with the size of the input, without the batch dimension (default: zero).\nOcclusion | `occlusion` | `window_shape`, `step` | [*Perturbation*] Computes rolling window view of the input array and replace each window with zero values, measuring the effect of the perturbation on the target output. The optional parameters `window_shape` and `step` behave like in [skimage](http:\u002F\u002Fscikit-image.org\u002Fdocs\u002Fdev\u002Fapi\u002Fskimage.util.html#skimage.util.view_as_windows). By default, each feature is tested independently (`window_shape=1` and `step=1`), however this might be extremely slow for large inputs (such as ImageNet images). When the input presents some local coherence (eg. images), you might prefer larger values for `window_shape`. In this case the attributions of the features in each window will be summed up. Notice that the result might vary significantly for different window sizes.\nShapley Value sampling | `shapley_sampling` | `samples`, `sampling_dims` | [*Perturbation*] Computes approximate Shapley Values by sampling `samples` times each input feature. Notice that this method can be significantly slower than all the others as it runs the network `samples*n` times, where `n` is the number of input features in your input. The parameter `sampling_dims` (a list of integers) can be used to select which dimensions should be sampled. For example, if the inputs are RGB images, `sampling_dims=[1,2]` would sample pixels considering the three color channels atomic. Instead `sampling_dims=[1,2,3]` (default) will samples over the channels as well.\n\n## Which neuron to target?\nIn general, any tensor that represents the activation of any hidden or output neuron can be user as `target_tensor`. If your network performs a classification task (ie. one output neuron for each possible class) you might want to target the neuron corresponding to the *correct class* for a given sample, such that the attribution map might help you undertand the reasons for this neuron to (not) activate. However you can also target the activation of another class, for example a class that is often missclassified, to have insight about features that activate this class.\n\n**Important**: Tensors in Tensorflow and Keras usually include the activations of *all* neurons of a layer. If you pass such a tensor to `explain` you will get the *sum* attribution map for all neurons the Tensor refers to. If you want to target a specific neuron you need either to slice the component you are interested in or multiply it for a binary mask that only select the target neuron.\n\n```python\n# Example on MNIST (classification, with 10 output classes)\nX = Placeholder(...)  # input tensor\nT = model(X) # output layer, 2-dimensional Tensor of shape (1, 10), where first dimension is the batch size\nys = [[0, 1, 0, 0, 0, 0, 0, 0, 0, 0]]  # numpy array of shape (1, 10) with one-hot encoding of labels\n\n# We need to target only one of the 10 output units in `T`\n# Option 1 (recommanded): use the `ys` parameter\nde.explain('method_name', T, X, xs, ys=ys)\n\n# Option 2: manually mask the target. This will not work with batch processing.\nT *=  ys # \u003C masked target tensor: only the second component of `logits` will be used to compute attributions\nde.explain('method_name', T, X, xs)\n\n```\n\n**Softmax**: if the network last activation is a Softmax, it is recommanded to target the activations *before* this normalization. \n\n### Performance: Explainer API\nIf you need to run `explain()` multiple times (for example, new data to process with the same model comes in over time) it is recommanded that you use the Explainer API. This provides a way to *compile* the graph operations needed to generate the explanations and *evaluate* this graph in two different steps. \n\nWithin a DeepExplain context (`de`), call `de.get_explainer()`. This method takes the same arguments of `explain()` except `xs`, `ys` and `batch_size`. It returns an explainer object (`explainer`) which provides a `run()` method. Call `explainer.run(xs, [ys], [batch_size])` to generate the explanations. Calling `run()` multiple times will not add new operations to the computational graph.\n\n\n```python\n# Normal API: \n\nfor i in range(100):\n    # The following line will become slower and slower as new operations are added to the computational graph at each iteration\n    attributions = de.explain('saliency', T, X, xs[i], ys=ys[i], batch_size=3)\n    \n # Use the Explainer API instead:\n \n # First create an explainer\n explainer = de.get_explainer('saliency', T, X)\n for i in range(100):\n    # Then generate explanations for some data without slowing things down\n    attributions = explainer.run(xs[i], ys=ys[i], batch_size=3)  \n ```\n\n\n### NLP \u002F Embedding lookups\nThe most common cause of `ValueError(\"None values not supported.\")` is `run()` being called with a `tensor_input` and `target_tensor` that are disconnected in the backpropagation. This is common when an embedding lookup layer is used, since the lookup operation does not propagate the gradient. To generate attributions for NLP models, the input of DeepExplain should be the result of the embedding lookup instead of the original model input. Then, attributions for each word are found by summing up along the appropriate dimension of the resulting attribution matrix.\n\nTensorflow pseudocode:\n```python\ninput_x = graph.get_operation_by_name(\"input_x\").outputs[0]\n# Get a reference to the embedding tensor\nembedding = graph.get_operation_by_name(\"embedding\").outputs[0]\npre_softmax = graph.get_operation_by_name(\"output\u002Fscores\").outputs[0]\n\n# Evaluate the embedding tensor on the model input (in other words, perform the lookup)\nembedding_out = sess.run(embedding, {input_x: x_test})\n# Run DeepExplain with the embedding as input\nattributions = de.explain('elrp', pre_softmax * y_test_logits, embedding, embedding_out)\n```\n\n### Multiple inputs\nModels with multiple inputs are supported for gradient-based methods. Instead, the `Occlusion` method will raise an exception if\n called on a model with multiple inputs (how perturbation should be generated for multiple inputs is actually not well defined).\n\nFor a minimal (toy) example see the [example folder](https:\u002F\u002Fgithub.com\u002Fmarcoancona\u002FDeepExplain\u002Ftree\u002Fmaster\u002Fexamples).\n\n## Contributing\nDeepExplain is still in active development. If you experience problems, feel free to open an issue. Contributions to extend the functinalities of this framework and\u002For to add support for other methods are welcome. \n\n## License\nMIT\n","DeepExplain：深度学习的归因方法\n[![构建状态](https:\u002F\u002Ftravis-ci.org\u002Fmarcoancona\u002FDeepExplain.svg?branch=master)](https:\u002F\u002Ftravis-ci.org\u002Fmarcoancona\u002FDeepExplain)\n===\nDeepExplain 提供了一个统一的框架，用于实现最先进的基于梯度和基于扰动的归因方法。研究人员和从业者可以使用它来更好地理解现有的推荐模型，也可以用来对其他归因方法进行基准测试。\n\n它支持 **TensorFlow** 以及使用 TensorFlow 作为后端的 **Keras**。**目前仅支持 TensorFlow V1。对于 V2，有一个开放的拉取请求，只要禁用急切执行模式即可正常工作。**\n\n实现了以下方法：\n\n**基于梯度的归因方法**\n- [**显著性图**](https:\u002F\u002Farxiv.org\u002Fabs\u002F1312.6034)\n- [**梯度乘以输入**](https:\u002F\u002Farxiv.org\u002Fabs\u002F1605.01713)\n- [**积分梯度**](https:\u002F\u002Farxiv.org\u002Fabs\u002F1703.01365)\n- [**DeepLIFT**](https:\u002F\u002Farxiv.org\u002Fabs\u002F1704.02685)，采用其第一种变体中的 Rescale 规则 (*)\n- [**ε-LRP**](http:\u002F\u002Fjournals.plos.org\u002Fplosone\u002Farticle?id=10.1371\u002Fjournal.pone.0130140) (*)\n\n标有 (*) 的方法是按照改进的链式法则实现的，这一点在 [Towards better understanding of gradient-based attribution methods for Deep Neural Networks](https:\u002F\u002Fopenreview.net\u002Fforum?id=Sy21R9JAW) 中有更详细的解释，作者为 Ancona 等人，发表于 ICLR 2018。因此，结果可能与原始实现略有不同。\n\n**基于扰动的归因方法**\n- [**遮挡法**](https:\u002F\u002Farxiv.org\u002Fabs\u002F1311.2901)，作为 Zeiler 等人提出的灰盒方法的扩展版本 ([arXiv:1311.2901](https:\u002F\u002Farxiv.org\u002Fabs\u002F1311.2901))。\n- [**Shapley 值采样法**](https:\u002F\u002Fwww.sciencedirect.com\u002Fscience\u002Farticle\u002Fpii\u002FS0305054808000804)\n\n## 什么是归因？\n考虑一个神经网络及其特定的输入（例如，如果该网络用于图像分类，则输入可能是一张图像）。输入是多维的，由多个特征组成。对于图像而言，每个像素都可以被视为一个特征。归因方法的目标是针对感兴趣的某个目标神经元（比如对应正确类别的神经元激活），为每个输入特征确定一个实数值 `R(x_i)`。\n\n当所有输入特征的归因值组合在一起，形成与输入样本相同形状时，我们就称之为 *归因图*（如下面的图片所示），其中红色和蓝色分别表示对目标输出激活有正向贡献的特征以及对其具有抑制作用的特征。\n![InceptionV3 上的归因方法比较](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fmarcoancona_DeepExplain_readme_a8a7e957f09f.png)\n\n这有助于更好地理解网络的行为、哪些特征对输出贡献最大，以及可能导致误分类的原因。\n\nDeepExplain 快速入门\n===\n## 安装\n```unix\npip install -e git+https:\u002F\u002Fgithub.com\u002Fmarcoancona\u002FDeepExplain.git#egg=deepexplain\n```\n\n请注意，DeepExplain 假设您已经安装了 `TensorFlow > 1.0` 和（可选）`Keras > 2.0`。\n\n## 使用\n\nTensorFlow 和 Keras 的示例代码可以在仓库的 `example` 文件夹中找到。DeepExplain 包含一个单一的方法：`explain(method_name, target_tensor, input_tensor, samples, ...args)`。\n\n参数名称 | 简称 | 类型 | 描述\n---------------|------|------|------------\n`method_name` | | 字符串，必填 | 要运行的方法名称（参见 [应该使用哪种方法？](#which-method-to-use)）。\n`target_tensor` | `T` | 张量，必填 | 表示所求归因的模型输出的 TensorFlow 张量对象（参见 [要针对哪个张量？](#which-neuron-to-target)）。\n`input_tensor` | `X` | 张量，必填 | 网络的符号化输入。\n`input_data` | `xs` | NumPy 数组，必填 | 将被馈送到 `X` 并为其计算归因的输入样本批次。请注意，第一个维度必须始终是批次大小。\n`target_weights` | `ys` | NumPy 数组，可选 | 如果 `T` 有多个输出，则应用于 `T` 的权重批次。通常在分类问题中需要针对特定的输出单元生成解释时才会用到。在这种情况下，`ys` 可以提供所需单元的独热编码。\n`batch_size` | | 整数，可选 | 默认情况下，DeepExplain 会尝试同时使用 `xs` 中的所有数据来评估模型。如果 `xs` 包含大量样本，可能需要将处理分成多个批次。此时，提供一个大于零的 `batch_size` 将自动把评估拆分为指定大小的块。\n`...args` | | 各种类型，可选 | 方法特定的参数（见下文）。\n\n`explain` 方法必须在 DeepExplain 上下文中调用：\n\n```python\n# 伪代码\nfrom deepexplain.tensorflow import DeepExplain\n\n# 选项 1. 在 DeepExplain 上下文中创建并训练您的模型\n\nwith DeepExplain(session=...) as de:  # \u003C 进入 DeepExplain 上下文\n    model = init_model()  # \u003C 构建模型\n    model.fit()           # \u003C 训练模型\n\n    attributions = de.explain(...)  # \u003C 计算归因\n\n# 选项 2. 先创建并训练您的模型，再应用 DeepExplain。\n# 重要提示：为了正确工作，待分析的图必须始终在上下文中重新构建！\n\nmodel = init_model()  # \u003C 构建模型\nmodel.fit()           # \u003C 训练模型\n\nwith DeepExplain(session=...) as de:  # \u003C 进入 DeepExplain 上下文\n    new_model = init_model()  # \u003C 假设 init_model() 返回一个带有 original model 权重的新模型\n    attributions = de.explain(...)  # \u003C 计算归因\n```\n\n初始化上下文时，请务必传递 `session` 参数：\n\n```python\n# 使用 TensorFlow\nimport tensorflow as tf\n# ...构建模型\nsess = tf.Session()\n# ... 如有必要，使用会话训练您的模型\nwith DeepExplain(session=sess) as de:\n    ...\n\n# 使用 Keras\nimport keras\nfrom keras import backend as K\n\nmodel = Sequential()  # 功能 API 也支持\n# ... 构建模型并训练\n\nwith DeepExplain(session=K.get_session()) as de:\n    ...\n```\n\n具体示例请参见 [这里](https:\u002F\u002Fgithub.com\u002Fmarcoancona\u002FDeepExplain\u002Ftree\u002Fmaster\u002Fexamples)。\n\n## 应该使用哪种方法？\nDeepExplain 支持多种方法。主要的划分是基于 *梯度的方法* 和 *扰动的方法*。前者速度更快，因为它们只需通过网络进行几次前向和反向传播迭代即可估计特征重要性。后者则通过对输入进行扰动，并测量输出相对于原始输入的变化来实现。这种方法需要依次测试每个特征（或一组特征），因此耗时较长，但通常能产生更平滑的结果。\n\n合作博弈论提出 [**Shapley 值**](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FShapley_value) 是一种独特的方式来分配特征的重要性，以满足一些重要的理论性质。遗憾的是，精确计算 Shapley 值的成本极高，因此 DeepExplain 提供了一种基于采样的近似方法。通过调整 `samples` 参数，可以权衡性能与误差之间的关系。需要注意的是，即使如此，该方法仍然会比本库中的其他方法慢得多。\n\n某些方法允许调整参数。请参见下表。\n\n方法 | `method_name` | 可选参数 | 备注\n---------------|:------|:------------|-----\n显著性图 | `saliency` |  | [*梯度*] 仅输出正向重要性。\n梯度乘以输入 | `grad*input` |  | [*梯度*] 快速。可能受噪声梯度和非线性饱和的影响。\n积分梯度 | `intgrad` |`steps`, `baseline` | [*梯度*] 类似于梯度乘以输入，但在网络中执行 `steps` 次迭代（默认：100次），将输入从 `baseline`（默认：零）逐步变化到实际提供的样本。如果提供 `baseline`，它必须是一个与输入大小相同的 NumPy 数组（但没有批次维度，因为同一个基准值将用于批次中的所有输入）。\nepsilon-LRP | `elrp` | `epsilon` | [*梯度*] 计算逐层相关性传播。仅推荐用于具有 ReLU 或 Tanh 非线性激活函数的网络。`epsilon` 的值必须大于零（默认：0.0001）。\nDeepLIFT（缩放） | `deeplift` | `baseline` | [*梯度*] 在大多数情况下，它是积分梯度的一种更快近似方法。不适用于包含乘法单元的网络（如 LSTM 或 GRU）。如果提供 `baseline`，它必须是一个与输入大小相同、不含批次维度的 NumPy 数组（默认：零）。\n遮挡 | `occlusion` | `window_shape`, `step` | [*扰动*] 对输入数组进行滑动窗口视图处理，将每个窗口替换为零值，从而测量扰动对目标输出的影响。可选参数 `window_shape` 和 `step` 的行为与 [skimage](http:\u002F\u002Fscikit-image.org\u002Fdocs\u002Fdev\u002Fapi\u002Fskimage.util.html#skimage.util.view_as_windows) 中的用法一致。默认情况下，每个特征独立测试（`window_shape=1` 和 `step=1`），但对于大型输入（如 ImageNet 图像）来说，这可能会非常缓慢。当输入具有局部连贯性时（例如图像），建议使用较大的 `window_shape` 值。在这种情况下，每个窗口内特征的重要性将被汇总。请注意，不同的窗口大小可能会导致结果有显著差异。\nShapley 值采样 | `shapley_sampling` | `samples`, `sampling_dims` | [*扰动*] 通过对每个输入特征进行 `samples` 次采样来计算近似的 Shapley 值。需要注意的是，由于该方法会运行网络 `samples*n` 次，其中 `n` 是输入特征的数量，因此它可能比其他所有方法都慢得多。参数 `sampling_dims`（一个整数列表）可用于选择要采样的维度。例如，如果输入是 RGB 图像，`sampling_dims=[1,2]` 将分别考虑三个颜色通道来采样像素；而 `sampling_dims=[1,2,3]`（默认）则会在通道维度上也进行采样。\n\n## 应该针对哪个神经元？\n一般来说，任何表示隐藏层或输出层神经元激活的张量都可以作为 `target_tensor` 使用。如果你的网络执行分类任务（即每个可能的类别对应一个输出神经元），你可能希望针对给定样本的 *正确类别* 所对应的神经元，这样特征重要性图可以帮助你理解该神经元为何会（或不会）被激活。不过，你也可以针对其他类别的激活情况，比如那些经常被误分类的类别，从而深入了解哪些特征会激活该类别。\n\n**重要提示**：TensorFlow 和 Keras 中的张量通常包含某一层中 *所有* 神经元的激活值。如果你将这样的张量传递给 `explain`，你将得到该张量所指代的所有神经元的 *总和* 特征重要性图。如果你想针对特定神经元，你需要要么切片出你感兴趣的组件，要么将其与只选择目标神经元的二值掩码相乘。\n\n```python\n# MNIST 示例（分类任务，10 个输出类别）\nX = Placeholder(...)  # 输入张量\nT = model(X) # 输出层，形状为 (1, 10) 的二维张量，第一维为批次大小\nys = [[0, 1, 0, 0, 0, 0, 0, 0, 0, 0]]  # 形状为 (1, 10) 的独热编码标签数组\n\n# 我们只需要针对 T 中的 10 个输出单元中的一个\n# 方法 1（推荐）：使用 ys 参数\nde.explain('method_name', T, X, xs, ys=ys)\n\n# 方法 2：手动掩码目标。此方法不适用于批处理。\nT *=  ys # \u003C 掩码后的目标张量：只有 logits 的第二个分量会被用于计算重要性\nde.explain('method_name', T, X, xs)\n\n```\n\n**Softmax**：如果网络的最后一层激活是 Softmax，则建议针对该归一化 *之前* 的激活值。\n\n### 性能：Explainer API\n如果你需要多次调用 `explain()`（例如，随着时间推移不断有新数据需要使用同一模型进行处理），建议使用 Explainer API。该 API 提供了一种方式，可以先 *编译* 生成解释所需的图操作，然后再在两个不同的步骤中 *评估* 这个图。\n\n在 DeepExplain 上下文中（`de`），调用 `de.get_explainer()`。该方法接受与 `explain()` 相同的参数，但不包括 `xs`、`ys` 和 `batch_size`。它返回一个解释器对象（`explainer`），该对象提供一个 `run()` 方法。调用 `explainer.run(xs, [ys], [batch_size])` 即可生成解释。多次调用 `run()` 不会导致计算图中新增操作。\n\n\n```python\n# 普通 API：\n\nfor i in range(100):\n    # 下面这行代码会随着每次迭代向计算图中添加新操作而越来越慢\n    attributions = de.explain('saliency', T, X, xs[i], ys=ys[i], batch_size=3)\n    \n # 改用 Explainer API：\n \n # 首先创建一个解释器\n explainer = de.get_explainer('saliency', T, X)\n for i in range(100):\n    # 然后为一些数据生成解释，而不会降低速度\n    attributions = explainer.run(xs[i], ys=ys[i], batch_size=3)  \n ```\n\n### NLP \u002F 嵌入查找\n`ValueError(\"None values not supported.\")` 的最常见原因是调用 `run()` 时，`tensor_input` 和 `target_tensor` 在反向传播中被断开了连接。这种情况在使用嵌入查找层时很常见，因为查找操作不会传播梯度。为了为 NLP 模型生成归因，DeepExplain 的输入应当是嵌入查找的结果，而不是原始模型输入。然后，通过沿结果归因矩阵的相应维度求和，即可得到每个词的归因值。\n\nTensorFlow 伪代码：\n```python\ninput_x = graph.get_operation_by_name(\"input_x\").outputs[0]\n# 获取嵌入张量的引用\nembedding = graph.get_operation_by_name(\"embedding\").outputs[0]\npre_softmax = graph.get_operation_by_name(\"output\u002Fscores\").outputs[0]\n\n# 在模型输入上评估嵌入张量（即执行查找操作）\nembedding_out = sess.run(embedding, {input_x: x_test})\n# 使用嵌入作为输入运行 DeepExplain\nattributions = de.explain('elrp', pre_softmax * y_test_logits, embedding, embedding_out)\n```\n\n### 多个输入\n基于梯度的方法支持具有多个输入的模型。然而，`Occlusion` 方法如果应用于具有多个输入的模型，则会抛出异常（因为对于多个输入如何生成扰动实际上并没有明确的定义）。\n\n有关最小化（玩具）示例，请参阅 [示例文件夹](https:\u002F\u002Fgithub.com\u002Fmarcoancona\u002FDeepExplain\u002Ftree\u002Fmaster\u002Fexamples)。\n\n## 贡献\nDeepExplain 目前仍在积极开发中。如果您遇到问题，欢迎随时提交 issue。我们非常欢迎对本框架功能进行扩展以及添加对其他方法支持的贡献。\n\n## 许可证\nMIT","# DeepExplain 快速上手指南\n\nDeepExplain 是一个为深度学习模型提供统一归因（Attribution）方法的框架，支持基于梯度和基于扰动的多种主流算法（如 Saliency Maps, Integrated Gradients, DeepLIFT, Occlusion 等），帮助开发者理解模型决策依据及错误分类原因。\n\n> **注意**：本项目目前主要支持 **TensorFlow V1**。若需在 TensorFlow V2 中使用，必须禁用 eager execution（即 `tf.compat.v1.disable_eager_execution()`）。\n\n## 环境准备\n\n在开始之前，请确保您的开发环境满足以下要求：\n\n*   **操作系统**：Linux \u002F macOS \u002F Windows\n*   **Python 版本**：推荐 Python 3.6 - 3.8\n*   **核心依赖**：\n    *   `TensorFlow > 1.0` (必须)\n    *   `Keras > 2.0` (可选，需使用 TensorFlow 后端)\n    *   `numpy`\n\n**国内加速建议**：\n安装依赖时建议使用国内镜像源以提升下载速度。\n```bash\npip install tensorflow==1.15.0 -i https:\u002F\u002Fpypi.tuna.tsinghua.edu.cn\u002Fsimple\n# 如需 Keras\npip install keras -i https:\u002F\u002Fpypi.tuna.tsinghua.edu.cn\u002Fsimple\n```\n\n## 安装步骤\n\n使用 `pip` 直接从 GitHub 源码安装 DeepExplain：\n\n```bash\npip install -e git+https:\u002F\u002Fgithub.com\u002Fmarcoancona\u002FDeepExplain.git#egg=deepexplain -i https:\u002F\u002Fpypi.tuna.tsinghua.edu.cn\u002Fsimple\n```\n\n## 基本使用\n\nDeepExplain 的核心是通过上下文管理器 `DeepExplain` 包裹模型构建或加载过程，并调用 `explain` 方法计算归因图。\n\n### 1. 导入与上下文设置\n\n无论使用原生 TensorFlow 还是 Keras，都必须将 Session 传入上下文。\n\n**TensorFlow 示例：**\n```python\nimport tensorflow as tf\nfrom deepexplain.tensorflow import DeepExplain\n\n# 构建模型逻辑...\nsess = tf.Session()\n\nwith DeepExplain(session=sess) as de:\n    # 在此上下文中构建或重新构建模型图\n    # model = init_model() \n    # attributions = de.explain(...)\n    pass\n```\n\n**Keras 示例：**\n```python\nimport keras\nfrom keras import backend as K\nfrom deepexplain.tensorflow import DeepExplain\n\nmodel = keras.models.Sequential()\n# ... 构建并训练模型\n\n# 获取 Keras 背后的 TF Session\nwith DeepExplain(session=K.get_session()) as de:\n    # 在此上下文中重新构建具有相同权重的模型\n    # new_model = init_model()\n    # attributions = de.explain(...)\n    pass\n```\n\n### 2. 计算归因 (Explain)\n\n`explain` 方法是核心接口，用于生成归因图。\n\n**参数说明：**\n*   `method_name`: 方法名称 (如 `'saliency'`, `'intgrad'`, `'occlusion'`)。\n*   `target_tensor` (`T`): 目标输出张量（通常是模型输出层）。\n*   `input_tensor` (`X`): 输入占位符张量。\n*   `input_data` (`xs`): 实际的输入数据 (numpy array)。\n*   `target_weights` (`ys`): (可选) 目标权重，常用于多分类任务中指定特定类别的 one-hot 编码。\n\n**完整最小化示例：**\n\n```python\nimport tensorflow as tf\nimport numpy as np\nfrom deepexplain.tensorflow import DeepExplain\n\n# 模拟数据\nxs = np.random.rand(1, 28, 28, 1)  # 输入样本 (batch_size=1)\nys = [[0, 1, 0, 0, 0, 0, 0, 0, 0, 0]] # 目标类别 one-hot 编码\n\nwith tf.Graph().as_default():\n    sess = tf.Session()\n    \n    # 定义简单的输入和输出占位符\n    X = tf.placeholder(tf.float32, (None, 28, 28, 1))\n    # 假设 T 是模型输出 logits\n    T = tf.reduce_sum(X, axis=[1, 2, 3]) \n\n    with DeepExplain(session=sess) as de:\n        # 选择方法：'intgrad' (Integrated Gradients)\n        # steps: 积分步数，baseline: 基线输入\n        attributions = de.explain('intgrad', T, X, xs, ys=ys, steps=100, baseline=np.zeros_like(xs))\n\n        print(\"Attributions shape:\", attributions.shape)\n        # attributions 即为与原输入形状相同的归因热力图数据\n```\n\n### 3. 常用方法速查\n\n| 方法类型 | 方法名 (`method_name`) | 特点 | 推荐场景 |\n| :--- | :--- | :--- | :--- |\n| **基于梯度** | `saliency` | 仅正归因，速度快 | 快速查看显著区域 |\n| | `grad*input` | 速度快，可能受噪声影响 | 通用快速分析 |\n| | `intgrad` | 效果稳定，需设置 `steps` | **推荐**，高精度归因 |\n| | `deeplift` | 速度快，近似 Integrated Gradients | 大规模数据快速推理 |\n| **基于扰动** | `occlusion` | 滑动窗口遮挡，速度慢但平滑 | 验证局部特征重要性 |\n| | `shapley_sampling` | 理论最严谨，速度极慢 | 小尺寸输入的高精度分析 |\n\n> **提示**：对于分类任务，如果最后一层是 Softmax，建议将 `target_tensor` 指向 Softmax **之前** 的 logits 层以获得更准确的归因结果。","某医疗影像实验室的算法团队正在开发基于深度学习的肺部 CT 结节分类模型，急需向医院专家证明模型是依据病灶特征而非背景噪声做出诊断。\n\n### 没有 DeepExplain 时\n- **决策过程如“黑盒”**：医生质疑模型为何将健康组织误判为结节，开发人员无法直观展示模型具体关注了图像的哪些像素区域。\n- **归因方法分散难用**：团队想对比 Saliency Maps、Integrated Gradients 等多种算法效果，但需分别寻找不同源码并适配接口，耗费大量工程时间。\n- **调试效率低下**：面对模型误诊案例，只能靠猜测调整网络结构或数据增强策略，缺乏基于特征贡献度的定量分析依据。\n- **框架兼容性差**：现有项目基于 TensorFlow 1.x 和 Keras 构建，许多新型解释工具不支持旧版本环境，迁移成本极高。\n\n### 使用 DeepExplain 后\n- **可视化归因图谱**：利用 DeepExplain 生成的热力图（Attribution Maps），清晰标红显示模型聚焦于结节边缘纹理，成功向医生解释判断依据。\n- **统一框架快速对比**：通过单一 `explain` 接口即可一键切换 Occlusion、DeepLIFT 等六种主流算法，迅速验证哪种方法最能反映真实病理特征。\n- **精准定位错误根源**：发现模型曾错误关注扫描设备的水印标识，团队据此针对性清洗数据，显著降低了假阳性率。\n- **无缝集成现有流程**：直接兼容团队原有的 TensorFlow 1.x 与 Keras 环境，无需重构代码即可嵌入训练后的模型进行即时分析。\n\nDeepExplain 通过统一的归因分析框架，将深度学习模型的“直觉”转化为可解释的视觉证据，极大提升了医疗 AI 的可信度与迭代效率。","https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fmarcoancona_DeepExplain_67bb9516.png","marcoancona","Marco Ancona","https:\u002F\u002Foss.gittoolsai.com\u002Favatars\u002Fmarcoancona_e103b32e.png","CTO & co-founder at Morgen. \r\nBefore Morgen, I was doing research on Explanable AI at ETH Zurich.","Morgen AG","Zurich",null,"marco_ancona","marcoancona.me","https:\u002F\u002Fgithub.com\u002Fmarcoancona",[83],{"name":84,"color":85,"percentage":86},"Python","#3572A5",100,758,135,"2026-04-06T12:05:18","MIT",4,"","未说明",{"notes":95,"python":93,"dependencies":96},"仅支持 Tensorflow V1。对于 Tensorflow V2，有一个开放的拉取请求，但必须禁用 eager execution（即时执行模式）才能工作。安装前需确保已自行安装好 Tensorflow 和 Keras。",[97,98],"tensorflow>1.0","keras>2.0 (可选，需使用 Tensorflow 后端)",[14,100],"其他","2026-03-27T02:49:30.150509","2026-04-18T09:19:15.078997",[104,109,114,119,123,128],{"id":105,"question_zh":106,"answer_zh":107,"source_url":108},39080,"为什么使用 LRP 或 DeepLIFT 方法时会出现“忘记在 DeepExplain 上下文中重建图”的警告，且结果不可靠？","这是因为您没有在 DeepExplain 的上下文管理器（`with DeepExplain(...) as de:`）内部创建或重新创建模型图。虽然 Gradient*Input、Integrated Gradients 和 Occlusion 方法可能仍能运行，但 LRP 和 DeepLIFT 需要梯度覆盖（gradient overriding），如果图不在上下文中构建，这些方法的结果将是错误的。此外，当前版本的 LRP 不支持 LSTM 单元，即使实现正确也无法使用，建议对包含 LSTM 的模型改用其他方法（如 Integrated Gradients）。","https:\u002F\u002Fgithub.com\u002Fmarcoancona\u002FDeepExplain\u002Fissues\u002F6",{"id":110,"question_zh":111,"answer_zh":112,"source_url":113},39081,"为什么某些类别的解释值全为 0 或 -0？","这通常是预期行为。如果模型倒数第二层的输出全为 0（例如所有 ReLU 激活函数未被激活，梯度为零），那么基于梯度的归因方法无法将贡献分配给输入特征。此时输出的“概率”仅由偏置项（bias）产生。在这种情况下，建议改用 `occlusion`（遮挡）方法，因为它不依赖梯度，能够提供更有效的解释。","https:\u002F\u002Fgithub.com\u002Fmarcoancona\u002FDeepExplain\u002Fissues\u002F8",{"id":115,"question_zh":116,"answer_zh":117,"source_url":118},39082,"如何避免在每次调用 run() 处理不同批次数据时重新编译计算图，从而提高效率？","默认的 `explain()` 方法在每次调用时都会执行 `get_symbolic_attribution()`，导致图重编译。优化方案是重构代码：先在单次调用中生成符号归因（symbolic attribution），然后在循环中针对不同的输入批次多次执行 `session.run()`。用户可以自定义继承 `AttributionMethod` 类，将 `get_symbolic_attribution()` 的调用移至初始化阶段，随后在一个单独的运行时方法中仅执行 `self.session_run(self.symbolic_attribution, xs, ys)`，从而在动态环境中显著提升运行速度。","https:\u002F\u002Fgithub.com\u002Fmarcoancona\u002FDeepExplain\u002Fissues\u002F31",{"id":120,"question_zh":121,"answer_zh":122,"source_url":108},39083,"如何在文本分类任务中获取每个单词的归因值？","首先需要确保模型在 DeepExplain 上下文中正确构建以避免梯度警告。对于文本数据，归因值通常对应于嵌入层（Embedding Layer）的输入向量。要获得单词级别的归因，需要将归因结果与原始的分词索引映射回去。由于 LRP 不适用于 LSTM，建议使用 Integrated Gradients 等方法。具体实现可参考 Keras 的 IMDB LSTM 示例，构建模型后在上下文中加载，并对输入序列进行解释，最后通过索引找到对应的初始单词。",{"id":124,"question_zh":125,"answer_zh":126,"source_url":127},39084,"如何处理具有多个输入（Multi-input）的 Keras 模型进行解释？","对于多输入模型，需要将所有输入张量作为一个列表传递给 DeepExplain。首先加载预训练模型，然后在 `DeepExplain` 上下文中定义一个新的 `Model`，其 inputs 为原模型所有输入层的列表（例如 `[model.layers[0].input, model.layers[6].input]`），outputs 为目标输出层。调用 `de.explain()` 时，目标张量设为新模型的输出，输入张量列表设为上述输入层列表，而实际数据 `xs` 也应是一个包含各输入对应数据的列表（例如 `[xs1, xs2]`）。","https:\u002F\u002Fgithub.com\u002Fmarcoancona\u002FDeepExplain\u002Fissues\u002F5",{"id":129,"question_zh":130,"answer_zh":131,"source_url":113},39085,"对于 ReLU 未激活导致梯度为零的模型，哪种解释方法最有效？","当模型中间层输出全为 0 导致梯度消失时，基于梯度的方法（如 Grad*Input, Integrated Gradients, LRP, DeepLIFT）将无法提供有意义的归因。此时最有效的解决方案是使用 `occlusion`（遮挡）方法。该方法通过系统地遮挡输入部分并观察预测变化来计算归因，不依赖于反向传播的梯度，因此即使在梯度为零的情况下也能正常工作。",[]]