个性化阅读
专注于IT技术分析

健全的逻辑和单调的人工智能模型

本文概述

人工智能已经迅速成为一种令人惊奇的资产, 在图像识别, 围棋甚至扑克等领域都达到了超人的性能水平。许多人对AI和人类的未来感到兴奋。同时, 人们普遍认为AI确实存在一个令人讨厌的缺陷:处于当前状态的AI可能出乎意料地不可靠。

危险的例子就是经典! IBM挑战赛期间, IBM AI的Watson轻松清理了董事会, 却错过了”最终危险!”问题, 该问题属于美国城市类别:”其最大的机场以二战英雄的名字命名;是第二次世界大战的第二大战场。”沃森回答说:”多伦多是什么????”-多余的问号(低赌注)表示对它的怀疑。

因此, 即使AI能够长时间(甚至数月, 数年, 数十年)进行类似童话般的表演, 但总有这种令人possibility舌的可能性, 突然之间, 它会神秘地失误。

我们人类最担心的不是AI会犯错, 而是错误将是多么”不合逻辑”。以沃森为例, 一个不知道问题答案的人会”从逻辑上”尝试至少猜出美国一个主要城市。我相信这是我们尚未公开采用自动驾驶汽车的主要原因之一:即使自动驾驶汽车在统计上可能更安全, 我们仍担心其潜在的AI可能会意外地与Watson类似地失误, 但影响更大。

这让我想知道, 正确的AI模型可以解决此问题吗?合适的AI是否有能力在关键时刻做出明智的决策, 即使它没有所有答案也是如此?这样的人工智能将能够改变技术的发展历程, 并为我们提供人工智能的童话般的好处……

我相信这些问题的答案是肯定的。我相信, 使用改进的, 更具逻辑约束的模型可以避免发生Watson这样的错误, 该模型的早期原型称为单调机器学习模型。借助适当的单调AI模型, 无需深入探讨:

  • 自动驾驶汽车会更安全, 因为即使在存在大量其他信号的情况下, 即使是最小量的人信号检测也始终足以激活安全协议。
  • 机器学习(ML)系统在对抗性攻击和意外情况下会更强大。
  • 机器学习的表现将更加合乎逻辑并且更易于理解。

我相信我们正在从AI的计算和算法能力飞速发展的时代过渡到AI的精细化, 有效性和理解性的时代, 单调机器学习模型是此令人振奋旅程的第一步。单调模型使AI更具”逻辑性”。

编者注:希望自己迈出第一步来了解ML基础知识的读者, 请阅读我们有关ML的介绍性文章。

单调AI模型的理论

那么什么是单调模型?松散地说, 单调模型是具有某些特征(单调特征)集的ML模型, 其增加总是导致模型增加其输出。

技术上…

…在上述定义中有两个地方不准确。

首先, 这里的特征是单调递增的。我们还可以具有单调递减的特征, 这些特征的增加总是导致模型的减少。可以简单地通过取反(乘以-1)将两者相互转换。

其次, 当我们说输出增加时, 我们并不是说它严格地增加了, 而是意味着它不会减少, 因为输出可以保持不变。

在现实生活中, 许多变量对表现出单调关系。例如:

  • 一次旅行的汽油价格在行驶距离上单调增加。
  • 信贷越好, 获得贷款的可能性就越大。
  • 预期的驾驶时间会随着交通量的增加而增加。
  • 收入随着广告的点击率而增加。

尽管这些逻辑关系很清楚, 但是对于使用有限数据且没有领域知识进行内插的ML模型, 它们可能不是。实际上, 该模型可能会错误地对它们进行插值, 从而导致荒谬而古怪的预测。能够捕获此类知识的机器学习模型在实践中表现得更好(通过避免过度拟合), 易于调试, 并且易于解释。在大多数用例中, 单调模型应与普通模型结合使用, 作为学习者集成的一部分。

单调AI模型真正发挥作用的地方之一是对抗性鲁棒性。单调模型是”强化的”机器学习模型, 这意味着它们可以抵抗对抗性攻击。只能操纵非单调特征的攻击者无法逃避单调AI模型, 因为他们无法相对于单调AI模型更改示例的标签。

单调AI模型的用例

到目前为止, 这种讨论完全是理论上的。让我们讨论一些实际的用例。

用例#1:恶意软件检测

单调AI模型最酷的用例之一就是在恶意软件检测中的使用。作为Windows Defender的一部分实现的, 在每个最新的Windows设备中都存在单调模型, 从而静默保护用户免受恶意软件的侵害。

