将 AI Explanations 与 AI Platform Prediction 结合使用

本文是关于如何使用 AI Explanations 在 AI Platform Prediction 上部署和使用模型的一般指南。

准备工作

在 AI Platform 中训练和部署模型之前,您必须先完成以下事项:

  • 设置本地开发环境。
  • 设置已启用结算功能和必要 API 的 GCP 项目。
  • 创建 Cloud Storage 存储分区以存储您的训练软件包和经过训练的模型。

如需设置您的 GCP 项目,请按照示例笔记本中提供的说明操作。

保存模型

支持 TensorFlow 1.15、2.1、2.2、2.3、2.4、2.5、2.6、2.7、2.8、2.9、2.10 和 2.11。使用 tf.saved_model.save 将模型保存在 TensorFlow 2.11 中,但不要将其用于 TensorFlow 1.15。

详细了解如何保存模型以用于 AI Explanations,以及如何使用 Explainable AI SDK

说明元数据文件

部署模型之前,您必须提交包含您的模型输入、输出和基准信息的元数据文件,这样 AI Explanations 才能为您的模型的适当部分提供说明。

我们建议使用 Explainable AI SDK 自动发现模型的输入和输出。在大多数情况下,这可以节省时间和精力,因为 Explainable AI SDK 会为您创建并上传说明元数据文件。

手动创建说明元数据文件

如果您有一个高级用例,您可能希望手动指定模型输入和输出。要手动创建说明元数据文件,请按以下步骤操作:

  • 确定您希望为其提供说明的输入和输出张量的名称。 请参阅下文中的手动查找输入和输出张量名称部分。详细了解如何识别输入和输出张量
  • 创建适当的基准并在 input_baselines 中指定。
  • 为您的 framework 指定“tensorflow”。
  • explanation_metadata.json 文件命名。
  • explanation_metadata.json 文件上传到存储 SavedModel 的同一个 Cloud Storage 存储分区。

explanation_metadata.json 文件如以下示例所示:

{
    "inputs": {
      "data": {
        "input_tensor_name": "YOUR_INPUT_TENSOR_NAME"
        "input_baselines": [0]
      }
    },
    "outputs": {
      "duration": {
        "output_tensor_name": "YOUR_OUTPUT_TENSOR_NAME"
      }
    },
    "framework": "tensorflow"
}

在此示例中,"data""duration" 是输入和输出张量的有意义的名称,您可以在构建和训练模型的过程中分配这些名称。实际的输入和输出张量名称采用 name:index 格式。例如 x:0Placeholder:0

对于 input_baselines,您可以先指定一个基准。 在此示例中,[0] 表示全黑图片。您可以指定多个基准以提供更多信息。详细了解如何调整基准

手动查找输入和输出张量名称

在大多数情况下,您可以使用 Explainable AI SDK 为模型生成输入和输出。如果您使用预训练的 TensorFlow 1.15 模型,则只需手动查找输入和输出张量名称。

查找输入和输出张量名称的最佳方法取决于输入和输出数据的类型以及模型的构建方式。如需详细了解每种情况以及相关示例,请参阅有关[了解输入和输出][understanding-inputs-outputs]的指南。

输入数据类型 输出数据类型 其他条件 推荐方法
数字或字符串 数字 输入不采用序列化形式。输出也不是被视作分类数据的数字数据(例如,数字类 ID)。 使用 SavedModel CLI 查找输入和输出张量的名称。或者,在训练和保存模型时构建说明元数据文件,在此期间您的程序或环境仍可以访问训练代码。
任何序列化数据 不限 在导出模型时,向传送输入函数添加 TensorFlow 解析操作。使用解析操作的输出来帮助确定输入张量。
不限 不限 模型包含预处理操作 如需在预处理步骤之后获取输入张量的名称,请使用 tf.Tensorname 属性获取输入张量名称
不限 不属于概率、logits 或其他浮点类型的张量 您希望为不属于概率、logits 或其他浮点类型的张量的输出获取说明。 使用 TensorBoard 检查您的图,找到正确的输出张量。
任何不可微分的数据 不限 您希望使用积分梯度(需要可微分的输入)。 将不可微分的输入编码为可微分的张量。 将原始输入张量和编码后的输入张量的名称添加到说明元数据文件中。

