本文概述
- 单调AI模型的理论
- 技术上…
- 单调AI模型的用例
- 实现与示范
- 单调AI模型与未来
危险的例子就是经典! IBM挑战赛期间, IBM AI的Watson轻松清理了董事会, 却错过了” 最终危险!” 问题, 该问题属于美国城市类别:” 其最大的机场以二战英雄的名字命名;是第二次世界大战的第二大战场。” 沃森回答说:” 多伦多是什么????” -多余的问号(低赌注)表示对它的怀疑。
因此, 即使AI能够长时间(甚至数月, 数年, 数十年)进行类似童话般的表演, 但总有这种令人possibility舌的可能性, 突然之间, 它会神秘地失误。
我们人类最担心的不是AI会犯错, 而是错误将是多么” 不合逻辑” 。以沃森为例, 一个不知道问题答案的人会” 从逻辑上” 尝试至少猜出美国一个主要城市。我相信这是我们尚未公开采用自动驾驶汽车的主要原因之一:即使自动驾驶汽车在统计上可能更安全, 我们仍担心其潜在的AI可能会意外地与Watson类似地失误, 但影响更大。
这让我想知道, 正确的AI模型可以解决此问题吗?合适的AI是否有能力在关键时刻做出明智的决策, 即使它没有所有答案也是如此?这样的人工智能将能够改变技术的发展历程, 并为我们提供人工智能的童话般的好处……
我相信这些问题的答案是肯定的。我相信, 使用改进的, 更具逻辑约束的模型可以避免发生Watson这样的错误, 该模型的早期原型称为单调机器学习模型。借助适当的单调AI模型, 无需深入探讨:
- 自动驾驶汽车会更安全, 因为即使在存在大量其他信号的情况下, 即使是最小量的人信号检测也始终足以激活安全协议。
- 机器学习(ML)系统在对抗性攻击和意外情况下会更强大。
- 机器学习的表现将更加合乎逻辑并且更易于理解。
编者注:希望自己迈出第一步来了解ML基础知识的读者, 请阅读我们有关ML的介绍性文章。
单调AI模型的理论 那么什么是单调模型?松散地说, 单调模型是具有某些特征(单调特征)集的ML模型, 其增加总是导致模型增加其输出。
技术上… … 在上述定义中有两个地方不准确。
首先, 这里的特征是单调递增的。我们还可以具有单调递减的特征, 这些特征的增加总是导致模型的减少。可以简单地通过取反(乘以-1)将两者相互转换。
其次, 当我们说输出增加时, 我们并不是说它严格地增加了, 而是意味着它不会减少, 因为输出可以保持不变。
在现实生活中, 许多变量对表现出单调关系。例如:
- 一次旅行的汽油价格在行驶距离上单调增加。
- 信贷越好, 获得贷款的可能性就越大。
- 预期的驾驶时间会随着交通量的增加而增加。
- 收入随着广告的点击率而增加。
单调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 snssns.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)
文章图片
我们将使用此功能来捕获以上逻辑:
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包含标签。这个分类问题并非无关紧要。
文章图片
你可以看到, 良性样本通常在前几个功能中具有更大的权重, 而恶意样本通常在后几个功能中具有更大的权重。
准备好数据后, 让我们执行一个简单的训练测试拆分:
from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
我们将使用一个函数来准备要与我们的XGBoost教程一起使用的数据:
import xgboost as xgbdef 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)
文章图片
查看结果, 我们可以发现没有明显的过度拟合。我们将这些结果与单调模型的结果进行比较。
为此, 让我们训练和测试单调的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)
文章图片
很明显, 单调模型的性能与无约束模型的性能相同。
现在, 我们将创建一个对抗数据集。我们将获取所有恶意样本, 并将它们的良性功能全部设置为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模型在对抗攻击方面的健壮性大约是2500倍。
LightGBM
在LightGBM中使用单调功能的语法是相似的。
TensorFlow格子
TensorFlow Lattice是用于处理单调性约束的另一个框架, 它是一组预建的TensorFlow估计器以及TensorFlow运算符, 用于构建你自己的晶格模型。格是多维插值查询表, 这意味着它们是在空间(如网格)中均匀分布的点, 以及这些点处的函数值。根据Google AI博客:
“ …对查询表的值进行了训练, 以最大程度地减少训练示例中的损失, 但此外, 查询表中的相邻值也被约束沿输入空间的给定方向增加, 这使得模型输出在这些方向。重要的是, 由于它们在查找表值之间进行插值, 因此网格模型是平滑的, 并且预测是有界的, 这有助于避免在测试时间中虚假的大或小预测。”
可在此处找到有关如何使用TensorFlow Lattice的教程。
单调AI模型与未来 【健全的逻辑和单调的人工智能模型】从防御设备免受恶意攻击到提供合理且有用的餐厅建议, 单调的AI模型已被证明对社会是一个巨大的福音, 也是一种掌握的绝佳工具。这里的单调模型将我们带入AI安全, 精巧和理解的新时代。所以我说, 这是单调的AI模型, 这是进步。
推荐阅读
- 使用AWS Lambda@Edge进行灵活的A/B测试
- 8种无服务器计算平台来运行你的应用程序代码
- 安卓基础之读取联系人的姓名和电话
- Server.MapPath是使用
- 安卓 通过www读取Application.persistentDataPath
- Android 如何将手机屏幕投屏到PC端
- 项目初始化以后出现(Unable to load script from assets 'index.android.bundle)
- Spring08-----IoC容器ApplicationContext
- Unexpected directive 'XXX' imported by the module 'AppMoode'