在一种情况下, 恶意软件作者冒充合法的注册企业来欺骗证书颁发机构, 并使用受信任的证书成功地对数字签名进行了数字签名。幼稚的恶意软件分类程序可能会使用代码签名作为功能, 并且会表明此类样本是良性的。

但是, 对于Windows Defender的单调AI模型而言并非如此, 其单调功能只是表明恶意软件的功能。无论恶意软件作者注入多少”良性”内容, Windows Defender的单调AI模型都将继续捕获样本并保护用户免受损害。

在我的课程《红队黑客机器学习》中, 我教授了几种规避基于ML的恶意软件分类器的技术。其中一种技术包括将具有”良性”内容/功能的恶意样本塞满以逃避幼稚的ML模型。单调模型可以抵抗这种攻击, 并且如果恶意行为者希望逃避分类器的话, 就会迫使他们更加努力地工作。

用例2:内容过滤

假设有一个团队正在为学校图书馆构建一个网上冲浪内容过滤器。单调AI模型非常适合在这里使用, 因为包含不适当内容的论坛可能还包含很多可接受的内容。

天真的分类器可能会权衡”不适当”功能的存在与”不适当”功能的存在。但这不会这样做, 因为我们不希望孩子访问不适当的内容, 即使该内容仅占内容的一小部分。

用例3:自动驾驶汽车AI

想象一下构建一个自动驾驶汽车算法。它看着图像并看到绿灯。它还看到一个行人。是否应该权衡彼此的信号?绝对不。行人的存在足以决定要停下汽车。行人的出现应被视为单调特征, 在这种情况下应使用单调AI模型。

用例#4:推荐引擎

推荐引擎是单调AI模型的绝佳用例。通常, 他们可能对每个产品有很多输入:星级, 价格, 评论数量等。在所有其他输入相同的情况下(例如星级和价格), 我们希望评论数量更多的产品。我们可以使用单调的AI模型来实现这种逻辑。

用例5:垃圾邮件和网络钓鱼过滤

该用例类似于恶意软件检测用例。恶意用户可能会使用带有良性伪造术语的垃圾邮件或网络钓鱼电子邮件来欺骗垃圾邮件过滤器。单调的AI模型将不受此影响。

实现与示范

关于单调AI模型的免费可用实现, 其中三个是最受支持的:XGBoost, LightGBM和TensorFlow Lattice。

单调ML XGBoost教程

基于多年的经验研究和竞争, XGBoost被认为是结构化数据性能最佳的算法之一。此外, XGBoost已实现单调性。

以下有关如何使用单调ML模型的演示XGBoost教程随附了一个Python回购。

首先导入一些库:

import random
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.metrics import confusion_matrix
import seaborn as sns

sns.set(font_scale=1.4)

我们要建模的场景是内容过滤或恶意软件数据库。我们将具有一些benign_features, 这些模型将对与”科学”, “历史”和”体育”相关的内容量进行建模, 或者在恶意软件中对”代码签名”和”公认的作者”进行建模。

同样, 我们将具有恶意软件功能, 该模型可以模拟例如与”暴力”和”毒品”相关的内容量, 或者在恶意软件的情况下, 可以模拟”对加密库进行调用的次数”和”与已知的恶意软件家族相似。”

我们将通过生成模型对情况进行建模。我们使用以下函数随机生成大量数据点, 大约一半为良性, 一半为恶意。

def flip():
    """Simulates a coin flip."""
    return 1 if random.random() < 0.5 else 0

每个数据点将随机生成其特征。 “良性”数据点对良性功能的偏见较高, 而”恶意”数据点对恶意功能的偏见较高。

我们将使用三角形分布, 如下所示:

bins = [0.1 * i for i in range(12)]

plt.hist([random.triangular(0, 1, 1) for i in range(50000)], bins)
类似于阶梯的数据点分布图。从0.1到0.2、0.2到0.3等的大多数存储桶中的数据点比左侧的数据点多约1,000个。第一个从0到0.1,似乎有大约500。

我们将使用此功能来捕获以上逻辑:

def generate():
    """Samples from the triangular distribution."""
    return random.triangular(0, 1, 1)

然后, 我们将继续创建数据集:

m = 100000
benign_features = 5
malicious_features = 5
n = benign_features + malicious_features
benign = 0
malicious = 1
X = np.zeros((m, n))
y = np.zeros((m))
for i in range(m):
    vec = np.zeros((n))