部署模型和版本

AI Platform Prediction 使用模型和版本资源来组织经过训练的模型。AI Platform Prediction 模型是存放机器学习模型版本的容器。

如需部署模型,请在 AI Platform Prediction 中创建模型资源,创建该模型的版本,然后将模型版本关联到存储在 Cloud Storage 中的模型文件。

创建模型资源

AI Platform Prediction 使用模型资源来组织模型的不同版本。

为您的模型版本创建模型资源。在以下 Google Cloud CLI 命令中,将 MODEL_NAME 替换为所需的模型名称。模型名称必须以字母开头,并且只能包含字母、数字和下划线。

您必须在区域端点上创建模型才能使用 AI Explanations。

gcloud ai-platform models create MODEL_NAME \
  --region us-central1

如需了解详情,请参阅 AI Platform Prediction 模型 API

创建模型版本

现在,您就可以使用先前上传到 Cloud Storage 且经过训练的模型来创建模型版本了。创建版本时,请指定以下参数:

  • name:在 AI Platform Prediction 模型中必须是唯一的。
  • deploymentUri:Cloud Storage 中 SavedModel 目录的路径。
  • framework(必填):仅限 tensorflow
  • runtimeVersion:使用支持 AI Explanations 的以下任意一个运行时版本:1.15、2.1、2.2、2.3、2.4、2.5、2.6、2.7、2.8、2.9、2.10 和 2.11。
  • pythonVersion:对于运行时版本 1.15 及更高版本,请使用“3.7”。
  • machineType(必填):AI Platform Prediction 用于提供预测和说明服务的节点的虚拟机类型。选择 AI Explanations 支持的机器类型
  • explanation-method:要使用的特征归因方法的类型:“sampled-shapley”、“integrated-gradients”或“xrai”。
  • 路径或步长:对采样 Shapley 使用 --num-paths,而对积分梯度或 XRAI 使用 --num-integral-steps

如需详细了解以上各参数,请参阅适用于版本资源的 AI Platform Training and Prediction API

  1. 设置环境变量,以存储 SavedModel 所在的 Cloud Storage 目录的路径、模型名称、版本名称和框架选项。

    MODEL=your_model_name
    MODEL_DIR="gs://your_bucket_name/"
    VERSION=your_version_name
    FRAMEWORK=tensorflow
    
  2. 创建版本:

    EXPLAIN_METHOD="integrated-gradients"
    gcloud beta ai-platform versions create $VERSION \
    --model $MODEL \
    --origin $MODEL_DIR \
    --runtime-version 1.15 \
    --framework $FRAMEWORK \
    --python-version 3.7 \
    --machine-type n1-standard-4 \
    --explanation-method $EXPLAIN_METHOD \
    --num-integral-steps 25 \
    --region us-central1
    

    创建版本需要几分钟时间。完成后,您应该会看到以下输出:

    Creating version (this might take a few minutes)......done.
  3. 检查模型部署的状态,并确保已正确部署模型:

    gcloud ai-platform versions describe $VERSION_NAME \
      --model $MODEL_NAME \
      --region us-central1
    

    检查状态是否为 READY。您应该会看到如下所示的输出:

    createTime: '2018-02-28T16:30:45Z'
    deploymentUri: gs://your_bucket_name
    framework: TENSORFLOW
    machineType: n1-standard-4
    name: projects/your_project_id/models/your_model_name/versions/your_version_name
    pythonVersion: '3.7'
    runtimeVersion: '1.15'
    state: READY

说明服务支持的机器类型

对于 AI Explanations 请求,您必须使用以下某种机器类型来部署模型版本。如果您不指定机器类型,部署会失败。

