在PyTorch中实现可解释的神经网络模型的方法详解

 更新时间:2023年06月21日 08:42:23   作者:冷冻工厂  
这篇文章主要为大家介绍在PyTorch如何中实现可解释的神经网络模型,并为您提供使用简单的 PyTorch 接口实现最先进的基于概念的模型的工具,需要的朋友可以参考下

目的

深度学习系统缺乏可解释性对建立人类信任构成了重大挑战。这些模型的复杂性使人类几乎不可能理解其决策背后的根本原因。

深度学习系统缺乏可解释性阻碍了人类的信任。

为了解决这个问题,研究人员一直在积极研究新的解决方案,从而产生了重大创新,例如基于概念的模型。这些模型不仅提高了模型的透明度,而且通过在训练过程中结合高级人类可解释的概念(如“颜色”或“形状”),培养了对系统决策的新信任感。因此,这些模型可以根据学习到的概念为其预测提供简单直观的解释,从而使人们能够检查其决策背后的原因。这还不是全部!它们甚至允许人类与学习到的概念进行交互,让我们能够控制最终的决定。

基于概念的模型允许人类检查深度学习预测背后的推理,并让我们重新控制最终决策。

在本文中,我们将深入研究这些技术,并为您提供使用简单的 PyTorch 接口实现最先进的基于概念的模型的工具。通过实践经验,您将学习如何利用这些强大的模型来增强可解释性并最终校准人类对您的深度学习系统的信任。

概念瓶颈模型

在这个介绍中,我们将深入探讨概念瓶颈模型。这模型在 2020 年国际机器学习会议上发表的一篇论文中介绍,旨在首先学习和预测一组概念,例如“颜色”或“形状”,然后利用这些概念来解决下游分类任务:

通过遵循这种方法,我们可以将预测追溯到提供解释的概念,例如“输入对象是一个{apple},因为它是{spherical}和{red}。”

概念瓶颈模型首先学习一组概念,例如“颜色”或“形状”,然后利用这些概念来解决下游分类任务。

实现

为了说明概念瓶颈模型,我们将重新审视著名的 XOR 问题,但有所不同。我们的输入将包含两个连续的特征。为了捕捉这些特征的本质,我们将使用概念编码器将它们映射为两个有意义的概念,表示为“A”和“B”。我们任务的目标是预测“A”和“B”的异或 (XOR)。通过这个例子,您将更好地理解概念瓶颈如何在实践中应用,并见证它们在解决具体问题方面的有效性。

我们可以从导入必要的库并加载这个简单的数据集开始:

import torch
import torch_explain as te
from torch_explain import datasets
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
x, c, y = datasets.xor(500)
x_train, x_test, c_train, c_test, y_train, y_test = train_test_split(x, c, y, test_size=0.33, random_state=42)

接下来,我们实例化一个概念编码器以将输入特征映射到概念空间,并实例化一个任务预测器以将概念映射到任务预测:

concept_encoder = torch.nn.Sequential(
    torch.nn.Linear(x.shape[1], 10),
    torch.nn.LeakyReLU(),
    torch.nn.Linear(10, 8),
    torch.nn.LeakyReLU(),
    torch.nn.Linear(8, c.shape[1]),
    torch.nn.Sigmoid(),
)
task_predictor = torch.nn.Sequential(
    torch.nn.Linear(c.shape[1], 8),
    torch.nn.LeakyReLU(),
    torch.nn.Linear(8, 1),
)
model = torch.nn.Sequential(concept_encoder, task_predictor)

然后我们通过优化概念和任务的交叉熵损失来训练网络:

optimizer = torch.optim.AdamW(model.parameters(), lr=0.01)
loss_form_c = torch.nn.BCELoss()
loss_form_y = torch.nn.BCEWithLogitsLoss()
model.train()
for epoch in range(2001):
    optimizer.zero_grad()
    # generate concept and task predictions
    c_pred = concept_encoder(x_train)
    y_pred = task_predictor(c_pred)
    # update loss
    concept_loss = loss_form_c(c_pred, c_train)
    task_loss = loss_form_y(y_pred, y_train)
    loss = concept_loss + 0.2*task_loss
    loss.backward()
    optimizer.step()

训练模型后,我们评估其在测试集上的性能:

c_pred = concept_encoder(x_test)
y_pred = task_predictor(c_pred)
concept_accuracy = accuracy_score(c_test, c_pred > 0.5)
task_accuracy = accuracy_score(y_test, y_pred > 0)

现在,在几个 epoch 之后,我们可以观察到概念和任务在测试集上的准确性都非常好(~98% 的准确性)!