y[i] = flip()
if y[i] == benign:
    for j in range(benign_features):
        vec[j] = generate()
    for j in range(malicious_features):
        vec[j + benign_features] = 1 - generate()
else:
    for j in range(benign_features):
        vec[j] = 1 - generate()
    for j in range(malicious_features):
        vec[j + benign_features] = generate()
X[i, :] = vec

X包含随机生成特征的向量, 而y包含标签。这个分类问题并非无关紧要。

典型样本:良性与恶意。每个图显示10个特征(0到9),其值的范围为0到1。在良性图中,大多数特征都在0.5以下;而在良性图中,大多数特征在0.5以下。功能6和7高于0.6;特征2接近0.8;而功能3接近1.0。在恶意图中,十分之七的特征在0.5以上,包括特征5、6、7和8。

你可以看到, 良性样本通常在前几个功能中具有更大的权重, 而恶意样本通常在后几个功能中具有更大的权重。

准备好数据后, 让我们执行一个简单的训练测试拆分:

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

我们将使用一个函数来准备要与我们的XGBoost教程一起使用的数据:

import xgboost as xgb

def prepare_for_XGBoost(X, y):
    """Converts a numpy X and y dataset into a DMatrix for XGBoost."""
    return xgb.DMatrix(X, label=y)

dtrain = prepare_for_XGBoost(X_train, y_train)
dtest = prepare_for_XGBoost(X_test, y_test)
dall = prepare_for_XGBoost(X, y)

现在, 让我们训练和测试数据上的简单(非单调)XGBoost模型。然后, 我们将打印出混淆矩阵, 以查看正确标记的正例, 正确标记的负例, 错误标记的正例和错误标记的负例的数值细分。

params = {"n_jobs": -1, "tree_method": "hist"}
model_no_constraints = xgb.train(params=params, dtrain=dtrain)
CM = predict_with_XGBoost_and_return_confusion_matrix(
    model_no_constraints, dtrain, y_train
)
plt.figure(figsize=(12, 10))
sns.heatmap(CM / np.sum(CM), annot=True, fmt=".2%", cmap="Blues")
plt.ylabel("True Label")
plt.xlabel("Predicted Label")
plt.title("Unconstrained model's training confusion matrix")
plt.show()
print()
CM = predict_with_XGBoost_and_return_confusion_matrix(
    model_no_constraints, dtest, y_test
)
plt.figure(figsize=(12, 10))
sns.heatmap(CM / np.sum(CM), annot=True, fmt=".2%", cmap="Blues")
plt.ylabel("True Label")
plt.xlabel("Predicted Label")
plt.title("Unconstrained model's testing confusion matrix")
plt.show()
model_no_constraints = xgb.train(params=params, dtrain=dall)
无约束模型的训练混淆矩阵,一个二乘二的棋盘格。 Y轴称为"真实标签",顶部为0,底部为1。 X轴称为"预测标签",左侧为0,右侧为1。色标从零的白色变为0.5的深蓝色。左上角和右下角正方形是深蓝色,分别为49.29%和48.89%。其他两个正方形接近白色,均为0.91%。右侧是非常相似的图表,但用于测试而非培训,按阅读顺序分别为49.33%,1.25%,1.20%和48.23%。

查看结果, 我们可以发现没有明显的过度拟合。我们将这些结果与单调模型的结果进行比较。

为此, 让我们训练和测试单调的XGBoost模型。我们传递单调约束的语法是一个序列(f0, f1, …, fN), 其中每个fi都是-1、0或1中的一个, 具体取决于我们是否希望特征i单调递减, 不受约束, 或单调增加。在当前情况下, 我们将恶意功能指定为单调递增。