下表对可用机器类型进行了比较:

名称 vCPU 内存 (GB)
n1-standard-2 2 7.5
n1-standard-4 4 15
n1-standard-8 8 30
n1-standard-16 16 60
n1-standard-32 32 120

这些机器类型仅在区域端点上提供。详细了解它们对其他 AI Platform Prediction 功能的支持

了解每种机器类型的价格。如需详细了解 Compute Engine (N1) 机器类型的规范,请参阅 Compute Engine 文档

设置输入数据的格式

在线预测的基本格式是数据实例列表。这些列表可以是普通的值列表,也可以是 JSON 对象的成员,具体取决于您在训练应用中配置输入的方式。了解如何设置复杂输入和二进制数据的格式以进行预测

以下示例显示了 TensorFlow 模型的输入张量和实例键:

{"values": [1, 2, 3, 4], "key": 1}

只要遵循以下规则,JSON 字符串的构成可能会很复杂:

  • 顶级实例数据必须是 JSON 对象,即键值对的字典。

  • 实例对象中的各个值可以是字符串、数字或列表。 您无法嵌入 JSON 对象。

  • 列表必须仅包含相同类型的内容(包括其他列表)。您不能混合使用字符串和数值。

您将在线预测的输入实例作为 projects.explain 调用的消息正文进行传递。详细了解预测请求正文的格式要求

  1. 如需使用 gcloud 提交请求,请确保输入文件是以换行符分隔的 JSON 文件,其中每个实例都是 JSON 对象,并且每行一个实例。

    {"values": [1, 2, 3, 4], "key": 1}
    {"values": [5, 6, 7, 8], "key": 2}
    

请求预测和说明

请求预测和说明:

gcloud beta ai-platform explain \
  --model $MODEL \
  --version $VERSION \
  --json-instances='your-data.txt' \
  --region us-central1

了解说明响应

部署模型后,您可以使用 Explainable AI SDK 为表格数据和图片数据请求说明并直观呈现特征归因结果:

import explainable_ai_sdk

m = explainable_ai_sdk.load_model_from_ai_platform(PROJECT_ID, MODEL_NAME, VERSION, region=REGION)
explanations = m.explain([instance_dict])
explanations[0].visualize_attributions()

对于表格模型,归因以条形图绘制。对于图片模型,归因使用您在部署模型时指定的可视化设置显示在输入图片上。

如需详细了解说明响应中的每个字段,请参阅 API 参考文档中的完整示例响应

如需了解如何解析说明响应,请参阅示例笔记本:

TensorFlow 2:

TensorFlow 1.15:

检查说明

以下代码示例可帮助您检查批量说明以及了解是否需要调整基准。

在代码中,您只需根据 explanation_metadata.json 文件中指定的内容更新输入键值。