由于这种架构,我们可以通过根据输入概念查看任务预测器的响应来为模型预测提供解释,如下所示:

c_different = torch.FloatTensor([0, 1])
print(f"f({c_different}) = {int(task_predictor(c_different).item() > 0)}")
c_equal = torch.FloatTensor([1, 1])
print(f"f({c_different}) = {int(task_predictor(c_different).item() > 0)}")

这会产生例如 f([0,1])=1 和 f([1,1])=0 ,如预期的那样。这使我们能够更多地了解模型的行为,并检查它对于任何相关概念集的行为是否符合预期,例如,对于互斥的输入概念 [0,1] 或 [1,0],它返回的预测y=1。

概念瓶颈模型通过将预测追溯到概念来提供直观的解释。

淹没在准确性与可解释性的权衡中

概念瓶颈模型的主要优势之一是它们能够通过揭示概念预测模式来为预测提供解释,从而使人们能够评估模型的推理是否符合他们的期望。

然而,标准概念瓶颈模型的主要问题是它们难以解决复杂问题!更一般地说,他们遇到了可解释人工智能中众所周知的一个众所周知的问题,称为准确性-可解释性权衡。实际上,我们希望模型不仅能实现高任务性能,还能提供高质量的解释。不幸的是,在许多情况下,当我们追求更高的准确性时,模型提供的解释往往会在质量和忠实度上下降,反之亦然。

在视觉上,这种权衡可以表示如下:

可解释模型擅长提供高质量的解释,但难以解决具有挑战性的任务,而黑盒模型以提供脆弱和糟糕的解释为代价来实现高任务准确性。

为了在具体设置中说明这种权衡,让我们考虑一个概念瓶颈模型,该模型应用于要求稍高的基准,即“三角学”数据集:

x, c, y = datasets.trigonometry(500)
x_train, x_test, c_train, c_test, y_train, y_test = train_test_split(x, c, y, test_size=0.33, random_state=42)

在该数据集上训练相同的网络架构后,我们观察到任务准确性显着降低,仅达到 80% 左右。

概念瓶颈模型未能在任务准确性和解释质量之间取得平衡。

这就引出了一个问题:我们是永远被迫在准确性和解释质量之间做出选择,还是有办法取得更好的平衡?

以上就是在PyTorch中实现可解释的神经网络模型的方法详解的详细内容,更多关于PyTorch 神经网络模型的资料请关注脚本之家其它相关文章!

相关文章

  • 在 Python 中使用通配符匹配字符串的方法

    在 Python 中使用通配符匹配字符串的方法

    这篇文章主要介绍了在 Python 中使用通配符匹配字符串的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • 使用keras时input_shape的维度表示问题说明

    使用keras时input_shape的维度表示问题说明

    这篇文章主要介绍了使用keras时input_shape的维度表示问题说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-06-06
  • python 按照固定长度分割字符串的方法小结

    python 按照固定长度分割字符串的方法小结

    这篇文章主要介绍了借助python脚本,可以轻松实现,原理就是:字符串的按照固定长度拆分
    2018-04-04
  • PyCharm+PyQt5+QtDesigner配置详解

    PyCharm+PyQt5+QtDesigner配置详解

    这篇文章主要介绍了PyCharm+PyQt5+QtDesigner配置详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • Python引用计数操作示例

    Python引用计数操作示例

    这篇文章主要介绍了Python引用计数操作,结合实例形式分析了Python引用计数相关操作与运行机制,需要的朋友可以参考下
    2018-08-08
  • Python中Parsel的两种数据提取方式详解

    Python中Parsel的两种数据提取方式详解

    在网络爬虫的世界中,数据提取是至关重要的一环,Python 提供了许多强大的工具,其中之一就是 parsel 库,下面我们就来深入学习一下Parsel的两种数据提取方式吧
    2023-12-12
  • 简单了解python代码优化小技巧

    简单了解python代码优化小技巧

    这篇文章主要介绍了简单了解python代码优化小技巧,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值
    2019-07-07
  • python中执行shell命令的几个方法小结

    python中执行shell命令的几个方法小结

    这篇文章主要介绍了python中执行shell命令的几个方法,本文一共给出3种方法实现执行shell命令,需要的朋友可以参考下
    2014-09-09
  • 三步解决python PermissionError: [WinError 5]拒绝访问的情况

    三步解决python PermissionError: [WinError 5]拒绝访问的情况

    这篇文章主要介绍了三步解决python PermissionError: [WinError 5]拒绝访问的情况,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-04-04
  • PyTorch如何修改为自定义节点

    PyTorch如何修改为自定义节点

    这篇文章主要介绍了PyTorch如何修改为自定义节点,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06

最新评论