params_constrained = params.copy()
monotone_constraints = (
    "("
    + ", ".join([str(0) for m in range(benign_features)])
    + ", "
    + ", ".join([str(1) for m in range(malicious_features)])
    + ")"
)
print("Monotone constraints enforced are:")
print(monotone_constraints)
params_constrained["monotone_constraints"] = monotone_constraints
model_monotonic = xgb.train(params=params_constrained, dtrain=dtrain)
CM = predict_with_XGBoost_and_return_confusion_matrix(model_monotonic, dtrain, y_train)
plt.figure(figsize=(12, 10))
sns.heatmap(CM / np.sum(CM), annot=True, fmt=".2%", cmap="Blues")
plt.ylabel("True Label")
plt.xlabel("Predicted Label")
plt.title("Monotonic model's training confusion matrix")
plt.show()
print()
CM = predict_with_XGBoost_and_return_confusion_matrix(model_monotonic, dtest, y_test)
plt.figure(figsize=(12, 10))
sns.heatmap(CM / np.sum(CM), annot=True, fmt=".2%", cmap="Blues")
plt.ylabel("True Label")
plt.xlabel("Predicted Label")
plt.title("Monotonic model's testing confusion matrix")
plt.show()
model_monotonic = xgb.train(params=params_constrained, dtrain=dall)
单调AI模型的训练混淆矩阵,一个2乘2的棋盘格。 Y轴称为"真实标签",顶部为0,底部为1。 X轴称为"预测标签",左侧为0,右侧为1。色标从零的白色变为0.5的深蓝色。左上角和右下角正方形是深蓝色,分别为49.20%和48.82%。右上角和左下角正方形接近白色,分别为0.99%和0.98%。右边是测试而非培训的非常相似的图表,按阅读顺序分别为49.32%,1.26%,1.22%和48.20%。

很明显, 单调模型的性能与无约束模型的性能相同。

现在, 我们将创建一个对抗数据集。我们将获取所有恶意样本, 并将它们的良性功能全部设置为1, 以”填充”它们的良性功能。然后, 我们将看到两种模型如何并行运行。

X_adversarial = X[y == malicious]
y_adversarial = len(X_adversarial) * [malicious]
for i in range(len(X_adversarial)):
    vec = X_adversarial[i, :]
    for j in range(benign_features):
        vec[j] = 1
    X_adversarial[i, :] = vec

让我们将它们转换为XGBoost提取的表单:

dadv = prepare_for_XGBoost(X_adversarial, y_adversarial)

对于XGBoost教程的最后一步, 我们将测试两种机器学习模型类型:

CM = predict_with_XGBoost_and_return_confusion_matrix(
    model_no_constraints, dadv, y_adversarial
)
plt.figure(figsize=(12, 10))
sns.heatmap(CM / np.sum(CM), annot=True, fmt=".2%", cmap="Blues")
plt.ylabel("True Label")
plt.xlabel("Predicted Label")
plt.title("Unconstrained model's confusion matrix on adversarial dataset")
plt.show()
CM = predict_with_XGBoost_and_return_confusion_matrix(
    model_monotonic, dadv, y_adversarial
)
plt.figure(figsize=(12, 10))
sns.heatmap(CM / np.sum(CM), annot=True, fmt=".2%", cmap="Blues")
plt.ylabel("True Label")
plt.xlabel("Predicted Label")
plt.title("Monotonic model's confusion matrix on adversarial dataset")
plt.show()
在同一个对抗数据集上,无约束与单调AI模型的训练混淆矩阵。每个都是两乘两格的棋盘。 Y轴称为"真实标签",顶部为0,底部为1。 X轴称为"预测标签",左侧为0,右侧为1。色标从零的白色变为1.0的深蓝色。两个矩阵的最上一行仅包含0.00%。左侧(无约束)矩阵的底行显示为99.99%和0.01%,而右侧(单调)矩阵的底行显示为75.81%和24.19%。

如你所见, 单调AI模型在对抗攻击方面的健壮性大约是2500倍。

LightGBM

在LightGBM中使用单调功能的语法是相似的。

TensorFlow格子

TensorFlow Lattice是用于处理单调性约束的另一个框架, 它是一组预建的TensorFlow估计器以及TensorFlow运算符, 用于构建你自己的晶格模型。格是多维插值查询表, 这意味着它们是在空间(如网格)中均匀分布的点, 以及这些点处的函数值。根据Google AI博客:

“…对查询表的值进行了训练, 以最大程度地减少训练示例中的损失, 但此外, 查询表中的相邻值也被约束沿输入空间的给定方向增加, 这使得模型输出在这些方向。重要的是, 由于它们在查找表值之间进行插值, 因此网格模型是平滑的, 并且预测是有界的, 这有助于避免在测试时间中虚假的大或小预测。”

可在此处找到有关如何使用TensorFlow Lattice的教程。

单调AI模型与未来

从防御设备免受恶意攻击到提供合理且有用的餐厅建议, 单调的AI模型已被证明对社会是一个巨大的福音, 也是一种掌握的绝佳工具。这里的单调模型将我们带入AI安全, 精巧和理解的新时代。所以我说, 这是单调的AI模型, 这是进步。

赞(0)
未经允许不得转载:srcmini » 健全的逻辑和单调的人工智能模型

评论 抢沙发

评论前必须登录!