{
    "inputs": {
      "YOUR_INPUT_KEY_VALUE": {
        "input_tensor_name": "YOUR_INPUT_TENSOR_NAME"
        "input_baselines": [0]
      }
    ...
}

例如,如果输入键值为“data”,则以下代码段第 4 行中的值也应该为“data”:

def check_explanations(example, mean_tgt_value=None, variance_tgt_value=None):
  passed_test = 0
  total_test = 1
  attribution_vals = example['attributions_by_label'][0]['attributions']['YOUR-INPUT-KEY-VALUE']

  baseline_score = example['attributions_by_label'][0]['baseline_score']
  sum_with_baseline = np.sum(attribution_vals) + baseline_score
  predicted_val = example['attributions_by_label'][0]['example_score']

  # Check 1
  # The prediction at the input is equal to that at the baseline.
  #  Please use a different baseline. Some suggestions are: random input, training
  #  set mean.
  if abs(predicted_val - baseline_score) <= 0.05:
    print('Warning: example score and baseline score are too close.')
    print('You might not get attributions.')
  else:
    passed_test += 1

  # Check 2 (only for models using Integrated Gradient explanations)
  # Ideally, the sum of the integrated gradients must be equal to the difference
  # in the prediction probability at the input and baseline. Any discrepancy in
  # these two values is due to the errors in approximating the integral.
  if explain_method == 'integrated-gradients':
    total_test += 1
    want_integral = predicted_val - baseline_score
    got_integral = sum(attribution_vals)
    if abs(want_integral-got_integral)/abs(want_integral) > 0.05:
        print('Warning: Integral approximation error exceeds 5%.')
        print('Please try increasing the number of integrated gradient steps.')
    else:
        passed_test += 1

  print(passed_test, ' out of ', total_test, ' sanity checks passed.')

在解析说明时,您可以对收到的每个归因执行检查:

for i in attributions_resp['explanations']:
  check_explanations(i)

使用近似误差来改善结果

AI Explanations 特征归因方法(采样 Shapley、积分梯度和 XRAI)全都基于 Shapley 值的变体。由于 Shapley 值的计算开销非常大,因此 AI Explanations 会提供近似值,而不是确切值。除特征归因结果外,AI Explanations 还会返回近似误差。如果近似误差超过 0.05,请考虑调整输入以减少误差。

您可以通过更改以下输入来减少近似误差并接近确切值:

  • 增加积分步数或路径数。
  • 更改您选择的输入基准。
  • 添加更多输入基准。将其他基准与积分梯度和 XRAI 方法配合使用时会增加延迟时间。将其他基准与采样 Shapley 方法配合使用时不会增加延迟时间。

增加步数或路径

如需减少近似误差,您可以增加:

  • 采样 Shapley 的路径数
  • 积分梯度或 XRAI 的积分步数

模型部署期间创建版本资源时设置这些参数。

调整基准

您可以在 explanation_metadata.json 文件中设置 input_baselines。本部分提供表格数据和图片数据的示例。输入基准可以表示与训练数据相关的中间值、最小值、最大值或随机值。

一般来说:

  • 从一个表示中间值的基准开始。
  • 将此基准更改为表示随机值的基准。
  • 请尝试使用两个基准,分别表示最小值和最大值。
  • 添加另一个表示随机值的基准。

表格数据示例

以下 Python 代码为表格数据创建说明元数据文件的内容。您可以使用采样 Shapley 或积分梯度来获取表格数据的特征归因。此代码属于表格数据的示例笔记本

请注意,input_baselines 是可以指定多个基准的列表。此示例仅设置了一个基准。该基准是训练数据的中间值列表(本例中为 train_data)。

explanation_metadata = {
    "inputs": {
      "data": {
        "input_tensor_name": model.input.name,
        "input_baselines": [train_data.median().values.tolist()],
        "encoding": "bag_of_features",
        "index_feature_mapping": train_data.columns.tolist()
      }
    },
    "outputs": {
      "duration": {
        "output_tensor_name": model.output.name
      }
    },
  "framework": "tensorflow"
  }

如需设置代表最小值和最大值的两个基准,请按如下所示设置 input_baselines[train_data.min().values.tolist(), train_data.max().values.tolist()]

图片数据示例

以下 Python 代码为图片数据创建说明元数据文件的内容。您可以使用积分梯度来获取图片数据的特征归因。此代码属于图片数据的示例笔记本

请注意,input_baselines 是可以指定多个基准的列表。此示例仅设置了一个基准。基准是随机值的列表。如果训练数据集中的图片包含大量黑白字符,则可以使用图片基准的随机值。

否则,请将 input_baselines 设为 [0, 1] 以表示黑白图片。

random_baseline = np.random.rand(192,192,3)

explanation_metadata = {
    "inputs": {
      "data": {
        "input_tensor_name": "input_pixels:0",
        "modality": "image",
        "input_baselines": [random_baseline.tolist()]
      }
    },
    "outputs": {
      "probability": {
        "output_tensor_name": "dense/Softmax:0"
      }
    },
  "framework": "tensorflow"
  }

后续步骤