轻松实现视频游戏的深度强化学习
深度 Q 网络已经彻底改变了深度强化学习领域,但是简单实验的技术先决条件直到现在还禁止新人进入…
使用 DQN 代理的雅达利乒乓
在本帖中,我们将调查如何使用谷歌强化学习库多巴胺为雅达利 2600 游戏训练一个深度 Q 网络(DQN)代理 (Mnih 等人,2015)。虽然有许多 RL 函数库,但这个函数库是根据的四个基本特性特别设计的:
- 简单的实验
- 柔性开发
- 紧凑可靠
- 可再生的
我们相信这些原则使得多巴胺成为当今最好的学习环境之一。此外,我们甚至让这个库在 Windows 上工作,我们认为这是一个了不起的成就!
在我看来,在强化学习中,任何受过训练的 RL 代理的可视化都是绝对必要的!因此,我们将(当然)在最后为我们自己的训练有素的代理人包括这一点!
我们将检查所有需要的代码片段(与其他库相比是最少的),但是你也可以在下面的 Github repo 中找到所有需要的脚本。
1.强化学习和深度 Q 学习简介
深度强化学习的一般前提是
“从高维度的感官输入中获得环境的有效表示,并使用这些来将过去的经验推广到新的情况。”
- Mnih 等人(2015 年)
如前所述,我们将由 Deepmind 实现 DQN 模型,它只使用原始像素和游戏分数作为输入。使用类似于图像分类的卷积神经网络来处理原始像素。主要区别在于目标函数,对于 DQN 代理来说,它被称为最优行动值函数
其中 rₜ 是在时间 t 用 γ 折现的最大奖励总和,使用行为策略 π = P(a ∣ s) 为每个观察-动作对获得。
深度 Q-Learning 的细节相对较多,如的经验重演和的迭代更新规则。因此,我们建议读者参考原始论文,以便更好地了解数学细节。
与当时(2015 年)之前的方法相比,DQN 的一个关键优势是能够使用相同的超参数集和仅像素值和游戏分数作为输入,超越 Atari 2600 游戏的现有方法,这显然是一个巨大的成就。
2.装置
这篇文章不包括安装 Tensorflow 的说明,但我们想强调的是,你可以同时使用CPU 和 GPU 版本。
然而,假设您使用的是Python 3.7.x
,这些是您需要安装的库(它们都可以通过pip
安装):
tensorflow-gpu=1.15 (or tensorflow==1.15 for CPU version)
cmake
dopamine-rl
atari-py
matplotlib
pygame
seaborn
pandas
3.训练我们的特工
深度强化学习的超参数调整需要大量的计算资源,因此被认为超出了本指南的范围。幸运的是,多巴胺的作者已经提供了 Bellemare 等人(2017)使用的具体超参数,可以在下面的文件中找到。我们使用这个*“配置文件”*的内容作为一个字符串,我们使用 gin 配置框架解析它。它包含所有相关的训练、环境和所需的超参数,这意味着我们只需要更新我们想要运行的游戏(尽管超参数可能不会对所有游戏都同样有效)。
我们从导入所需的库开始
import os
import gin.tf
from dopamine.discrete_domains import run_experiment
接下来,我们定义根路径来保存我们的实验
DQN_PATH **=** '/tmp/path/to/save/experiments/dqn'
然后,我们定义想要运行的游戏(在本例中,我们运行游戏“Pong”),
GAME **=** 'Pong'
最后,我们定义 DQN 配置字符串:
dqn_config **=** """
# Hyperparameters used for reporting DQN results in Bellemare et al. (2017).
import dopamine.discrete_domains.atari_lib
import dopamine.discrete_domains.run_experiment
import dopamine.agents.dqn.dqn_agent
import dopamine.replay_memory.circular_replay_buffer
import gin.tf.external_configurables
DQNAgent.gamma = 0.99
DQNAgent.update_horizon = 1
DQNAgent.min_replay_history = 50000 # agent steps
DQNAgent.update_period = 4
DQNAgent.target_update_period = 10000 # agent steps
DQNAgent.epsilon_train = 0.01
DQNAgent.epsilon_eval = 0.001
DQNAgent.epsilon_decay_period = 1000000 # agent steps
DQNAgent.tf_device = '/gpu:0' # use '/cpu:*' for non-GPU version
DQNAgent.optimizer = @tf.train.RMSPropOptimizer()
tf.train.RMSPropOptimizer.learning_rate = 0.00025
tf.train.RMSPropOptimizer.decay = 0.95
tf.train.RMSPropOptimizer.momentum = 0.0
tf.train.RMSPropOptimizer.epsilon = 0.00001
tf.train.RMSPropOptimizer.centered = True
atari_lib.create_atari_environment.game_name = "{}"
# Deterministic ALE version used in the DQN Nature paper (Mnih et al., 2015).
atari_lib.create_atari_environment.sticky_actions = False
create_agent.agent_name = 'dqn'
Runner.num_iterations = 200 # 200
Runner.training_steps = 250000 # 250000 # agent steps
Runner.evaluation_steps = 125000 # 125000 # agent steps
Runner.max_steps_per_episode = 27000 # 27000 # agent steps
AtariPreprocessing.terminal_on_life_loss = True
WrappedReplayBuffer.replay_capacity = 1000000
WrappedReplayBuffer.batch_size = 32
""".format(GAME)
基本上就是这样了!
现在,我们只需编写训练代理的最终代码,
运行上面的(需要很长时间!),你应该看到 DQN 模型粉碎乒乓游戏!
4.想象我们的特工
我们在 GTX 1070 GPU 上运行了大约 22 小时的实验。
我们包含了优化结果的可视化和 Pong 代理的*【live】*性能。我们将此分为两段:
a)培训结果
导航到 tensorboard logs 文件夹,该文件夹可以在您之前定义的DQN_PATH
中找到,然后运行以下命令:
tensorboard --logdir .
这应该会给你一个类似这样的视觉效果
您可以看到,运行 12 次后,性能才逐渐提高。
b)现场演示
现在是有趣的部分!
我们将使用位于多巴胺库的utils
文件夹中的example_vis_lib
脚本。因此,我们运行实时演示的脚本如下所示:
运行上面的代码,您应该看到脚本开始为 1000 步生成图像,然后将图像保存到 video.mp4 文件中。
这是我们模型的 gif 图:
雅达利突破使用 DQN 代理培训 22 小时
很明显,经纪人并不完美,也确实输了不少比赛。尽管如此,它做了一个相对不错的工作!
如果我们多训练几天(或者使用更大的 GPU),我们可能会得到一个接近完美的代理。
5.结论
就这样吧!
这基本上就是我们实际上需要多么少的代码来实现一个最先进的 DQN 模型来运行 Atari 2600 游戏并进行现场演示!
随意试验明显更好的彩虹模型 ( Hessel et al .,2018 ),这是也包括在多巴胺库,以及其他非雅达利的游戏!
作为最终演示,我们提供了一个小的 gif 图片,展示了一名代理人使用彩虹模型接受了为期两天的雅达利突破培训:
雅达利突破与彩虹模型训练了两天
你可以看到彩虹模型表现得非常好!
如果你喜欢这篇文章,请不要犹豫留下你的任何意见或建议!
6.参考
[1]林隆基,用神经网络进行机器人的强化学习(1993),CS-93-103 号。
[2] M. Hessel 等,Rainbow:结合深度强化学习的改进(2018),第三十二届 AAAI 人工智能会议。
[3] P. S. Castro,S. Moitra,C. Gelada,S. Kumar,M. G. Bellemare,多巴胺:深度强化学习的研究框架 (2018),arXiv 预印本 arXiv:1812.06110。
[4] V. Mnih 等人,(2015),通过深度强化学习实现人类水平的控制,Nature 518.7540(529–533)。
原载于 2020 年 7 月 22 日https://holmdk . github . io。
生产中的深度强化学习
Zynga 使用强化学习来个性化用户体验
弗兰基·查马基在 Unsplash 上拍摄的照片
由来自 Zynga ML 工程团队的迈赫迪·本·阿耶德和帕特里克·哈利娜
系列介绍
设计用户体验是一门困难的艺术。与其他应用程序相比,视频游戏为设计师提供了一个巨大的工作空间。在 Zynga,我们一直在想创新的方法来最大化用户在玩游戏时的体验。
在这个多部分的系列中,Zynga 的 ML 工程团队将讨论如何在制作中使用深度强化学习(RL)来个性化 Zynga 游戏的许多方面。深度强化学习的使用已被证明在增加关键指标方面是成功的,如用户保留率和用户参与度。这些文章是我们在 2019 年多伦多机器学习峰会和 2020 年 Spark 峰会上的演讲的延伸。
2019 年多伦多机器学习峰会
在第一篇文章中,我们将:
- 介绍深度强化学习
- 解释为什么它是驱动个性化系统的良好候选
- 对其在 Zynga 的使用做一个高层次的概述
本系列的其余部分将涵盖以下内容:
- 第 2 部分:深入探究 Zynga 的 RL 应用
- 第 3 部分:RL 技术和基础设施
- 第 4 部分:RL 的培训挑战
- 第 5 部分:提升 RL 应用程序的技巧
关于 Zynga
Zynga 是全球领先的手机游戏开发商之一。它的投资组合有一些世界上最受欢迎的手机游戏,如与朋友的话,帝国和谜题,香椿爆炸,CSR2,扑克,等等。Zynga 的使命是通过游戏将世界各地的人们联系起来。
个性化用户体验的需求
为广泛的用户构建成功的应用程序是具有挑战性的。日常挑战应该有多难?应该推荐什么游戏模式?每个用户都是不同的,这使得很难构建一个适合每个人需求的应用程序。这种差异可能是由于玩家的人口统计,位置,甚至他们的游戏风格。因此,构建个性化的用户体验有可能提高用户参与度和忠诚度。
虽然在用户会话期间有许多旋钮和杠杆可以控制,但个性化可以归结为一个共同的模式:给定用户的状态,选择一个动作以最大化长期回报。
这些是 Zynga 个性化问题中典型的状态、行为和奖励的例子:
- State :用户的背景,由一组特征组成,例如,他们玩游戏多长时间了,他们在什么级别,在过去几个级别的表现历史,等等。
- 动作:应用程序被控制的方面。可能是下一关的难度,发送消息的时间,推荐的游戏模式等等。
- 奖励:这是我们希望个性化改进的关键绩效指标(KPI)。对于 Zynga 来说,其中一些指标是参与度指标,如玩家玩的关卡数量和会话长度。
分段个性化
Zynga 在使用个性化来增强游戏体验方面有着悠久的历史。一种已经被成功使用的简单方法是基于规则的优化。这种方法根据玩家的属性将玩家分成不同的部分(或组),并为每个部分提供定制体验。
细分对于广泛的群体很有效,但是对于细粒度的个性化就不那么有效了。该过程也是非常手动的,并且需要人在回路中进行任何调整。这导致了一些问题:
- 将用户群细分需要人类的直觉和反复试验。
- 需要进行 A/B 测试,以发现应该将哪种经验分配给每个细分市场,从而提升 KPI。
- 规则中可以使用的属性数量是有限的(一个人只能制定这么多规则)。这将细分限制为非常粗粒度的个性化。
- 随着应用程序功能的变化和受众变得更加成熟,微调的细分策略会变得陈旧,这就需要不断的手动调整和维护。
深度加固解决方案
近年来深度学习的兴起及其与强化学习的结合为个性化提供了新的解决方案。
深度学习是一种机器学习,利用人工神经网络来学习数据中的复杂关系。给定一大组数据和预期输出,训练神经网络来学习将输入数据转换为预期输出的模式。
除了使用激活函数之外,这些网络的分层架构允许这些模型学习数据中较低和较高层次的概念,这是使用经典机器学习模型所不可能的。
近年来,深度学习经历了大量的突破,导致了图像和语音识别以及深度强化学习等领域的大量成功。
安娜斯塔西娅·杜尔吉尔在 Unsplash 上的照片
**另一方面,**强化学习是一种经典的机器学习技术。它专注于训练代理人做出一系列决策,使长期总回报最大化。长期方面是关键;代理不会选择短期优化的操作。代理人可能会在短期内遭受损失,以便在稍后的时间点获得更大的收益。
强化学习代理在一个循环中与环境交互,并通过试错进行学习。在每个周期,它:
- 从环境(例如,用户上下文)接收观察
- 根据观察结果选择行动
- 接收对所选行动的反馈,作为奖励和新的观察
图片来自 Pixabay 的 uleem odhit 和 Pexels 的 cottonbro
深度强化学习是两种技术的结合。使用深度神经网络作为函数逼近允许代理解决使用经典强化学习不可能解决的问题。它允许代理:
- 使用大的状态空间来表示环境的观察值
- 改进未来奖励近似值
- 使用隐藏层学习和概括复杂的问题
- 适当地处理新的观察,即使他们以前没有经历过
使用深度强化学习训练的代理不仅可以学习解决复杂问题的最佳策略,还可以适应环境的变化。
结论
深度学习和深度强化学习释放了解决以前不可能解决的问题的力量,例如复杂环境中的规划和高维空间中的学习模式。在 Zynga,我们相信深度强化学习的使用将继续使我们能够为每个用户个性化我们的游戏,无论他们的技能水平、位置或人口统计。
下一步是什么?
在接下来的文章中,我们将与您分享有关深度强化学习代理的不同用例的更多信息,以便个性化我们的用户体验。我们还将提供对我们的机器学习基础设施和深度强化学习框架的见解,我们建立并开源了名为 rl-bakery 的框架。最后,我们将分享在此过程中遇到的一些主要挑战和学到的东西。
敬请期待!
Zynga 生产中的深度强化学习
活动讲座
帕特里克·哈琳娜和迈赫迪·本·阿耶德| TMLS2019
https://torontomachinelearning.com/
深度强化学习已经在新闻中看到了很多突破,从像围棋、雅达利和 Dota 这样的游戏到自动驾驶汽车,但在生产中将其应用于数百万人带来了很多挑战。
强化学习的承诺是自动化的用户体验优化。作为世界上最大的移动视频游戏公司之一,Zynga 需要自动化,以便为我们 7000 万月活跃用户提供个性化的游戏体验。
本次演讲讨论了 RL 如何解决许多业务问题,在生产中使用 RL 的挑战,以及 Zynga 的 ML 工程团队如何通过我们的个性化管道克服这些挑战。
生产中的深度强化学习第 2 部分:个性化用户通知
Zynga ML 工程团队的迈赫迪·本·阿耶德(T1)和 T2·帕特里克·哈琳娜(T3)。
这个系列讨论了 Zynga 如何在产品中使用深度强化学习来个性化我们游戏中的用户体验。它基于我们在 Spark 峰会和多伦多 ML 峰会上的陈述。
在这篇文章中,我们将讨论如何使用 RL 来个性化通知,并提高 Words with Friends Instant 的点击率。它作为一个例子来说明构建 RL 应用程序需要什么,以及为什么 RL 如此强大。
亚历克·鲍德温欣喜若狂地收到了来自 Words With Friends 的个性化推送通知(由 Zynga 公司提供)
我们使用强化学习的旅程始于 2018 年。我们知道它在理论上符合个性化的需求,但我们需要测试它在现实世界中是否可行。在本文中,我们将讨论一个 Zynga 应用程序来说明 RL 如何对个性化产生真正的影响。为了保护商业秘密,一些细节被模糊处理。剧透警告:RL 特工成功了!从那以后,我们继续为深度 RL 应用开发开源库, RL Bakery ,并推出了其他几个生产应用。
推送通知计时
大多数移动应用程序每天都向他们的用户群发送消息。例如,Zynga 的热门文字游戏 Words With Friends 会发送消息提醒用户,他们的朋友正在等待搬家。决定何时发送该信息是一个挑战。我们有全球用户群,每个人都有自己的时间表。发送通知的时间是敬业度的关键驱动因素。
- 如果在合适的时间发送通知,用户可能会回来参与游戏。
- 如果通知是在一个糟糕的时间发送的,用户可能会忽略它,不再回到游戏中来。你甚至会错过你的妈妈正等着你采取下一步行动!
与朋友的对话 2(由 Zynga 公司提供)
以前的方法
在我们开始之前,游戏已经实现了一个基于工作段的解决方案。玩家群根据用户所在的国家分为 3 个时区。每个用户在他们所在时区的晚上都会收到一条消息,因为那是最受欢迎的游戏时间。这种方法作为快速的第一次尝试效果很好,但是他们准备对其进行优化。
我们如何为全球用户选择最佳的通知时间?(由凯尔·格伦在 Unsplash 上拍摄)
你能想到这个解决方案有什么缺点吗?
首先是粗略的时区近似值。当然,世界上不止有三个时区。不仅如此,像美国和加拿大这样的国家有多个时区,很难将玩家的国家映射到一个特定的时区。我们甚至可能没有与所有用户相关联的正确国家。
除了数据问题之外,缺乏个性化是基于细分的个性化方案的常见问题。即使我们确定了某人的时区,每个人都有自己的时间表。如果是周一,在凌晨 3 点给某人发信息可能会更好,因为那是他们夜班的“午休时间”。细分策略没有使用足够的玩家背景来执行细粒度的用户体验个性化。
这种方法的前提有一个更关键的问题,说明了为什么 RL 对于个性化如此强大。最终,我们的目标是提高用户参与度。如果我们有一个完美的模型告诉我们这个用户将在晚上 7 点玩,那么在那个时间发送消息有意义吗?他们已经开始参与游戏了!我们应该试着在一小时前发送消息吗?12 小时前?如果我们连续三次尝试在晚上 7 点给用户发消息,而他们没有回应,我们是否应该尝试不同的时间?这就是 RL 的用武之地。它回答了这个问题:我对这个用户采取什么行动来增加参与度。
强化学习设置
回顾我们系列的第 1 部分,我们将个性化问题公式化为为给定状态选择一个动作,以最大化长期回报。对于通知定时问题,我们使用以下状态、动作和奖励:
- **状态:**用户与之前推送通知的历史交互。时间窗口被限定为 14 天,并且数据点被结构化为时间序列。
- **操作:**发送下一个通知的时间。所以有 24 个动作可用。
- **奖励:**当用户与推送通知交互时,提供一个积极的奖励。否则不提供奖励。
我们建立了一个机器学习管道,为所有符合推送通知条件的玩家收集、训练和执行批量推荐。
(关于基础设施的更多细节将在本系列的第 3 部分中分享。)
强化学习培训设置
构建强化学习应用实际上意味着什么?本质上,我们是在训练一个代理来选择动作。有很多训练智能体的深度学习算法:DQN、PPO、TD3、SAC 等。每个月都有新的算法(有新的 3 个字母缩写)发表在 ML 论文上。
我们的专业不是研究和实现这些算法。我们使用了来自开源 TF-Agents 库的现成实现。我们选择使用 DQN 算法进行概念验证。这是一种更简单的算法,但它实际上被用于 AlphaGo 项目,以击败世界上最好的围棋选手。
选择 RL 算法后,我们选择了一组超参数。其中许多都涉及任何深度学习算法核心的深度学习模型。您需要选择最能代表您的功能和策略(代理的决策逻辑)的网络架构。)您还需要选择深度学习超参数,如学习率、优化算法(如 ADAM、SGD)等。
还有一些 RL 特定参数。对 DQN 来说,探索是以一种ε贪婪机制进行的。这意味着在概率为ε的情况下,会选择一个随机行动。其余时间,将使用具有最佳预测奖励的动作。通常以较高的ε开始,以鼓励探索,然后随着时间的推移降低ε,因为代理专注于成功的策略。
使用 RL 选择超参数值很困难。与监督学习不同,您不能简单地提供一组静态的标记数据,并确定哪些超参数会产生最佳结果。RL 只从环境的反馈中学习。从一个时间步长到未来时间的复杂交互无法从静态数据集中捕捉到。然而,在这种情况下,我们有一个现有的策略(简单的分割方法,将世界分成 3 个时区。)我们通过训练代理模仿现有方法来测试不同的超参数。我们将在本系列的第 4 部分对此进行更详细的讨论。
强化学习训练循环
每天,我们都会运行一个批处理培训工作流来更新我们的代理,并生成发送下一个推送通知的时间。该工作流收集以下培训数据:
- 两天前用户的状态
- 2 天前的操作(发送通知的时间)
- 用户的下一个状态(1 天前)
- 1 天前的用户参与度值(奖励)
对每个用户来说,这被组合成一个轨迹
(状态、动作、下一状态、奖励)
这组轨迹用于更新现有的 RL 代理。更新意味着在 Tensorflow 上运行深度学习工作流:代表智能体的神经网络的值被更新,以更好地反映状态、行动和长期奖励之间的关系。
RL 代理的一个好处是,他们暗中跟踪“长期回报”。请注意,我们只告诉代理第二天的即时奖励。我们不需要等一个星期再告诉 it 关于 7 天保留期的信息。RL 算法基于即时奖励和下一个状态,建立它们自己的长期奖励的内部估计。
这是一个离线、批量 RL 问题的例子。它是离线的,因为我们从离线数据(而不是与环境的即时交互)中训练代理。)之所以是批量,是因为我们在批量输入数据。这种设置不同于论文和研究中讨论的大多数 RL 问题。在大多数学术问题中,代理人在模拟环境中接受在线训练,并立即做出反应。然而,离线问题在现实世界中更为典型,因为奖励往往从行动发生时就开始延迟。
结果
经过几天的数据收集和训练,代理将点击率提高了 10%左右(相对而言)。这第一次成功展示了使用一个相当简单的解决方案强化学习的力量。它通过算法测试不同的策略,以个性化每个用户的价值,并学习如何优化关键指标,如长期保留和参与。
代理能够回答这个问题:我应该在什么时候给每个用户发消息,以便提高参与度。它不知疲倦地工作,探索新的策略,寻找新的模式。如果游戏或用户模式改变,它也能适应。在这种情况下,强化学习框架为我们提供了一种通过最小的调整和无手动过程来优化关键指标的方法。这使得它成为个性化应用程序的完美方法。
这第一次的成功让我们将这个解决方案部署到 Friends Instant 的所有玩家群中。它现在每天为几百万玩家投入生产。
下一步是什么
培训 RL 代理并将其部署到生产环境中会带来一些挑战。它需要设置定制的机器学习基础设施,能够在需要时维护和提供建议。本系列的下一篇文章将讨论这些挑战。
使用 Python 进行深度强化学习|第 2 部分|使用深度 Q 网络创建和训练 RL 代理(DQN)
在第一部分 , 我们一行一行的讲解了游戏环境的制作。在这一部分,我们将学习如何创建和训练深度 Q 网络(DQN ),并使代理能够使用它,以便成为我们游戏中的专家。
[## 使用 Python 进行深度强化学习|第 1 部分|创建环境
设计和建立一个游戏环境,允许 RL 代理在上面训练和玩。
towardsdatascience.com](/reinforcement-learning-with-python-part-1-creating-the-environment-dad6e0237d2d)
在这一部分,我们将讨论:
1-为什么是深 Q 网(DQN)?
2-什么是 DQN?
3-DQN 是如何工作的?
4-解释我们的 DQN 建筑。
5-解释代理类。
6-培训代理。
有人可能会问“你为什么不用 Q-Learning 而不用 DQN?”这个问题的答案取决于许多因素,例如:
环境有多复杂?
在我们的例子中,我们可以用两种方式回答这个问题:
- 如果我们希望 RL 代理的输入与人类的输入一样接近,我们将选择输入作为字段的数组表示。
RL 代理所看到的与人类玩家所看到的
在这种情况下,当我们使用 Q-Learning 时,环境会很复杂,而且由于 Q-Table 非常大,所以不可能存储它。为了证明这一点,考虑以下计算:
输入数组的状态数= (数组中每一项可以取的不同值的个数)^(宽度*高度)
输入数组可以具有的状态数= 4 ^ 10 * 20
= 4 ^ 200 = 2.58225e120
Q-表格大小 =动作空间大小*输入数组可以具有的状态数
Q-表格尺寸= 5 * 2.58225 e120 = 1.291125 e121
要存储这个数量的数组(每项 8 位),我们需要 9.39417077e109 太字节。
这就是为什么我们简单地使用 DQN 而不是 Q-Learning。
- 另一方面,如果你想使用 Q-Learning,使用另一种输入会更有效。例如,您可以使用球员和球洞的 X 坐标、球员的宽度和球洞的宽度。这种方式的输入比使用数组表示简单得多。
什么是 DQN?
它只是一个普通的神经网络,唯一的区别是它的输入是环境的状态,它的输出是为了最大化当前步骤的回报而执行的最佳动作。
我们通过使用**经验重放和重放记忆来做到这一点,**这些概念将在下一节解释。
深度 Q 网(DQN)如何运作?
要完全理解 DQN 是如何工作的,你需要知道一些与 DQN 相关的概念:
1-体验回放和回放记忆:
类似于人类通过使用他们以前经验的记忆来学习的方式,dqn 也使用这种技术。
经验回放:代理执行每一步后收集的一些数据,这个经验回放包含【当前状态,当前动作,步骤回报,下一个状态】。
**重放存储器:**是一堆n经验重放,重放存储器主要用于通过获得重放的随机样本来训练 DQN,并使用这些重放作为 DQN 的输入。
为什么使用随机重放样本而不是顺序重放?
- 当使用顺序重放时,DQN 倾向于过度拟合而不是一般化。
使用重放记忆的一个关键原因是打破连续样本之间的相关性。
2-模型和目标模型:
为了获得一致的结果,我们将训练两个模型,第一个模型**【模型】将在代理做出每一步后拟合,另一方面,第二个模型【目标 _ 模型】每 n 步加载【模型】**的权重(n = UPDATE_TARGET_EVERY)。
我们这样做是因为从一开始,一切都是随机的,从**“模型”的初始权重到代理执行的动作。这种随机性使得模型**更难执行好的动作,但是当我们有另一个模型每 n 步使用第一个模型获得的知识时,我们就有了某种程度的一致性。
在我们解释了一些关键概念知道我们可以总结学习的过程后,我将使用来自这篇精彩博客的 DeepLizard 的话:
解释我们的 DQN 建筑:
对于我们的 DQN,尝试了许多架构,其中许多都不工作,但最终有一个架构被证明工作良好。
失败的尝试次数:
- 最初的失败之一是具有两个输出层的架构,第一个输出层负责预测最佳移动(向左、向右或不移动),而另一个输出层负责预测最佳宽度改变动作(增加宽度、减小宽度、不改变宽度)。
- 另一个失败包括太深的网络,除了他们缓慢的训练过程,他们的表现太差。
寻找更好的架构:
在一些失败之后,进行了网格搜索,以找到能够胜过玩游戏的人的架构,下表显示了一些网格搜索的结果:
注意:下面的表格是为了最后显示最佳结果而排列的。
从第一次网格搜索的结果,我们可以清楚地看到,复杂和深度网络未能学会如何玩游戏,另一方面,最简单的网络工作得最好。
使用第一次网格搜索的结果,执行了另一次网格搜索,得到了一些好的结果:
从这个结果我们可以看出, 最好的只有并不能提高模型的性能,另一方面,同时使用 ECC(ε条件约束)和 EF(ε波动)可以提高模型的性能。
我们将在另一篇博客中讨论 ECC 和 EF。
其他一些网格搜索结果:
-
测试 【仅最佳】:
-
测试更简单的网络:
在所有这些网格搜索之后,我们最终决定使用一种架构,其中一个卷积层有 32 个滤波器,批量大小为 128,两个密集(全连接)层各有 32 个节点,我们将同时使用 ECC 和 EF。
网络摘要:
*Model: "model_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 20, 10, 1) 0
_________________________________________________________________
conv2d_1 (Conv2D) (None, 18, 8, 32) 320
_________________________________________________________________
dropout_1 (Dropout) (None, 18, 8, 32) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 4608) 0
_________________________________________________________________
dense_1 (Dense) (None, 32) 147488
_________________________________________________________________
dense_2 (Dense) (None, 32) 1056
_________________________________________________________________
output (Dense) (None, 5) 165
=================================================================
Total params: 149,029
Trainable params: 149,029
Non-trainable params: 0
_________________________________________________________________*
- ***输入层:*输入形状与代表游戏场地的数组形状相同 (20 乘 10)。
- ***卷积层:一个 Conv2D 层,有 32 个滤波器,大小为 22
- 辍学率为 20%
- 展平:将 2D 卷积层的输出转换成 1D 数组。
- 密集(全连接)层:两个密集层各有 32 个节点。
- **输出层:输出层包含 5 个输出节点,每个节点代表一个动作【无动作,左移,右移,减宽,增宽】
讲解代理类*类:*
代理类是一个包含所有与代理相关的东西的类,比如 DQN、训练函数、重放记忆和其他东西,下面是这个类的逐行解释。
模型创建:
这两个函数用于创建给定两个列表的模型:
- conv 列表:该列表的每一项定义了卷积层的滤波器数量。
- ***密集列表:*该列表的每一项定义了密集层的节点数。
培训代理:
为了保持跟踪最佳模型并保存它以在训练后使用,使用以下函数:
接下来是一些常量:
接下来是将被训练的架构:
将使用前面的三种架构执行网格搜索,网格搜索的结果存储在数据帧中。
查看我的 Github 代码库:
* [## ModMaamari/强化-学习-使用-python
使用 Python 的强化学习。通过以下方式为 ModMaamari/强化-学习-使用-python 开发做出贡献…
github.com](https://github.com/ModMaamari/reinforcement-learning-using-python)*
概括地说,我们讨论了:
- 选择 DQN 而不是 Q-Learning 的原因。
- DQNs,简单解释一下。
- dqn 是如何工作的?
- 我们使用了什么架构,为什么?
- 代理 类,解释代码。
- 训练模型和网格搜索最佳模型的过程。
在下一部分,我们将:
- 使用 Tensorboard 分析训练结果。
- 尝试最好的模式。
资源:
本系列的其他部分:
设计和建立一个游戏环境,允许 RL 代理在上面训练和玩。
towardsdatascience.com](/reinforcement-learning-with-python-part-1-creating-the-environment-dad6e0237d2d) [## 使用 Python 进行深度强化学习|第 3 部分|使用 Tensorboard 分析训练好的模型
在前面的部分中:
towardsdatascience.com](/deep-reinforcement-learning-with-python-part-3-using-tensorboard-to-analyse-trained-models-606c214c14c7)
您可以关注我:
您可能还喜欢:
- 深度神经网络用于回归问题
- AI 生成泰勒斯威夫特的歌词
- 用 Python 介绍随机森林算法
- 带 TensorFlow APIs 的机器学习速成班汇总
- 如何用 Tensorflow 和 Keras 制作一个 CNN?
- 如何选择最好的机器学习模型?*
使用 Python 进行深度强化学习|第 3 部分|使用 Tensorboard 分析训练好的模型
在前面的部分中:
- 第一部分讲解并创建游戏环境。
设计和建立一个游戏环境,允许 RL 代理在上面训练和玩。
towardsdatascience.com](/reinforcement-learning-with-python-part-1-creating-the-environment-dad6e0237d2d)
- 第二部分讨论了训练 DQN 的过程,解释了 DQNs 并给出了选择 DQN 而不是 Q-Learning 的理由。
[## 使用 Python 的深度强化学习|第 2 部分|使用深度 Q 创建和训练 RL 代理…
在第一部分,我们经历了制作游戏环境,并逐行解释。在这一部分,我们是…
towardsdatascience.com](/deep-reinforcement-learning-with-python-part-2-creating-training-the-rl-agent-using-deep-q-d8216e59cf31)
在这一部分中:
我们将:
- 使用 Tensorboard 可视化训练好的模型。
- 解释加载和尝试已训练模型的方式。
- 用最好的模型,让它玩游戏。
使用张量板:
1-使用修改的 Tensorboard 使 Tensorboard 在一个日志文件中记录来自训练过程中所有情节的数据,而不是每次我们拟合模型时都制作新的日志文件。
下一个代码modified tensor board来自 sentdex 的这个博客,我只是稍微修改了一下,让它可以在 TensorFlow2.0 上运行:
2-在代理类的 init 中定义修改后的 tensorboard 的对象:
路径 和 名称 用于定义保存日志文件的完整路径。
3-拟合模型时,将修改后的张量板作为回调传递:
4-每集开始时:
5-要更新日志,请使用下一行:
可视化日志:
在“logs”文件夹所在的目录下打开终端,并运行:
tensorboard --logdir="logs/"
将出现一个浏览器窗口:
你可以自己尝试其他选项。
通过使用这些可视化,我们可以看到记录的变量之间的关系,例如 epsilon 和 max_reward。
加载和使用训练模型:
代理人玩游戏的一些镜头:
资源:
本系列的其他部分:
设计和建立一个游戏环境,允许 RL 代理在上面训练和玩。
towardsdatascience.com](/reinforcement-learning-with-python-part-1-creating-the-environment-dad6e0237d2d) [## 使用 Python 的深度强化学习|第 2 部分|使用深度 Q 创建和训练 RL 代理…
在第一部分,我们经历了制作游戏环境,并逐行解释。在这一部分,我们是…
towardsdatascience.com](/deep-reinforcement-learning-with-python-part-2-creating-training-the-rl-agent-using-deep-q-d8216e59cf31)
您可以关注我:
您可能还喜欢:
- 深度神经网络用于回归问题
- AI 生成泰勒斯威夫特的歌词
- 用 Python 介绍随机森林算法
- 带 TensorFlow APIs 的机器学习速成班汇总
- 如何用 Tensorflow 和 Keras 制作一个 CNN?
- 如何选择最好的机器学习模型?
深度 RL 案例研究:自动化工程
人工智能和计算机系统能接管工程的其他领域吗?
在不同的工程领域中,参数调整是一个常数。计算机科学家调整他们模型的值,电气工程师改变他们晶体管的宽度,化学工程师检查他们过程的效率。这些不同角色的不变方面:人类在高维、非凸优化问题上是不可靠的。在所有这些情况下,我们的大脑就是优化功能——设计工程师还可以使用哪些优化器,为什么要使用?最近发现的这些工程角色之间的差异:只有计算问题被结构化和规范化到足以让学习戏剧性地改变它们。
自动参数调整— AutoML:
AutoML,即自动机器学习,正在流行起来。当我在脸书的时候,我正在测试 PyTorch 的预发布版本,Berkeley 的同事刚刚发布了他们自己的开源包 Tune (for Ray) 。
介绍 Ray Tune,这是最先进的超参数调节库,可供研究人员和开发人员在任何…
medium.com](https://medium.com/riselab/cutting-edge-hyperparameter-tuning-with-ray-tune-be6c0447afdf)
AutoML 是做什么的?简而言之,它…
- 加载设计变量和目标的向量,
- 将模型拟合到目标函数,
- 返回当前数据集中的最佳参数。
现在,我们可以了解这意味着什么。
设计变量和设置
每个设计问题都有一组要优化的变量,变量的数量决定了要使用的优化器的类型。由于难以限制优化器可访问的变量,自动化设计的采用受到限制。工程师运用多层次的知识来理解系统是如何工作的。他们利用这些知识来调整许多方面,并汇聚成一个解决方案——通常在不受约束的环境中工作。现代机器学习在结构化问题中工作得非常好,所以在实际问题中启用 AutoML 的很大一部分是有效的数据科学。设计师必须将系统最重要的方面提取到变量的子集里(有人知道主成分分析吗?)被标准化并准备好供计算机拟合和迭代。
这些原则只有在工具设置好之后才能应用,也就是说,学习算法可以直接改变感兴趣的变量并运行新的模拟。自动化设计的影响力取决于它改变和测试新参数的能力。工具的障碍是这些问题的解决方案变得非常小众的原因— 需要对参数优化和设计工具有博士水平的理解才能在硬件中部署它们。
为目标建模
贝叶斯优化是 AutoML 优化器中使用最频繁的工具(可以使用任何非梯度依赖优化器:备选包括 遗传算法 或 交叉熵方法 )。
在贝叶斯优化循环(算法)中迭代高斯过程(模型)的拟合。黑点代表数据,这显示了 2 到 4 个数据点。目标函数通过测量拟合表面,并预测状态空间剩余部分的平均值和方差。绿色(激活功能)用于选择下一组参数,参见下面的优化选择部分。(来源— 将人类从循环中解放出来……)
目标的模型就是所捕获的正在设计的系统的行为。这是至关重要的一步,它使计算机成为一种更加结构化的选择形式。计算机可以用平滑高斯过程、深度神经网络或概率分布的组合来模拟复杂的非线性函数。
这些不同的模型选项在表达性、可解释性和样本效率之间进行权衡。高斯过程(最终是非参数高斯分布)是一个很好的选择,因为它们在样本效率方面占优势,同时带有可解释的不确定性概念。
最佳选择
这是计算机比人类获益最多的地方。
人类擅长将一种设计与另一种设计进行比较(也许是不可思议的强烈直觉),但我们缺乏任何真正的能力来提出给定数据集的最佳或接近最佳的下一组参数。使用结构化学习模型为算法提供了一种明确的方式来决定下一个参数集。
在贝叶斯优化中,传递下一组参数的工具被称为采集函数。获取功能是另一个可供人类选择的设计选项。其他方法(CMA、CEM 等)可以将他们的预测建模为样本分布,取这种分布的平均值就是当前的最优估计。采集函数的不同选择在参数探索、模型开发和先验知识之间进行平衡。关键是优化器消除了困扰人类调优* 的选择歧义。*
编辑描述
dash.harvard.edu](https://dash.harvard.edu/handle/1/27769882)
如果你正在为你的项目寻找一个 AutoML 工具——看看这个来自弗赖堡的研究小组。*
我们认为优化一组参数——人类在 中调十几个变量 还是人类选择几个 算法棋子 哪个更好?让我们看看在研究中选择适合当前特定设计问题的优化器和模型的可能性。
来源——我的大阪之旅。
自动化设计的前沿
我概述了去年给我留下深刻印象的自动化工程的两个最近的例子。(我正试图从这些研究中获得灵感,在我自己的研究中优化机器人设计,这有望导致这篇博文的第二个版本。)
电路设计
Kourosh Hakhamaneshi 等人。al 将进化算法(优化选择)和深度神经网络鉴别器(目标函数模型)应用于高维电路设计问题(设计空间)。
电路设计涉及许多方面,但在高层次上,设计一个片上系统的一个组件归结为四个步骤:1)改变原理图(使用的组件,例如晶体管、电阻),2) 模拟原理图,直到它是准确的,3) 布局原理图,以便它可以在电路代工厂(TSMC,英特尔)创建,4) 模拟电路布局。最耗时的环节是最后一步,模拟可能需要几天时间。原理图-模拟-布局-模拟是一个非常宽的循环,其中简单的迭代不会产生任何功能性结果。
(来源— BAIR 在 BagNet 上的博客文章)
如果一种算法不能减少模拟(和验证)电路如何制造所需的时间,那么它知道在哪里放置带电阻的晶体管只是难题的一小部分。有一个核心技术方面使本文能够实现功能性结果(过去其他项目失败的地方):使用深度学习鉴别器来判断哪些新设计应该在布局后仿真中进行评估。
电路设计的复杂性是作者以这种方式设置问题的原因。他们需要使用进化算法,因为它可以快速地提出更多的样本,并获得关于参数是否应该工作的初始指示(给定历史人口数据),然后鉴别器充当过滤器,以大幅减少计算负担。
这种方法的主要优势是 它能够在模拟电路设计 的各种约束条件下工作。这篇论文的作者代表了离线优化和电路设计领域的知识高峰——在专门问题上实现新颖优化所需的罕见组合,因此希望 BagNet 取得成功。
在这篇文章中,我们分享了一些关于深度学习在模拟 IC 设计中的应用的最新成果…
bair.berkeley.edu](https://bair.berkeley.edu/blog/2019/09/26/circuits/)
机器人设计
这里托马斯·廖等人。al 将贝叶斯优化(优化选择)和高斯过程(目标函数模型)应用于微机电系统优化(设计空间)。
在任何硬件设计问题中,设计的评估通常会因几周的制造时间而延迟。这在微机电系统(MEMs)中尤其如此**、,其中有两个阶段用于延迟和变化:掩模组装(工具设置)和纳米制造(实际构造)。该方法通过启用参数空间的并行搜索来增加设计优化的吞吐量。本文使用贝叶斯优化循环的升级版本。**
(来源—MEMs 论文中的形态学学习)
伟大的洞察力是用一个新的获取函数修改贝叶斯优化,该函数返回一组参数向量以在下一次评估中尝试。然后,该模型可以立即适应所有这些试验,并提出另一批试验。这就是所谓的分层过程约束批量贝叶斯优化(HPC-BBO) 。该模型可以拟合来自问题的任何数据,因此并行评估是挂钟时间的实质性改进(使用新的采集功能可能会稍微降低采样效率)。
实现这一点的两个关键技术细节是 1) 用模型想象真实过程的回报(标准贝叶斯优化需要在获得另一个样本之前评估真实系统上的参数),首先在批量贝叶斯优化中提出,以及 2) 关于第二个约束的批量建议参数的上下文优化——需要设计与特定控制器一起工作,这成为一个联合学习问题。
这种学习协议强调了 AutoML 在结构问题上的工作能力,这些问题过去是专门留给人类设计师的。结构和并行化使其在实际硬件中循环时非常高效。
[## 微机器人形态学和控制器的高效数据学习
机器人设计通常是一个缓慢而困难的过程,需要反复构建和测试原型,并且…
arxiv.org](https://arxiv.org/abs/1905.01334)
来自我实验室的真实(外部)和想象的微型机器人。(来源相关学术 论文来自我的小组)*
这种方法在很多方面都站不住脚——设计变量太多,无法访问特定机构使用的专有设计工具之外的数据,缺乏老一辈工程师的教育。也就是说,一些年轻的专家在他们的领域所付出的努力会产生巨大的回报。
深度 RL 案例研究:基于模型的规划
模型学习为强化学习领域提供了结构和可解释性。
什么是基于模型的强化学习,什么是对其未来的乐观,DeepMind 在最近的一篇论文中说它的代理可以通过“做梦”从零开始学习计划是什么意思。基于模型的学习可能是样本最优的——如果我们能够恰当地捕捉环境的动态,那么代理可以精确地计划来完成我们想要的任何任务(其中无模型学习专注于单个任务)。DeepMind 最近的 MuZero 算法向世界表明,由于其规划能力,MBRL 将继续存在。
快速历史拍摄
许多决策算法一直使用环境模型来解决问题。一些经典的例子包括搜索方法,如 A-Star 或树搜索。这些计划顺序动作的方法的问题是它们缺乏在连续环境中的能力。当您试图创建一个包含无限个候选动作的动作选择树时,会发生什么?这个缩放问题是深度强化学习中基于模型的规划试图通过将动作选择转换为易处理的优化问题来覆盖的众多问题之一——给我们一个动作而不是一个样本空间。
基于模型的强化学习回顾
MBRL 的方块图。来源,我在 IROS 2019 的演讲。
基于模型的强化学习(MBRL)遵循代理在其环境中行动的方法,学习所述环境的模型,然后利用该模型来行动。它通常以参数化的动态模型为特征,通知某种控制器。该回路在图中用 Clank 表示。在 MBRL,通常控制问题在它本身和动态模型的学习之间缺少一个链接,这引入了一些最优性的损失。本文将关注如何使用某种动力学模型来计划一系列的动作。我首先回顾了一些过去的方法,并借鉴了 DeepMind 最近的工作,该工作正在准备使用基于模型的规划来解决 RL 中令人兴奋的前沿问题。
我年轻的非专业摄影还在继续。降落在哥斯达黎加的坦博尔。
使用概率动力学模型的少量试验中的深度强化学习
MBRL 和规划一直在大幅上升,特别是自从蔡氏等人在 2018 年神经信息处理会议上的一篇同事论文:“使用概率动力学模型的少数试验中的深度强化学习”(spot light paper ~ 4%的被接受论文)。艾尔。它描述了如何将动力学模型塑造成一个有用的控制器,这是 MBRL 第一次因为渐近最优(与软 actor-critic 和其他无模型算法相比)和样本效率更高而受到关注。
PETS 中使用的三个模块是深度动力学模型、轨迹传播器(不是真正的规划器)和基于采样的控制(来源)。
何时信任您的模型:基于模型的策略优化
另一篇直接导致 DeepMind 最近工作的论文(我认为是 MBRL 领域相当有开创性的)是 Janner 等人的论文“何时信任你的模型:基于模型的策略优化”,该论文对 MBRL 的早期工作进行了两项根本性的改变:1)他们成功地表明基于模型的算法可以使用标准的上下文策略(当状态传入时返回动作的网络)作为控制器,2) MBRL 可以使用动态模型的离线模拟来改进控制策略的当前迭代。
这种算法的工作原理是创建一个动态模型,然后在模拟中对动态模型运行非常短的软 actor-critic 部署,这在很少的环境交互中生成可靠的策略,创造了基于模型的策略优化(MBPO)。
在模型上进行模拟时,对未来的不确定性估计迅速增加(来源)。
从头开始学习基于模型的规划
Pascanu、李和 DeepMind 团队的这篇较老的论文“从零开始学习基于模型的规划”试图解决这样的批评:“虽然模型可以用来评估一个计划,但它并没有规定如何构建一个计划。”以经典的 DeepMind 方式——他们改进并整合了最近研究的许多方面到一个令人印象深刻的系统中。他们正在接受 MBRL 挑战,并为动力学模型的离线模拟创造了术语“想象力”(非常类似于两年后问世的 MBPO)。这种情况下的关键区别是,在这种新的基于想象的计划方法(IBP)中,他们还学习何时想象**,并以巧妙的方式使用真实和模拟体验中的上下文。**
对 IBP 的想象框架。
类似于 MBPO,这项最新的工作使用情境化的策略进行控制。扩展在于,IBP 不是仅仅使用过去的状态来决定下一步行动,而是有自己的方法来生成上下文。作者使用长短期记忆(LSTM)模块从最近的模拟和真实经历中学习上下文,这提高了控制任务的性能。本文评估了向前一步、向前 n 步和全树探索的性能。全树探索允许管理者通过不同深度的不同动作来探索想象,通过最大计算成本来限制探索的深度和广度。 MBPO 在这个设置上做了改进,在想象时使用了一种无模型算法的状态,以获得令人印象深刻的性能。
学习基于树的规划允许对不同深度和宽度的真实世界和想象的行动进行评估,以及估计的回报(来源)。
作者提出,这种想象框架也可以很好地进行概括。我认为这与元学习有关,在这种情况下,管理者——处理何时行动与何时计划——可以处理任务抽象,并学习学习不同的任务(在现实和模拟中)。经理目前是一个离散的行动,奖励很少,所以学习起来一定很难——他们目前在这里使用强化算法。
这篇论文是 DeepMind 刚刚发布的一些工作的前身,他们将规划集成到他们的巨型机器学习系统中,以解决具有巨大行动空间和高天花板的游戏。
高潮:穆泽罗
Schrittwieser 等人的模型“通过计划掌握雅达利、围棋、国际象棋和日本象棋。al 是基于模型的 RL 的一个重要时刻。显示 MBRL 可以直接从像素(建立模型的常见斗争点)解决雅达利游戏作为一种新的艺术状态,将进一步推动 MBRL 在顶级强化学习会议中的指数级上升(几年前不到 1%,很快达到 RL 论文的 10%左右)。
用一个已学过的模型来计划、表演和训练。a)动态模型返回一个估计的奖励和状态,它可以被转换成一个未来值,B) MuZero 根据上下文策略(类似于之前)在每个时间步使用蒙特卡罗树搜索进行操作,C) MuZero 通过验证来自重放缓冲器的轨迹并通过在真实轨迹的每一步将它们想象成一个模拟的未来来训练(来源)。
MuZero 算法将来自 MBRL 的许多块构建到一个系统中,该系统显示了无模型算法的有效性。算法需要从像素而不是物理状态观察中运行的项目,因此 MBRL 需要聪明的编码来使它们最佳地执行。主要区别包括:
- 动态模型不是试图从真实的隐藏状态中计划行动和奖励,而是对一种内部状态进行编码,这种状态没有真实环境的语义表示。这允许反向传播直接最大化期望的度量,而对问题的形状具有较少的约束。
- 从这个隐藏的内部状态计算策略和值函数,类似于来自 AlphaZero 的联合策略和值函数(它们最近的无模型 RL 成功)。
- 与 AlphaZero 的蒙特卡罗树搜索(MCTS)不同的是,在推出潜在行动时,他们可以使用学习到的模型来引导或想象**,即未来价值估计,这变成了一种基于模型的基本规划。**
这个规划函数提高了学习算法的样本效率,因为提前规划可以达到赢得一场比赛的稀疏回报。最终,这是为什么规划有助于更快地学习的一个潜在原因——它让算法从它当前的行动中寻找回报,而不是依赖随机探索(这在 MBRL 也有帮助和贡献)。
(这篇文章中没有提到的对 MBRL 的一个限制是基于模型的 RL 的墙时间效率很差——运行一个运行中的半猎豹的模拟可能需要一周时间。我希望在未来从事这项工作——基本上所有的动力学模型训练和想象步骤都会导致算法比无模型的算法运行得慢得多。一些算法,如 MBPO,甚至有奇怪的事件顺序(在每个实时步骤进行想象),这使得它无法在真实的机器人上运行。
更多?订阅我关于机器人、人工智能和社会的时事通讯!
一个关于机器人和人工智能的博客,让它们对每个人都有益,以及即将到来的自动化浪潮…
robotic.substack.com](https://robotic.substack.com/)**
深度堆叠网络(DSN)
神经网络已经存在了一段时间,但是提供诸如特征提取等功能的能力使得它们的使用更加可行
深度堆叠网络(DSN)是一种深度架构,旨在支持大型 CPU 集群,并受益于深度神经网络的深度学习能力。深度堆叠网络架构最初是由邓梨和董宇在 2011 年提出的,通常被称为深凸网络(DCN),以强调用于学习网络的算法的深度。
深度网络模型已被证明是一种有前途的范式,它为高性能机器学习提供复杂数据,其中多个集中在神经网络上。近年来,为了使用非神经网络方法构建不同的深度架构,已经进行了更多的实验。深度堆叠网络(DSN)模型使用简单易学的模块来创建复杂的并行参数训练网络。
DSN 架构的核心理论是堆叠原理,正如最初建议的那样,首先组装基本的功能模块或分类器,然后相互堆叠,以便学习复杂的功能或分类器。
基于 SVM 的深度堆叠网络(SVM-DSN)
基于 SVM 的深度堆叠网络(SVM-DSN)使用 DSN 架构来组织用于深度学习的线性 SVM 分类器。从全局的角度来看,SVM-DSN(基于 SVM 的深层堆叠网络)可以从局部的角度,将数据表示作为深层网络逐层提取,但是是并行的。SVM 堆栈可以收敛到其理想解,并获得支持向量,与神经网络相比,这可能导致抗饱和和理解方面的令人着迷的改进。
由于其特性,SVM 和 DSN 之间的训练并行化只能达到基础水平——训练数据的定向特征和 SVM 可以为从训练数据中学习块提供支持向量。传统的 D-SNA 只能达到块级别,但是基于向量的 SVM 可以用于块学习。
SVM-DSN 模型具有一些有益的特征,例如整体和空间优化以及并行化。
自动编码器
自动编码器是一种人工神经网络,旨在无人值守的情况下学习有效的数据编码。深度学习当然不是什么新鲜事,但由于它能够对神经网络进行深度分层并加速其执行,近年来经历了爆发式增长。深度学习结构依赖于更多的数据,网络越深,基于样本数据进行训练并基于其成功进行奖励的受监控学习算法的数量就越多。
自动编码器堆叠是一种训练深度网络的方法,深度网络由多个层组成,并使用贪婪方法进行训练。深度堆叠网络使用采取多层感知器的简化形式的基本模块的堆叠。
有几种方法可以学习堆栈中的自动编码器,例如使用多个编码器。堆叠式自动编码器结构已经在深度神经网络的模型中使用了许多年,例如在深度学习的神经网络中。
虽然构建这些类型的深层架构可能很复杂,但它们可以很快上手。Tensorflow 中从头构建的深度堆栈自动编码器模型。在批处理架构中,每个编码层都有自己的层,它应该是一个完整的自动编码器,并且这些层都是堆叠的。由自动编码器生成的函数可以被馈送到网络的其他层,例如代码和数据层。
DSN 的优势
神经网络已经存在了一段时间,但提供特征提取等功能的能力使其使用更加可行。GPU 能够从深度学习中受益,因为它可以更容易地训练和运行原始处理器效率不高的深度网络。这一优势使得 SVM 和 DSN 能够避免深度神经网络中的神经元饱和问题,从而提高性能。
引用来源
- http://big road . fadyghalidesign . com/6 zax 6h/stacked-auto encoder . html
- https://developer . IBM . com/technologies/artificial-intelligence/articles/cc-machine-learning-deep-learning-architectures/
- https://www . fotosmitk . de/0 rqzxf/image-noiseing-and-super-resolution-using-residual-learning-of-deep-convolutionary-network . html
- https://www . researchgate . net/figure/A-Deep-Stacking-Network-Architecture _ fig 1 _ 272885058
- https://deepai . org/publication/SVM-based-deep-stacking-networks
- https://arxiv.org/abs/1902.05731
用于图像分类的深度迁移学习
从数据导入到精度评估的分步指南
以下教程介绍了如何为图像分类建立先进的深度学习模型。该方法基于机器学习框架“Tensorflow”和“Keras”,并包括复制本教程中的结果所需的所有代码(不幸的是,在中型文章中包含代码块时的语法看起来不太好,但它应该是可读的)。
建立模型的先决条件是访问标记数据,作为一个例子,我使用了各种交通标志的图像(可以在这里下载)。因此,该模型的任务是预测它看到的是哪种交通标志。为了使示例更真实,我将数据量减少到每个类最多 200 张图像(因为在机器学习的实际应用中,数据量通常是有限的)。
这些图片当然只是作为一个例子,让你开始。只要遵循与当前设置相同的文件夹结构,就可以很容易地用您自己的图像替换它们,如下所述。
用您自己的数据替换图像:
将您的图像放在主文件夹“data/”下的子文件夹中,将图像类别的名称作为子文件夹名称,如下所示的示例文件夹结构。首先,您需要将图像分成训练、验证和测试数据。“training_data”文件夹中的图像是用于训练模型的实际图像,而“validation_data”文件夹中的图像用于优化训练和模型超参数。然后,测试数据被用作最终评估,在一组完全独立的图像上评估模型的准确性。
包含数据集的文件夹结构示例:
培训数据:
- 数据/列车/类别 1:类别 1 中的标志图像
- 数据/列车/类别 2:来自类别 2 的标志图像
- ……………………………………
验证数据:
- data/val/category_1:来自类别 1 的标志图像
- data/val/category_2:第 2 类标志的图像
- ……………………………………
测试数据:
- 数据/试验/类别 1:类别 1 中的标志图像
- 数据/测试/类别 2:类别 2 中的标志图像
- ……………………………………
在“训练”、“验证”和“测试”之间分割图像的一种方式是,例如,使用 80%的图像来训练模型,并且分别对 10%的图像进行验证/测试。关于分离“训练”、“验证”和“测试”数据的重要性的简要介绍,你也可以阅读这里的
定义和运行模型所需的库和包:
这些是一些有用的 python 库/包,它们使我们的生活变得更加容易,因为我们不必从头开始编写所有的代码和功能。如果没有这些库/包,构建深度学习模型实际上将是一项非常艰巨的任务!
**import** **numpy** **as** **np**
**import** **os**
**import** **matplotlib.pyplot** **as** **plt**
**import** **seaborn** **as** **sns**
**from** **numpy.random** **import** seed
seed(1337)
**from** **tensorflow** **import** set_random_seed
set_random_seed(42)
**from** **tensorflow.python.keras.applications** **import** vgg16
**from** **tensorflow.python.keras.applications.vgg16** **import** preprocess_input
**from** **tensorflow.python.keras.preprocessing.image** **import** ImageDataGenerator, load_img
**from** **tensorflow.python.keras.callbacks** **import** ModelCheckpoint
**from** **tensorflow.python.keras** **import** layers, models, Model, optimizers
**from** **sklearn.metrics** **import** classification_report, confusion_matrix, accuracy_score
**from** **plot_conf_matr** **import** plot_confusion_matrix
定义训练/测试数据和不同的类别:
在这里,我们定义了 train/val/test 图像的位置以及我们想要分类的所有不同类别的名称。然后,我们绘制训练集中每个类别的图像数量。
train_data_dir = "data/train"
val_data_dir = "data/val"
test_data_dir = "data/test"category_names = sorted(os.listdir('data/train'))
nb_categories = len(category_names)
img_pr_cat = []**for** category **in** category_names:
folder = 'data/train' + '/' + category
img_pr_cat.append(len(os.listdir(folder)))sns.barplot(y=category_names, x=img_pr_cat).set_title("Number of training images per category:")
每节课的训练图像数量概述
让我们也从各种标志类别中绘制一些示例图像,以直观显示典型的图像质量:
**for** subdir, dirs, files **in** os.walk('data/train'):
**for** file **in** files:
img_file = subdir + '/' + file
image = load_img(img_file)
plt.figure()
plt.title(subdir)
plt.imshow(image)
**break**
一些示例图像
正如你从上面的例子中看到的,分辨率和质量都不是很好。然而,在机器学习的实际应用中,图像质量和数据量往往非常有限。因此,与使用成千上万的“完美的”高质量图像相比,限制为每类最多 200 个训练图像的低质量图像代表了更真实的例子。
迁移学习:
现阶段不需要了解各种类型的深度学习模型的所有细节,但是可以在这里找到一些常用的建模方式的总结,供感兴趣的人参考。
在本教程中,我们使用预训练的深度学习模型(VGG16)作为我们图像分类器模型的基础,然后根据我们自己的数据重新训练该模型,即迁移学习
img_height, img_width = 224,224
conv_base = vgg16.VGG16(weights='imagenet', include_top=**False**, pooling='max', input_shape = (img_width, img_height, 3))
您可能会注意到上面的参数“pooling= 'max '”。原因是,我们不是将 VGG16 模型的卷积基础连接到最终输出层之前的几个完全连接的层(这是在原始 VGG16 模型中完成的),而是使用最大池输出(也可以使用“平均池”,因为这取决于哪种方法效果最好的用例)。这种方法是使用完全连接的图层从要素地图过渡到模型输出预测的替代方法。根据我的经验,这种方法通常非常有效,并且使模型不容易过度拟合,正如这篇论文中所描述的:
传统的卷积神经网络在网络的较低层执行卷积。对于分类,最后一个卷积层的特征图被矢量化,并馈入完全连接的层,随后是 softmax 逻辑回归层。这种结构将卷积结构与传统的神经网络分类器联系起来。它将卷积层视为特征提取器,生成的特征以传统方式进行分类。
然而,完全连接的层容易过度拟合,从而阻碍了整个网络的泛化能力。在本文中,我们提出了另一种称为全局平均池的策略来取代 CNN 中传统的全连接层。我们没有在特征地图上添加完全连接的层,而是取每个特征地图的平均值,并将结果向量直接输入 softmax 层。与完全连接的图层相比,全局平均池的一个优势是,它通过加强要素地图和类别之间的对应关系,更适合卷积结构。因此,特征图可以很容易地解释为类别置信度图。另一个优点是在全局平均池中没有要优化的参数,因此在这一层避免了过拟合。此外,全局平均池汇总了空间信息,因此对输入的空间平移更具鲁棒性。我们可以把全局平均池看作一个结构正则化器,它明确地强制特征图成为概念(类别)的置信度图。
加载了预训练的 VGG16 模型后,我们还可以选择在下面的代码块中冻结模型的“更深的层”,只在我们自己的数据上重新训练最后几层。这是一种常见的迁移学习策略,当可用于训练的数据量有限时,这通常是一种很好的方法。
迁移学习
这个选项目前在代码中被注释掉了(使用#符号),因此我们正在重新训练模型的所有层。训练的层数代表了一个你可以自己试验的参数。可训练层数如何影响模型性能?
*#for layer in conv_base.layers[:-13]:*
*# layer.trainable = False*
作为检查,我们还可以打印模型所有层的列表,以及它们是否可训练(对/错)
**for** layer **in** conv_base.layers:
print(layer, layer.trainable)
使用 VGG16 模型作为基础,我们现在在上面构建最终的分类层来预测我们定义的类。然后,我们打印模型摘要,列出模型的参数数量。如果你决定“冻结”一些层,你会注意到下面的“可训练参数”的数量将会减少。
model = models.Sequential()
model.add(conv_base)
model.add(layers.Dense(nb_categories, activation='softmax'))
model.summary()
正如您所看到的,模型最后一层的输出形状对应于类的数量,在我们的例子中是 10。
用于读取和处理图像的发生器:
然后,我们需要定义一些函数,从我们的文件夹中读取图像,并将它们提供给图像分类器模型。作为其中的一部分,我们还添加了一些基本的图像预处理,其中输入图像被缩放为具有范围[0,1]内的像素值(在原始图像中为 0–255)。
*#Number of images to load at each iteration*
batch_size = 32*# only rescaling*
train_datagen = ImageDataGenerator(
rescale=1./255
)
test_datagen = ImageDataGenerator(
rescale=1./255
)*# these are generators for train/test data that will read pictures #found in the defined subfolders of 'data/'*print('Total number of images for "training":')
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size = (img_height, img_width),
batch_size = batch_size,
class_mode = "categorical")print('Total number of images for "validation":')
val_generator = test_datagen.flow_from_directory(
val_data_dir,
target_size = (img_height, img_width),
batch_size = batch_size,
class_mode = "categorical",
shuffle=**False**)print('Total number of images for "testing":')
test_generator = test_datagen.flow_from_directory(
test_data_dir,
target_size = (img_height, img_width),
batch_size = batch_size,
class_mode = "categorical",
shuffle=**False**)
运行上述代码块的输出
定义模型参数并开始训练:
这里,我们定义一些控制模型训练过程的参数。重要的参数是例如训练率、多少个时期来训练模型以及使用哪个优化器。你不需要理解所有这些术语来跟随教程,但是感兴趣的人可以在这里快速阅读。
我们还定义了一个检查点参数,在训练期间,我们在每个时期之后跟踪验证的准确性。利用这一点,我们总是保留在训练过程中表现最好的模型的副本。
learning_rate = 5e-5
epochs = 10checkpoint = ModelCheckpoint("sign_classifier.h5", monitor = 'val_acc', verbose=1, save_best_only=**True**, save_weights_only=**False**, mode='auto', period=1)
model.compile(loss="categorical_crossentropy", optimizer=optimizers.Adam(lr=learning_rate, clipnorm = 1.), metrics = ['acc'])
我们现在准备好开始根据我们自己的数据训练模型,对于每个“时期”,我们打印训练和验证损失和准确性。在训练数据上测量的模型精度由“acc”给出,在验证集中的图像上的精度由“val_acc”给出。这是最重要的量,因为它告诉我们模型在训练过程中尚未看到的图像上有多精确。
理想情况下,“val_acc”应该随着我们不断训练模型而针对每个时期增加,并且当我们的模型不能从我们的训练数据中学习到任何更有用的信息时,最终达到稳定的值。
history = model.fit_generator(train_generator,
epochs=epochs,
shuffle=**True**,
validation_data=val_generator,
callbacks=[checkpoint]
)
培训期间的输出
从上面显示的输出中,我们可以看到,在训练过程中,损耗减少了,而精度增加了。每次验证精度达到新的最大值时,都会保存检查点文件(输出:“将模型保存到 sign_classifier.h5”。训练完成后,我们加载在训练期间具有最佳验证准确性的检查点文件:
model = models.load_model("sign_classifier.h5")
评估模型准确性:
我们首先将模型精度的变化和训练过程中的损失可视化,因为这为我们提供了重要的信息来评估我们可以做些什么来提高精度。想要更好地了解这个话题,你也可以看看这个视频:
绘制和保存学习曲线的代码:
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']epochs = range(1,len(acc)+1)plt.figure()
plt.plot(epochs, acc, 'b', label = 'Training accuracy')
plt.plot(epochs, val_acc, 'r', label='Validation accuracy')
plt.title('Training and validation accuracy')
plt.legend()
*plt.savefig('Accuracy.jpg')*plt.figure()
plt.plot(epochs, loss, 'b', label = 'Training loss')
plt.plot(epochs, val_loss, 'r', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()
*plt.savefig('Loss.jpg')*
从左图开始,显示了训练/验证准确性:蓝线表示在训练图像上测量的模型准确性,我们看到这很快达到几乎为 1 的值(这表示对 100%的训练图像进行了正确分类)。然而,验证准确性是在验证集上测量的准确性,这是我们真正关心的准确性。在这种情况下,准确率稳定在 97–98%左右,这意味着我们成功地将验证集中的几乎所有图像分类到正确的类别。
为了了解不同类别的准确性,我们可以计算并绘制“混淆矩阵”。这代表了评估模型准确性的说明性方式,因为它比较了测试集中所有图像的“真实”与“预测”类别。注意:如果重新运行代码时没有得到完全相同的数字,也不用担心!在模型初始化等方面存在一些固有的随机性。这使得结果有时略有不同。
(计算和绘制混淆矩阵的代码包含在图的下方)
Y_pred = model.predict_generator(test_generator)
y_pred = np.argmax(Y_pred, axis=1)
cm = confusion_matrix(test_generator.classes, y_pred)
plot_confusion_matrix(cm, classes = category_names, title='Confusion Matrix', normalize=**False**, figname = 'Confusion_matrix_concrete.jpg')
是脚本“plot_conf.py”中的代码,其中包含绘制混淆矩阵的函数“plot _ conf _ matrix”。
import numpy as np
import matplotlib.pyplot as pltdef plot_confusion_matrix(cm, classes, figname,
normalize=False,
title=’Confusion matrix’,
cmap=plt.cm.Blues):
“””
This function prints and plots the confusion matrix.
Normalization can be applied by setting `normalize=True`.
“””
import numpy as np
import matplotlib.pyplot as plt
import itertools
if normalize:
cm = cm.astype(‘float’) / cm.sum(axis=1)[:, np.newaxis]
print(“Normalized confusion matrix”)
else:
print(‘Confusion matrix, without normalization’)plt.figure(figsize=(8,8))
plt.imshow(cm, interpolation=’nearest’, cmap=cmap)
plt.title(title)
#plt.colorbar()
tick_marks = np.arange(len(classes))
plt.xticks(tick_marks, classes, rotation=90)
plt.yticks(tick_marks, classes)fmt = ‘.2f’ if normalize else ‘d’
thresh = cm.max() / 2.
for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
plt.text(j, i, format(cm[i, j], fmt),
horizontalalignment=”center”,
color=”white” if cm[i, j] > thresh else “black”)plt.ylabel(‘True label’)
plt.xlabel(‘Predicted label’)
plt.tight_layout()
plt.savefig(figname)
从上面的混淆矩阵中可以看出,模型错误分类的主要类别是“交叉点”,在其中的 10 幅图像中,它将该类别与“产量”类别相混淆。作为最后的度量,我们还可以计算在测试集上评估的总准确性
accuracy = accuracy_score(test_generator.classes, y_pred)
print("Accuracy in test set: **%0.1f%%** " % (accuracy * 100))
这给出了 98%的输出精度,这还不错!但是,我们能做得更好吗?我们的数据量有限,那么使用图像增强来改善它怎么样?
图像增强模型:
在我们的例子中,该模型已经表现得非常好,准确率为 97–98%。然而,当处理有限数量的训练数据时,一种策略是“图像增强”。也就是说,我们收集了现有图像的副本,但是做了一些小的修改。这些变化可以是变换,例如轻微旋转、缩放、水平翻转图像、++。此处还介绍了图像增强的更多示例。
在下文中,我们定义了与之前相同的模型,但是这里我们也将图像增强作为一种人工增加训练数据量的方式。
使用与之前相同的卷积基础和模型结构,编写代码来构建新模型:
conv_base = vgg16.VGG16(weights='imagenet', include_top=**False**, pooling='max', input_shape = (img_width, img_height, 3))
*#for layer in conv_base.layers[:-13]:*
*# layer.trainable = False*model = models.Sequential()
model.add(conv_base)
model.add(layers.Dense(nb_categories, activation='softmax'))
增强功能:
我们代码中唯一需要更改的是下面显示的训练数据生成器的定义。我们可以在这里添加一些数据增加策略,例如[-10,10]度范围内的随机旋转,范围±10%内的随机缩放和宽度/高度移动,以及范围±10%内的亮度变化。
作为增强图像的示例,我们可以将它们保存到指定的文件夹“augm_images ”,如下面的功能“train_generator”中所定义的。此选项目前已被注释掉(以避免保存数千幅图像),但如果您想要可视化您合并的增强,您可以更改此选项。这通常是一个好主意,只是为了确保增强的图像对于您正在处理的用例仍然有意义。
train_datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=10,
zoom_range=0.1,
width_shift_range=0.1,
height_shift_range=0.1,
horizontal_flip=**False**,
brightness_range = (0.9,1.1),
fill_mode='nearest'
)
*# this is a generator that will read pictures found in*
*# subfolers of 'data/train', and indefinitely generate*
*# batches of augmented image data*
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size = (img_height, img_width),
batch_size = batch_size,
*#save_to_dir='augm_images',*
save_prefix='aug',
save_format='jpg',
class_mode = "categorical")
使用扩充数据训练新模型
我们现在准备使用额外的增强数据来训练相同的模型,这应该有望提高模型的准确性。
learning_rate = 5e-5
epochs = 20
checkpoint = ModelCheckpoint("sign_classifier_augm.h5", monitor='val_acc', verbose=1, save_best_only=**True**, save_weights_only=**False**, mode='auto', period=1)
model.compile(loss="categorical_crossentropy", optimizer=optimizers.Adam(lr=learning_rate, clipnorm=1.), metrics = ['acc'])history = model.fit_generator(train_generator,
epochs=epochs,
shuffle=**True**,
validation_data=test_generator,
callbacks=[checkpoint]
)
训练完成后,我们再次加载在训练期间具有最佳验证准确性的检查点文件:
model = models.load_model("sign_classifier_augm.h5")
绘制学习曲线:
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1,len(acc)+1)
plt.figure()
plt.plot(epochs, acc, 'b', label = 'Training accuracy')
plt.plot(epochs, val_acc, 'r', label='Validation accuracy')
plt.title('Training and validation accuracy')
plt.legend()
*#plt.savefig('Accuracy_Augmented.jpg')*
plt.figure()
plt.plot(epochs, loss, 'b', label = 'Training loss')
plt.plot(epochs, val_loss, 'r', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()
*#plt.savefig('Loss_Augmented.jpg')*
计算并绘制混淆矩阵:
Y_pred = model.predict_generator(test_generator)
y_pred = np.argmax(Y_pred, axis=1)
cm_aug = confusion_matrix(test_generator.classes, y_pred)
plot_confusion_matrix(cm_aug, classes = category_names, title='Confusion Matrix', normalize=**False**, figname = 'Confusion_matrix_Augm.jpg')
计算在测试集上评估的最终准确度:
accuracy = accuracy_score(test_generator.classes, y_pred)
print("Accuracy in test set: **%0.1f%%** " % (accuracy * 100))
这给出了 99.3%的输出,与我们没有增强图像的初始模型相比,这是一个改进!
模型精度的评估:
从上述模型准确性的结果可以看出,数据扩充确实提高了我们模型的准确性。在当前示例中,我们获得了大约 99%的最终准确度。此外,通过检查上面的混淆矩阵,我们可以检查模型错误地分类了哪些标志类别。在这里,我们注意到,在少数情况下,该模型仍然将“交叉点”错误分类为“产量”,但明显优于没有图像增强的模型。
注意:如果重新运行代码时没有得到完全相同的数字,也不用担心!在模型初始化等方面存在一些固有的随机性。这可能会使结果有时略有不同。
从测试集中绘制一些图像,并将模型预测与实际情况进行比较:
作为模型准确性的最终可视化,我们可以绘制测试图像的子集以及相应的模型预测。
为“test_subset”定义一个文件夹,其中包含了测试集中的 50 幅图像:
test_subset_data_dir = "data/test_subset"
test_subset_generator = test_datagen.flow_from_directory(
test_subset_data_dir,
batch_size = batch_size,
target_size = (img_height, img_width),
class_mode = "categorical",
shuffle=**False**)
对该文件夹中包含的图像进行预测,并将图像与预测的和实际的类一起可视化。你同意这些分类吗?
Y_pred = model.predict_generator(test_subset_generator)
y_pred = np.argmax(Y_pred, axis=1)
img_nr = 0
**for** subdir, dirs, files **in** os.walk('data/test_subset'):
**for** file **in** files:
img_file = subdir + '/' + file
image = load_img(img_file,target_size=(img_height,img_width))
pred_emotion = category_names[y_pred[img_nr]]
real_emotion = category_names[test_subset_generator.classes[img_nr]]
plt.figure()
plt.title('Predicted: ' + pred_emotion + '**\n**' + 'Actual: ' + real_emotion)
plt.imshow(image)
img_nr = img_nr +1
分类模型的输出示例
总结:
如果您设法使用包含的数据集浏览了整个教程,您有望对深度学习和图像识别如何用于解决交通标志分类的现实问题有所了解。祝你好运,用其他图片进一步探索这个模型,这些图片可以来自你的公司,也可以来自 kaggle 等资源,或者只是谷歌图片搜索!
如果你想要更多关于这个图像分类教程(以及一般的机器学习)的详细信息,我还会在下面的研讨会演示中介绍这些材料:“从炒作到现实世界的应用”。(教程演练大约开始。视频开始 35 分钟)。
祝你好运!
你觉得这篇文章有趣吗?如果是这样的话,你可能也会喜欢我的其他一些关于人工智能、机器学习、物理等主题的文章。,你可以在下面的链接和我的中型作者简介中找到:【https://medium.com/@vflovik】
而且,如果你想成为一个媒体会员,免费访问平台上的所有资料,你也可以使用下面我的推荐链接。(注意:如果您使用此链接注册,我也会收到一部分会员费)
[## 通过我的推荐链接加入 Medium—Vegard flo vik
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@vflovik/membership)
更多来自 Vegard Flovik 媒体:
- 蒙特卡洛方法简介
- 从物理学到数据科学的转变
- 什么是图论,为什么要关心?
- 如何(不)使用机器学习进行时间序列预测:续集
- 建造一个能读懂你思想的人工智能
- 人工智能和大数据隐藏的风险
- 如何使用机器学习进行异常检测和状态监控
- 如何(不)使用机器学习进行时间序列预测:避免陷阱
- 如何利用机器学习进行生产优化:利用数据提高绩效
- 你是怎么把物理教给 AI 系统的?
- 我们能使用纳米级磁铁建立人工大脑网络吗?
- 供应链管理中的人工智能:利用数据推动运营绩效
深层变分推理
用 DL 体系结构研究变分推理
深度变异推理——伽玛分布
作者:纳坦·卡茨
贝叶斯推理
在机器学习(ML)的世界里,贝叶斯推理经常被当作是没有人愿意采纳的奇特的谜一样的大叔。一方面,贝叶斯推理提供了大量来自数学、统计学和物理学的理论科学工具。此外,它承载着令人印象深刻的科学突破的历史遗产。另一方面,正如几乎每个数据科学家都会说的那样:它在实践中几乎从未奏效。
这篇文章由两部分组成:
1.变分推理的产生概述(六)
2.描述我尝试使用 DL 技术解决一个 VI 问题。
贝叶斯问题
贝叶斯问题可以描述如下:我们有观测数据 X
其中数据可以表示数字、类别或任何其他可以想象的数据类型。我们假设该数据是使用潜在变量 Z. 生成的,我们手头有四种分布:
1.P( Z )潜在变量的先验分布
2.P( X | Z )可能性—此函数的分布类型由数据决定,(例如:如果我们有整数,我们可能会想到泊松,如果我们有正数,我们可能会使用伽马分布)。
3.P( X ) —观测数据的分布。
4.P( Z | X )后验分布——给定值 X 时,具有值 Z 的概率
这些分布通过贝叶斯公式结合在一起:
因此,贝叶斯问题是关于寻找后验分布和 Z 的值。障碍在于,在现实生活的模型中,P(X)很难处理。
直到 1999 年,解决贝叶斯问题的工作方式是利用抽样。诸如 Metropolis Hastings 或 Gibbs 之类的算法被成功地用于在广泛的科学领域中求解后验函数。尽管它们工作得很好,但存在两个重大问题:
高方差
缓慢收敛
1999 年迈克尔·乔丹发表了一篇论文《变分图形模型导论》(这一年更著名的 MJ 退出了,这提出了宇宙是否受“MJ 守恒定律”支配的问题)
在这篇论文中,他描述了贝叶斯问题的解析解。在这个解决方案的核心中,他建议,我们可以通过设置 q 的家族函数引入潜在变量 Z. 的分布函数 q ,而不是通过采样来追踪后验函数,我们可以使用这个 q 来逼近后验函数。对于这个解,他使用了欧拉-拉格朗日方程,这是变分法中的一个基本方程,它带来了的概念:变分推理(VI) 。
什么是变分推理?
在本节中,我们将详细描述 VI。回想一下,我们的目标是使用函数 q 来逼近后验函数 P( Z | X ),该函数是 Z 的分布。乔丹建议的衡量标准是 KL 散度(https://project Euclid . org/download/pdf _ 1/Euclid . aoms/1177729694
这种解析解的思想减少了高方差和缓慢收敛的障碍。另一方面,由于我们设置了一系列函数,我们引入了一些偏差。以下公式说明了所提供的解决方案:
LHS 不依赖于 Z ,因此可以将其视为常数。最小化 KL 散度相当于最大化第二项:“证据下界”(ELBO)
作为具有预定义形状的函数, q 具有由λ表示的常数。
我们可以将 VI 视为一个 ELBO 最大化问题:
物理!
Jordan 使用这个解决方案的动机来自于 Helmholtz 和 Boltzmann 在热力学方面的工作。ELBO 函数非常类似于亥姆霍兹自由能,其中第一项是能量,第二项是熵。Jordan 使用伊辛模型的平均场定理(MFT ),假设磁自旋不相关,这简化了处理 q 的方式。伊辛问题有一个指数解(玻尔兹曼分布),这成为了 q 形状的普遍选择
VI —示例
我现在将提供一个例子来说明如何制定一个 VI 问题。我们将假设我们有一个高斯似然的实数数据。潜变量 **Z,**因此是一对
利用平均场定理, q 可以写成乘积
我们在哪里
详细的配方可以在这里找到
可以看出,这样的公式需要对每个模型进行大量的分析计算。当我们讨论 BBVI 时,我们将在下面的一个部分中讨论这一点。
2002 年,Blei 发表了他的“潜在的狄利克雷分配”,在那里他使用 VI 进行主题抽取,VI 得到了很大的提升
有几种工具可用于 VI,如 Edward、Stan、PyMC3 和 Pyro
利用 VI 进行分布尾部的推断
我必须处理的问题是识别观察数据的尾部。数据本身是一组概率值,因此我们假设可能性具有贝塔分布。在讨论建模步骤之前,我先举一个尾部典型问题的例子。
让我们假设我们有一个预测疾病的模型,准确率为 99%。我们可以假设 0.1%的人口患病。每天有 10 万人接受测试。990 个健康的人会听到自己有病。这个错误代价很高,因为他们要做医疗程序。出现这种问题主要是因为模型通常被训练成在对称假设下优化准确性。如果我们依赖我们的模型,阈值的微小变化可能会造成巨大的损失。因此,我们需要尽可能准确地理解 1%的尾部。
VI 作为一种分析解决方案,似乎是实现这一目的的一个有趣的工具。令人惊讶的是,我发现 DL 的世界并没有大量拥抱 VI,这确实鼓励我走这条路。
变分推理的深度学习
在这一部分,我将描述我使用 DL 解决 VI 问题的尝试。回想一下,我们的数据的可能性有一个贝塔分布。这个分布有一个非常困难的先验。因此,我们把γ作为先验,因为它在正实线上有支持。在 VI 术语中,γ是先验分布和 q 分布。因此,我们训练 Gamma 对 Z进行采样,Z 本身就是β的{α,β}对。
混合密度网络-MDN
要考虑的第一个框架是 MDN(混合密度网络)。毕晓普(http://publications.aston.ac.uk/id/eprint/373/)提出的这类网络旨在学习给定分布的参数。我们修改损失:而不是使用可能性,我们使用 ELBO。
在所有图中,红色代表我们基于 VI 的样本,蓝色是由随机引擎创建的合成样本。
以下是我们 MDN 试验的典型结果:
基于 VI 的样品相对接近合成样品。然而,它肯定是可以改进的。此外,虽然在内部和左侧(从我的角度来看,这是感兴趣的尾巴)非常相似,但在上部尾巴,我们遭受巨大的差异。
我们希望尝试其他工具。
强化学习——演员评论家
变分推理经常被解释为强化学习问题(http://www 0 . cs . UCL . AC . uk/staff/d . silver/web/Publications _ files/viral . pdf)。我们认为 q 函数为策略函数, Z 为选项,报酬为 ELBO。当我们使用 RL 工具解决此类问题时,我们必须注意到需要进行两项修改:
我们没有插曲——我们有 IID 样本
选项不是离散的,而是伽玛分布的
为了解决第一个子句,我们必须修改 Q 学习更新公式:
因为没有真正的插曲,所以必须去掉第二项,因为它表示未来的预期回报。
关于第二个子句,我们必须训练一个 Gamma 形式的策略函数(这里有一个很好的动机http://proceedings.mlr.press/v70/chou17a/chou17a.pdf
为了训练一个策略函数,我们将使用 actor-critic with experience replayhttps://towards data science . com/understanding-actor-critic-methods-931 b 97 b 6 df 3 f并添加我们的修改。
这些是我们得到的图表:
对于小正值,结果在区间[0,1-a]内相当好。我们完全没有建立上尾翼的模型。
黑盒变分推理
虚拟仪器的出现为研究后验分布提供了新的方向。然而,它对期望值进行了大量的分析计算(参见 Gaussian dist 的例子)。以上)。有一个明确的目标,就是找到一个更通用的方案,减少分析量,更好地处理大量数据。下面的幻灯片是 Blei 对这种需求的描述:
提供的解决方案使用了随机优化。Robbins 和 Monro 提出的一类算法(一种随机近似方法,1951 年)
罗宾斯-门罗算法
罗宾斯门罗算法旨在解决一个根问题:设 F 为函数,α为常数。我们假设方程存在唯一的解:
我们希望找到它。
假设 F 不可观测,但是存在随机变量 T,使得
Robbins 和 Monro 已经表明,对于某些规则,以下算法收敛于 L:
这个序列叫做罗宾斯门罗序列。
返回 BBVI
在 2013 年https://arxiv.org/pdf/1401.0118.pdf的一篇论文中,Blei 建议通过使用 Robbins-Monro 序列对 VI 进行两步改进。这种算法被称为“黑盒变分推理”(BBVI)。第一步如下所示:
主要思想是构建一个针对 ELBO 梯度的蒙特卡罗估计器,并使用 Robbins Monro 序列,如后面部分所述。这种算法(和许多其他蒙特卡罗算法一样)存在高方差。Blei 提出了两种方法来减少这种差异:
在这篇论文中,Blei 使用 Rao Blackwell 通过使用条件分布的 Rao Blackwell 性质来创建每个常数的估计量。
现在绘图
我使用的 BBVI 没有方差减少技术
我们可以看到,与 AC 相比,我们减少了尾部问题,但仍然存在这个问题。在最后一个图中,我们没有尾部问题,但是近似性变弱了
成绩汇总
我们看到,将深度学习工具用于 VI 取得了部分成功。我们在区间内进行了相当好的逼近,但无法逼近上尾部。此外,在所有的框架中,我都遭受了一定程度的不稳定。
有几个看似合理的原因:
DL-问题
建筑不够复杂
更多时代
γ-β问题
传统上,DL 问题是在高斯或均匀等常见分布上研究的。这些分布没有依赖于偏度和峰度的参数。这在 Gamma 中不是这样,在 Gamma 中,由引擎训练的参数完全确定偏斜度和峰度。这可能需要不同的技术
我们用 ELBO 作为损失函数。该函数强烈依赖于先前的形状。伽玛并不是贝塔的真正先验。这可能意味着需要修改损失
Beta 有紧凑的支持。事实上,我们只在尾部附近有问题(分布的一个“奇点”),这可能会带来障碍。这个“奇点”问题有待研究
我们可以总结说,这些实验已经表明 VI 可以使用 DL 机制来解决。然而,这需要进一步的工作。尽管如此,我们还是为这位神秘的叔叔澄清了一些事情。
这里有一个模仿我的试验的 torch 代码(抱歉,真实的代码已经用于我做的一些商业工作)
【https://github.com/natank1/DL-_VI
致谢
我要感谢 Uri Itai 在工作之前和期间进行的富有成效的讨论以及他的全面审查,感谢 Shlomo Kashani 和 Yuval Shachaf 提出的想法和意见,感谢 Leonard Newnham 澄清强化学习领域的问题
参考文献
http://www.jmlr.org/papers/volume3/blei03a/blei03a.pdf
https://people . eecs . Berkeley . edu/~ Jordan/papers/variable-intro . pdf
https://towards data science . com/a-hitch illers-guide-to-mixture-density-networks-76b 435826 CCA
https://publications . Aston . AC . uk/id/eprint/373/1/NCRG _ 94 _ 004 . pdf
https://www . ri . CMU . edu/WP-content/uploads/2017/06/thesis-Chou . pdf
http://www.michaeltsmith.org.uk/#
https://github.com/trevorcampbell/ubvi/tree/master/examples
https://arxiv.org/pdf/1811.01132.pdf
http://proceedings.mlr.press/v70/chou17a/chou17a.pdf
https://towards data science . com/understanding-actor-critic-methods-931 b 97 b 6 df 3 f
http://incompleteideas.net/book/the-book-2nd.html
https://arxiv.org/pdf/1401.0118.pdf
https://project Euclid . org/download/pdf _ 1/Euclid . aoms/1177729586
http://edwardlib.org/tutorials/klqp
https://mc-stan.org/users/interfaces/
【https://github.com/stan-dev/pystan/tree/develop/pystan
https://docs.pymc.io/notebooks/getting_started.html
https://project Euclid . org/download/pdf _ 1/Euclid . aoms/1177729694
http://publications.aston.ac.uk/id/eprint/373/
深度行走:被忽视的 NLP 和图数据结构的私生子
随机漫步和 Word2Vec 优于矩阵分解,产生了惊人的强大的节点嵌入
信用:Pixabay
该理论
近年来,自然语言处理(NLP)经历了创新的复兴;似乎每年都有一些新的算法超越了它的前辈。例如,开创性的论文“注意是你所需要的”真正震撼了 NLP 雪花玻璃球,使以前的艺术级神经网络架构,如 LSTM,相形见绌。然而,您可能会惊讶地听到,随着神经网络的应用,图形数据结构刚刚达到学术兴趣的顶峰。
图形很棘手;它们可以被表示为(邻接)矩阵,但是它们也可以被表示为它们自己独特的数据结构,其中每个节点引用同一图中可变数量的其他节点。这种可变性是图表如此迷人的真正原因——它们不完全是表格数据,很容易用矩阵表示,但也不完全是非结构化的。事实上,有些人可能会认为图像比图表更具结构性。图像的内容可能变化很大,但是给定指定的尺寸,每个像素都有相同数量的相邻像素(邻居)。相反,图节点的邻居数量是可变的。尽管有其微妙的本质,图表在社会中随处可见;社交网络、电网和供应链只是图形多功能性的几个明显例子。
人们对一些问题进行了大量思考,比如*“如何最好地搜索一个图——先搜索深度还是广度?”*但是越来越多的人对寻找节点间的相似性(或相异性)感兴趣。这可以用于人道主义目标(例如,根据以前的病毒爆发位置及其结构,确定潜在的病毒爆发高风险城市)或简单的商业目标(例如,向应用程序用户推荐朋友和/或产品)。)
考虑推荐系统——不是所有的用户都喜欢相同数量的产品,也不是所有的产品都被相同数量的用户喜欢;它几乎要求图形数据结构。然而……使用矩阵和分解技术(比如 SVD)来呈现推荐是非常普遍的。
为了学习节点嵌入,必须以某种方式对图结构进行采样。一种简单(但令人惊讶的有效)的方法是通过随机漫步,这非常简单:从任何给定的节点开始,识别所有邻居,随机选择一个……然后漫步。冲洗并重复,直到你走了足够多的(这需要一些判断并引入一些偏差。)在推荐系统的上下文中,我们的图是 二分图——意味着有两类节点(产品和用户。)这样,给定的随机游走将从一个类的实例跳到另一个类的实例。例如:
*John -> Titanic -> Allie -> Pearl Harbor -> Adam -> The Pianist*
对图形进行采样有点像在迷宫中漫步;您从一个起点随机行走(在完成行走之前可能会多次返回到起点),并重复这个过程几次。当你完成每一步的时候,你会对迷宫 看起来像 有一个相当不错的想法。然而,在它们目前的形式下,这些随机漫步不能直观地使用。别担心——NLP 来帮忙了!
Google 在 2013 年提出的算法 Word2Vec,可以通过滑动窗口方案来学习单词的相似度。一次看到 x 个单词(在窗口中),一个目标单词和(通常)5 个来自直接周围上下文的上下文单词(duh。)一个神经网络简单地学习回答问题,“是目标词***(在当前窗口中)的一个上下文词吗?”所以像“狗”这样的词可能有频繁出现的上下文词,如“散步”和“宠物”同样,“猫”这个词可能有半相似的上下文词(也许不包括散步——我不知道谁会带着猫散步。我们能够通过任何两个单词共享(或不共享)相同上下文的频率来量化它们之间的相似性。并且这些上下文在嵌入中被捕获(当被目标词“激活”时,完全训练的神经元的神经网络层。)嵌入的观察数值可以通过距离度量(例如余弦相似度)与其他数值进行比较,以确定与单词的相似程度。***
所以我们知道两件事:(A)我们的随机行走产生了语言样本,以及(B) Word2Vec 可以学习给定语言的单词嵌入(或者在我们的例子中,节点嵌入)。这就是深度行走算法的全部内容。
如果您对白皮书感兴趣,请不要再看了!
应用程序
在一家著名的技术公司工作时,我带领一个数据科学实习生团队开发了一个产品,可以将求职者与招聘海报相匹配。竞争对手让求职者充斥着招聘海报,反之亦然。目标不是高质量的比赛,而是注意力超载。如果你找不到工作候选人,说明你不够努力。我的主管想要一款可以帮助求职者和求职者找到对方的产品——不是通过匹配职位,而是通过匹配技能。我拿到的教科书案例是:
X-Corp(一个隐藏身份和利益的假名)例行公事地需要 C++专家;他们上传“软件工程师”的招聘信息,但似乎无法及时找到合格的候选人。 你能做什么?
我思考了这个问题,意识到工作描述和简历没有被充分地分析技能。仅仅一个职位头衔就足以引发 Glassdoor 上的匹配,的确如此。我们需要了解技能对技能、工作对工作以及(最重要的)技能对工作之间的关系。成功学习这些关系的意义是非常有益的。
*由于保密协议状态,我不能提供实际的数据,也不能提供用于解决这个问题的具体架构。然而,我将使用公开可用的数据通过一个综合问题来说明这些概念。劳工统计局维护着一个名为 ONET ( 的数据集,我相信这是职业网络的简称。这个资源由统计学家、经济学家和劳动研究人员维护。一些数据集可以在网上免费获得。感兴趣的是技术技能数据集。
技术技能数据预览
我们只对第二列和第三列感兴趣,即职称(title)和技能职称(Example。)这些数据形成了一个二分图,其中给定的工作与多种技能有关系,给定的技能与给定的工作有多种关系。通过一点数据预处理,我们可以从推荐系统中借用一页(尽管我将证明这不如深度行走方法有效。)我们简单地为每个技能-工作关联创建一个“一次性”编码,在工作-技能矩阵中,如果工作需要某项技能,则用 1 表示(如果不需要,则用 0 表示)。与推荐系统没有任何不同!
为了简洁起见,我将把存储库链接留在这里。
Pandas 有一些很酷的内置函数,允许我们相对轻松地将上述格式的数据转换成一种热编码。(但是请注意矩阵是多么稀疏!)
数据清理
现在,我们有几个矩阵分解的选项。就个人而言,我更喜欢使用 PyTorch 的基于梯度的方法,使用均方误差成本函数。然而,奇异值分解也在推荐系统中广泛使用。代码细节已在回购中详细说明!
我们可以通过“抽查”节点嵌入来定性地评估我们的性能。我写的一个简单的函数找到正确类别的节点,(工作或技能),给定余弦相似性最小阈值和最大计数阈值。有些结果是直观的,比如数据库管理员,也许还有生物统计学家。然而,像供应链经理和技术作家这样的角色会提出这样一个问题——“一切都是随意相似的吗?“并且有证据支持这个结论,直觉匹配和非直觉匹配都落在余弦相似度范围内(0.8- > 0.9)。也许有意义的比赛只是一个机会的问题?
矩阵分解方法
类别设置为无
注意,在第二个截图中,我将类别设置为 none。这将检索技能和工作;但是,在给定阈值的情况下,我们没有捕获任何作业。事实上,Adobe Systems Illustrator 是 C++第二常见的节点;它比 Python“更相似”,比软件开发人员更相似(如上面的“仅工作匹配”中所示。)
我们可以评估节点嵌入结果的一个有趣的方法是查看它们的二维分布。我们可以通过主成分分析将维数从 10 减少到 2,这保留了模型中的大部分方差,在 2D 表示中捕获。PCA 是一个棘手的概念,我们今天不会在这个理论上绕太远。现在,让我们只检查结果!
矩阵分解 PCA 图
然而,在这种表示中,你看不出职业是用红色编码的,而技能是用蓝色编码的。实际上,所有节点都映射到相同的接近 0 的 x 轴值,而所有有意义的变化都发生在 y 轴上。有一些例外,但这些只是少数的技能。那么…哪里出了问题?
嗯,我们有几个重要的限制要讨论。第一,有近 9000 个技术技能,只有(差不多)1000 个工作岗位。此外,有些工作比其他工作需要更多的技能。因此,与职务对应的给定基准表行的总和可能是相对较高的数字,如 100(意味着该职务拥有 100 项技能)或相对较低的数字,如 10。这里起作用的潜在变量是节点连通性、介数和/或中心性。一些节点与技能有很好的联系,这些技能可能与其他工作有很好的联系,也可能没有。此外,由于工作与技能之间的不平衡,这种一键矩阵非常稀疏。矩阵因式分解需要将一个矩阵分解成两个,当两个矩阵相乘时,返回原矩阵。正如你所看到的,0 的存在远远超过了 1 的影响。
换句话说,就和都不具备的技能而言,工作是相似的!当矩阵稀疏性是一个问题时,这种直觉可以应用于推荐系统。**
您可能已经注意到,使用一次性编码矩阵可能不是最理想的。你是对的!我们可以从 NLP 中采用各种编码策略来增强我们的结果…然而,这将不可避免地引入用户偏见。例如,伪 TF-IDF 设计可能会考虑某项技能在所有作业中出现的总次数以及单个作业的总技能数。 Microsoft Excel 在这个数据集中极为常见;应该和 C++这种相对不常见的技能一样有影响力吧?问得好!
(对于那些好奇的人,我还使用 SVD 来分解一个热编码矩阵。这是主成分分析图。)
奇异值分解主成分图
我们可能会花费数周时间来尝试对最佳设计进行特征设计(不管分解技术如何),但此时,让我们后退一步,考虑一种更直观、图形友好的方法。进入——深走。
如前所述,我们需要通过随机游走的图形采样来收集语言的“语料库”。让我们从技能 Python 来考察一个随机游走。
从 Python 开始的随机漫步
请注意,职业统计员出现了 3 次,作为技能、 SAS JMP 和数据描述数据表之间的中间跳转。随机漫步发现了什么?这些技能有些孤立,没有很好的联系,工作关联也很少。这正是扰乱矩阵分解方法的原因。然而,随机漫步雄辩地抓住了这些技能的中心性(或缺乏中心性)。注意,这个随机漫步是使用 NetworkX 执行的,NetworkX 是一个非常棒的基于 python 的图形/网络建模包。
现在,我们将简单地使用 Gensim 实现,而不是从头开始实现 Word2Vec。为了保持矩阵分解结果的一致性/可比性,我们还将学习 10 个潜在特征。无论是哪种情况,这都是一个你需要关注的超参数——它有效地控制了过度拟合(这在推荐系统和节点嵌入的上下文中是一个棘手的话题)。)
让我们看看 Deep Walk 的表现。请注意,技能和工作都被检索到,这说明它们被映射到相似的空间,但并不是任意地彼此相似——节点相似性差异是有意义的!
为了进一步说明生成的节点嵌入的质量,让我们检查另一个 PCA 图。(还是那句话,职业和红色,技能是蓝色。)
深度行走 PCA 图
****哇!这不仅是美丽的,它显示了我们应该想从我们的嵌入这么多的东西。(A)嵌入分布在更大的空间上。(B)存在主要是“技能”的不同分类区域和主要是“职业”的区域©然而,这些区域有适度的重叠,描绘了高度相互关联的节点(无论是技能还是职业。这种方法表现如此之好的一个原因是随机漫步本身。技能可能比职业多,但整个“语料库”采用了 job -> skill -> job -> skill...
的形式,这意味着稀疏的影响将以一种巧妙的方式得到缓解!
最后,我们开始的源问题——我们如何更快地找到 C++程序员?天真的直觉会告诉我们,软件开发人员是现任的 C++专家。然而,我们可以看到物理学家和机器人工程师更接近 C++。我们无法确定为什么会这样,但我们可以提出一些叙述。C++是一种低级语言。web 开发人员越来越多地使用框架,这样他们就不需要不断地重复发明轮子。期望一个 web 开发人员成为安全专家、网络专家、图形渲染专家、数据库专家等等,以及 web 应用程序可能需要的所有元素是不现实的。然而,物理学家可能非常需要知道从同一实验室的工程师设计的传感器中收集数据,一种低级语言将帮助他们最大限度地利用分配给他们的计算资源。
TL/DR —推荐系统广泛使用矩阵分解。当存在最小的阶级不平衡时(无论是用户对产品,工作对技能,等等),这是非常有用的。)像 TF-IDF 这样的编码技巧可以(理论上)增强一键编码产生的结果。然而,稀疏性会极大地限制矩阵分解的有效性。图形友好的方法是推荐系统、信息检索等等的未来!我鼓励您尝试链接存储库中的代码,并将这些技术应用到您自己选择的新颖应用程序中。
如果你认为我的内容没问题,请订阅!😃
DeepAnT——时间序列的无监督异常检测
只有当你有大海捞针的方法时,才能观察到图案的美!
丹尼尔·塔夫乔德在 Unsplash 上的照片
什么是异常现象,我为什么要担心?
“一个异常值”或“异常值”是样本空间中那些异常的数据点,或超出趋势。现在,问题是,“你如何定义异常或异常的东西?”
答:数学上,不在相同趋势中的数据点与其邻域中的数据点相同。
作为业务伙伴或技术专家,在日常工作中从大量数据中发现异常模式。在这里,我们将讨论一种能够以接近实时的格式检测数据中所有(几乎)异常的方法。
在本文中,我们将尝试学习如何从数据中检测异常而无需事先训练模型,因为你无法根据数据训练模型,而我们对此一无所知!
这就是无监督学习的想法出现的地方。
选择时间序列数据的原因是,它们是最常见的真实世界数据之一,我们作为数据科学家进行分析。
来到模型——“**DeepAnT”**是一个无监督的基于时间的异常检测模型,它由卷积神经网络层组成。在检测时间序列数据中的各种异常时,它确实工作得很好。但这可能需要注意检测噪声,这可以通过调整超参数来处理,如内核大小、回看、时间序列窗口大小、隐藏层中的单元等等。
代码和数据的链接在这里的 Github 链接中提供—
[## bmonikraj/medium-ds-unsupervised-异常检测-deepant-lstmae
使用 DeepAnT 和 LSTM 自动编码器数据描述的无监督异常检测的基于深度学习的技术…
github.com](https://github.com/bmonikraj/medium-ds-unsupervised-anomaly-detection-deepant-lstmae)
数据中的特征数= 27(包括’时间戳’特征)
数据特征类型=数值
现在我们知道了数据,让我们进入代码库,解决我们遇到的问题。
问题描述:-我们有大约 80 年的加拿大气候数据(数据频率=每天),我们想从气候数据中识别异常。
import numpy as np
import pandas as pd
import torch
from sklearn.preprocessing import MinMaxScaler
import time
import datetime
import matplotlib.pyplot as plt
import seaborn as sns
import os
data_file = ""
MODEL_SELECTED = "deepant" *# Possible Values ['deepant', 'lstmae']*
LOOKBACK_SIZE = 10
for dirname, _, filenames **in** os.walk('/kaggle/input'):
for filename **in** filenames:
data_file = os.path.join(dirname, filename)
模块被导入,文件被加载到 Kaggle 内核的环境中。
def read_modulate_data(data_file):
*"""*
*Data ingestion : Function to read and formulate the data*
*"""*
data = pd.read_csv(data_file)
data.fillna(data.mean(), inplace=True)
df = data.copy()
data.set_index("LOCAL_DATE", inplace=True)
data.index = pd.to_datetime(data.index)
return data, df
在上面的代码片段中,我们从文件中读取数据,该文件存在于环境中。
读取后,我们将索引数据转换为时间戳。
将时间戳作为数据索引的主要动机是,如果需要,通过数据帧图和重采样进行更好的分析。
def data_pre_processing(df):
*"""*
*Data pre-processing : Function to create data for Model*
*"""*
try:
scaled_data = MinMaxScaler(feature_range = (0, 1))
data_scaled_ = scaled_data.fit_transform(df)
df.loc[:,:] = data_scaled_
_data_ = df.to_numpy(copy=True)
X = np.zeros(shape=(df.shape[0]-LOOKBACK_SIZE,LOOKBACK_SIZE,df.shape[1]))
Y = np.zeros(shape=(df.shape[0]-LOOKBACK_SIZE,df.shape[1]))
timesteps = []
for i **in** range(LOOKBACK_SIZE-1, df.shape[0]-1):
timesteps.append(df.index[i])
Y[i-LOOKBACK_SIZE+1] = _data_[i+1]
for j **in** range(i-LOOKBACK_SIZE+1, i+1):
X[i-LOOKBACK_SIZE+1][LOOKBACK_SIZE-1-i+j] = _data_[j]
return X,Y,timesteps
except **Exception** as e:
print("Error while performing data pre-processing : **{0}**".format(e))
return None, None, None
在这里,我们在[0,1]
的范围内对数据进行标准化,然后通过将“时间步长”作为一个维度纳入图片来修改数据集。
想法是将维度数据集从[Batch Size, Features]
转换到[Batch Size, Lookback Size, Features]
class **DeepAnT**(torch.nn.Module):
*"""*
*Model : Class for DeepAnT model*
*"""*
def __init__(self, LOOKBACK_SIZE, DIMENSION):
super(DeepAnT, self).__init__()
self.conv1d_1_layer = torch.nn.Conv1d(in_channels=LOOKBACK_SIZE, out_channels=16, kernel_size=3)
self.relu_1_layer = torch.nn.ReLU()
self.maxpooling_1_layer = torch.nn.MaxPool1d(kernel_size=2)
self.conv1d_2_layer = torch.nn.Conv1d(in_channels=16, out_channels=16, kernel_size=3)
self.relu_2_layer = torch.nn.ReLU()
self.maxpooling_2_layer = torch.nn.MaxPool1d(kernel_size=2)
self.flatten_layer = torch.nn.Flatten()
self.dense_1_layer = torch.nn.Linear(80, 40)
self.relu_3_layer = torch.nn.ReLU()
self.dropout_layer = torch.nn.Dropout(p=0.25)
self.dense_2_layer = torch.nn.Linear(40, DIMENSION)
def forward(self, x):
x = self.conv1d_1_layer(x)
x = self.relu_1_layer(x)
x = self.maxpooling_1_layer(x)
x = self.conv1d_2_layer(x)
x = self.relu_2_layer(x)
x = self.maxpooling_2_layer(x)
x = self.flatten_layer(x)
x = self.dense_1_layer(x)
x = self.relu_3_layer(x)
x = self.dropout_layer(x)
return self.dense_2_layer(x)
我们正在创建模型 DeepAnT 架构(关于论文的更多信息可以在 IEEE 的链接— 研究论文中找到)。
它包含两层卷积层,在确定数据时间模式中的异常时非常有效。
可以根据数据进一步调整内核大小和过滤器数量,以实现更好的性能。
让我们来看看模型架构,以便更好地直观理解—
由 Mohsin Munir、Shoaib Ahmed Siddhiqui、Andreas Dengel 和 Sheraz Ahmed 撰写的 IEEE 论文中的 DeepAnT 模型架构
def make_train_step(model, loss_fn, optimizer):
*"""*
*Computation : Function to make batch size data iterator*
*"""*
def train_step(x, y):
model.train()
yhat = model(x)
loss = loss_fn(y, yhat)
loss.backward()
optimizer.step()
optimizer.zero_grad()
return loss.item()
return train_step
功能make_train_step
是创建迭代器,它可以向计算模型提供小批量的数据。
MSE 损失函数传递给 make_train_step 函数,Adam 优化器用于多个历元后的损失函数优化和收敛。
def compute(X,Y):
*"""*
*Computation : Find Anomaly using model based computation*
*"""*
if str(MODEL_SELECTED) == "deepant":
model = DeepAnT(10,26)
criterion = torch.nn.MSELoss(reduction='mean')
optimizer = torch.optim.Adam(list(model.parameters()), lr=1e-5)
train_data = torch.utils.data.TensorDataset(torch.tensor(X.astype(np.float32)), torch.tensor(Y.astype(np.float32)))
train_loader = torch.utils.data.DataLoader(dataset=train_data, batch_size=32, shuffle=False)
train_step = make_train_step(model, criterion, optimizer)
for epoch **in** range(30):
loss_sum = 0.0
ctr = 0
for x_batch, y_batch **in** train_loader:
loss_train = train_step(x_batch, y_batch)
loss_sum += loss_train
ctr += 1
print("Training Loss: **{0}** - Epoch: **{1}**".format(float(loss_sum/ctr), epoch+1))
hypothesis = model(torch.tensor(X.astype(np.float32))).detach().numpy()
loss = np.linalg.norm(hypothesis - Y, axis=1)
return loss.reshape(len(loss),1)
else:
print("Selection of Model is not in the set")
return None
最后一步是通过数据运行模型(批量)。我们使用 MSE 损失函数和 Adam 优化器,并在 30 个时期内运行。
此后,我们生成假设并计算损失,即数据集中给定的各个时间戳的异常置信度得分。
形象化
异常置信度得分的频率分布|作者图片
异常可信度分数与时间戳(freq=“daily”) |作者图片
看上面的两个图,我们可以得出结论,异常置信度得分大于 1.2 的时间戳是那些可以被视为潜在异常的时间戳,并且可以通过分析采取进一步的行动:)
- DeepAnT 是一种适用于基于时间序列的异常检测的体系结构模型。
- 用于类似问题的其他架构有:LSTM 自动编码器、具有时间信息的 kNN 聚类。
- 时间序列数据,在需要实时分析的情况下,应该考虑数据流。
对于想直接在 Kaggle 内核上运行的:)
使用 Kaggle 笔记本探索和运行机器学习代码|使用加拿大 80 年的气候数据
www.kaggle.com](https://www.kaggle.com/bmonikraj/unsupervised-timeseries-anomaly-detection/notebook)
如有任何疑问,请通过bmonikraj@gmail.com联系我本人
deep chem——在生命科学和化学信息学中使用 ML 和 DL 的框架
使 ML 和 DL 在药物发现、材料科学、量子化学和生物学中的使用民主化。
图片来源: Pixabay
将机器学习和深度学习应用于药物发现、基因组学、显微观察和量子化学可以产生根本性的影响,并有可能显著加快医学研究和疫苗开发的进程,这是任何像 Covid19 这样的疫情所必需的。
在我们开始之前,这篇文章是一篇非常高水平的文章,专门针对对药物发现感兴趣的数据科学家和 ML 研究人员,尤其是在像 Covid19 这样的现有疫情时期。
DeepChem 是一个开源框架,内部使用 TensorFlow,该框架专门用于简化各种生命科学应用的深度学习模型的创建。
在本教程中,我们将了解如何设置 DeepChem,以及如何将 DeepChem 用于:
1.训练一个可以预测分子毒性的模型
2.训练预测分子溶解度的模型
3.使用智能字符串查询分子结构。
设置 DeepChem
虽然,在多个来源中,我看到用户表达了他们对在 Windows、Linux 和 Mac 环境中设置 DeepChem 的关注,但是我发现使用 pip 安装程序很容易做到这一点。
DeepChem 开发团队非常活跃,他们确实提供每日构建,所以我希望每个人都能看看他们的 pypi 页面:https://pypi.org/project/deepchem/#history并安装一个合适的版本,以防最新版本有任何问题。一个简单的 pip 安装 deepchem 将会安装最新的版本。
接下来,除了 DeepChem,您还需要安装 TensorFlow。我已经使用 pip install tensorflow 和开源化学信息学软件包 RDkit 安装了最新版本的 TensorFlow。对于 RDkit 和在 Windows 中安装,我没有找到任何可靠的 pip 安装程序,所以使用 conda 安装程序从https://anaconda.org/rdkit/rdkit安装它:conda install-c RDkit RDkit
一旦这三个模块安装完毕,我们就可以开始实验了。
预测分子的毒性
分子毒性可以被定义为一种物质对任何有机体表现出的副作用的总和。计算方法实际上可以利用分子的化学和结构特性来确定给定化合物的毒性,并利用分子描述符(Dong 等人, 2015 )和指纹(薛和 Bajorath,【2000】)来确定分子特征,可以有效地提取任何给定分子固有的化学和结构信息,用于基于预测的方法。
为了预测毒性,我们将使用 MoleculeNet 的 Tox21 毒性数据集,并使用 DeepChem 加载所需的数据集。
import numpy as np
import deepchem as dc
tox21_tasks, tox21_datasets, transformers = dc.molnet.load_tox21()
在此之后,我们将看到所有的毒性类,只是打印到 21_tasks
['NR-AR',
'NR-AR-LBD',
'NR-AhR',
'NR-Aromatase',
'NR-ER',
'NR-ER-LBD',
'NR-PPAR-gamma',
'SR-ARE',
'SR-ATAD5',
'SR-HSE',
'SR-MMP',
'SR-p53']
我们可以通过以下方式将整个数据集分为训练、测试和验证数据集:
train_dataset, valid_dataset, test_dataset = tox21_datasets
如果我们检查数据集的分布,我们会发现数据集是不平衡的,因此我们需要平衡数据集,因为通常我们会尝试解决多类分类问题。因此,如果数据集不平衡,多数类会给分类器增加偏差,这会扭曲结果。因此,默认使用的 transformer 对象是一个平衡转换器。
print(transformers)
[<deepchem.trans.transformers.BalancingTransformer at 0x26b5642dc88>]
现在,对于培训部分:
model = dc.models.MultitaskClassifier(n_tasks=12, n_features=1024, layer_sizes=[1000])
model.fit(train_dataset, nb_epoch=10)
metric = dc.metrics.Metric(dc.metrics.roc_auc_score, np.mean)
train_scores = model.evaluate(train_dataset, [metric], transformers)
test_scores = model.evaluate(test_dataset, [metric], transformers)
现在,DeepChem 的子模块包含各种 dc.models 不同的生命科学专用模型。
最后我们看到,最终的 AUC-ROC 分数是:
{'training mean-roc_auc_score': 0.9556297601807405}
{'testing mean-roc_auc_score': 0.7802496964641786}
这向我们表明,在模型中存在一些过度拟合,因为与训练集相比,测试数据集度量得分要少得多。但是,尽管如此,现在我们确实有了一个可以预测分子毒性的模型!
预测分子的溶解度
溶解度是一种度量,它显示了分子在水中溶解的难易程度。对于任何药物发现,检查化合物的溶解度是非常重要的,因为药物应该溶解到患者的血流中,以达到所需的治疗效果。通常,药物化学家花费大量时间来修饰分子以增加溶解性。在本节中,我们将使用 DeepChem 来预测分子的溶解度。
我们将使用 MoleculeNet 的 delaney 数据集来预测分子溶解度,该数据集也可在 DeepChem 中获得。
# load the featurized data
tasks, datasets, transformers = dc.molnet.load_delaney(featurizer='GraphConv')# Split into traintest-validation dataset
train_dataset, valid_dataset, test_dataset = datasets# Fit the model
model = dc.models.GraphConvModel(n_tasks=1, mode='regression', dropout=0.2)
model.fit(train_dataset, nb_epoch=100)# Use r2 score as model evaluation metric
metric = dc.metrics.Metric(dc.metrics.pearson_r2_score)
print(model.evaluate(train_dataset, [metric], transformers))
print(model.evaluate(test_dataset, [metric], transformers))
甚至在第一遍中,我们从模型评估结果中看到一些过度拟合。
{'training pearson_r2_score': 0.9203419837932797}
{'testing pearson_r2_score': 0.7529095508565846}
让我们看看如何预测一组新分子的溶解度:
smiles = ['COC(C)(C)CCCC(C)CC=CC(C)=CC(=O)OC(C)C',
'CCOC(=O)CC',
'CSc1nc(NC(C)C)nc(NC(C)C)n1',
'CC(C#C)N(C)C(=O)Nc1ccc(Cl)cc1',
'Cc1cc2ccccc2cc1C']
接下来,我们需要从它们的 SMILES 格式来描述这些新的分子
from rdkit import Chem
mols = [Chem.MolFromSmiles(s) for s in smiles]
featurizer = dc.feat.ConvMolFeaturizer()
x = featurizer.featurize(mols)predicted_solubility = model.predict_on_batch(x)
predicted_solubility
因此,我们可以看到预测的溶解度值:
array([[-0.45654652],
[ 1.5316172 ],
[ 0.19090167],
[ 0.44833142],
[-0.32875094]], dtype=float32)
我们很容易看到 DeepChem 如何使上述两个用例变得非常容易,这可能需要一个人类化学家花很多时间来解决这些问题!
对于最后一部分,我们将看到一些可视化和查询技术作为 RDkit 的一部分,这是任何人在处理这种用例时都非常需要的。
智能字符串来查询分子结构
SMARTS 是前面描述的 SMILES 语言的扩展,可用于创建查询。
# To gain a visual understanding of compounds in our dataset, let's draw them using rdkit. We define a couple of helper functions to get startedimport tempfile
from rdkit import Chem
from rdkit.Chem import Draw
from itertools import islice
from IPython.display import Image, displaydef display_images(filenames):
"""Helper to pretty-print images."""
for file in filenames:
display(Image(file))def mols_to_pngs(mols, basename="test"):
"""Helper to write RDKit mols to png files."""
filenames = []
for i, mol in enumerate(mols):
filename = "%s%d.png" % (basename, i)
Draw.MolToFile(mol, filename)
filenames.append(filename)
return filenames
现在,让我们来看一个微笑的样本,并想象它的分子结构。
from rdkit import Chem
from rdkit.Chem.Draw import MolsToGridImage
smiles_list = ["CCCCC","CCOCC","CCNCC","CCSCC"]
mol_list = [Chem.MolFromSmiles(x) for x in smiles_list]
display_images(mols_to_pngs(mol_list))
这就是视觉结构是如何从微笑字符串形成的。
现在,假设我们想要查询具有三个相邻碳的微笑字符串。
query = Chem.MolFromSmarts("CCC")
match_list = [mol.GetSubstructMatch(query) for mol in
mol_list]
MolsToGridImage(mols=mol_list, molsPerRow=4,
highlightAtomLists=match_list)
我们看到,突出显示的部分,代表有三个相邻碳的化合物。
同样,让我们看看一些通配符查询和其他子结构查询选项。
query = Chem.MolFromSmarts("C*C")
match_list = [mol.GetSubstructMatch(query) for mol in
mol_list]
MolsToGridImage(mols=mol_list, molsPerRow=4,
highlightAtomLists=match_list)
query = Chem.MolFromSmarts("C[C,N,O]C")
match_list = [mol.GetSubstructMatch(query) for mol in
mol_list]
MolsToGridImage(mols=mol_list, molsPerRow=4,
highlightAtomLists=match_list)
因此,我们可以看到,选择性子查询也可以很容易地处理。
因此,这就把我们带到了本文的结尾。我知道这篇文章水平很高,专门针对对药物发现感兴趣的数据科学家和 ML 研究人员,尤其是在 Covid19 等现有疫情的时代。希望我能帮上忙!如果你在生物信息学或化学信息学方面有很强的背景,并希望进入数据科学领域,请通过这里提到的**中的任何选项联系我。继续关注:https://medium.com/@adib0073和我的网站:https://www.aditya-bhattacharya.net/了解更多!
DeepDow —深度学习的投资组合优化
DeepDow 是一个 Python 包,专注于在单次正向传递中执行资产分配的神经网络。
单前锋传球?
投资组合优化传统上是一个两步程序:
- 建立对证券未来表现的信念
- 根据这些信念寻找最优投资组合
两步程序的一个臭名昭著的例子(受 Markowitz 启发)是
- 预期收益估计 μ 和协方差矩阵σ
- 求解凸优化问题
通常,这两个步骤是完全分开的,因为它们需要不同的方法和不同的软件。
deepdow
绝对抛弃这种范式。它力求将上述两个步骤合二为一。基本思想是构建端到端的深度网络,输入最原始的特征(回报、交易量……)并输出资产配置。这种方法有多种好处:
- 超参数可以变成可训练的重量(即第二阶段的𝛾)
- 利用深度学习提取有用的特征进行分配,不需要技术指标
- 单一损失函数
核心理念
金融时间序列可以被视为一个三维张量,具有以下维度
- 时间
- 资产
- 指示器/通道
举一个具体的例子,我们可以研究多个纳斯达克股票(资产维度)的每日(时间维度)开盘价回报、收盘价回报和交易量(渠道维度)。形象地说,人们可以想象
通过固定一个时间步长(代表现在),我们可以将张量分成 3 个不相交的子张量
首先, x 代表所有关于过去和现在的知识。第二个张量 g 代表包含在不久的将来的信息,我们不能用它来做投资决策。最后, y 是市场的未来演变。现在可以沿着时间维度移动,并在每个时间步长应用相同的分解。这种生成数据集的方法称为滚动窗口。
现在我们关注一种特殊类型的神经网络,它输入 x 并返回所有资产的单个权重分配 w ,使得它们的总和为 1。换句话说,根据我们过去的知识, x 我们构建了一个投资组合, w 我们立即买入并持有一段时间。设 F 是带有参数𝜃的神经网络,下图代表高级预测管道。
难题的最后一块是损失函数的定义。在最一般的术语中,每样本损失 L 是输入 w 和 y 并输出实数的任何函数。然而,在大多数情况下,我们首先计算投资组合在时间范围内每个时间步的回报率 r ,然后应用一些汇总函数 S 如均值、标准差等。
网络层
好吧,但是我们如何构建这样的网络呢?不是硬编码一个单一的架构deepdow
实现强大的构建块(层),用户可以自己组装。两个最重要的图层组是
变形层
目标是从输入中提取特征。
- RNN
- 1D 卷积
- 时间扭曲
- …
分配层
给定输入张量,它们输出有效的资产分配。
- 可微凸优化(
cvxpylayers
)即 Markowitz - Softmax(稀疏和约束变量也是)
- 基于聚类的分配器
- …
一般的模式是创建一个由多个转换层组成的管道,最后是一个分配层。注意,几乎任何实值超参数都可以变成一个可学习的参数,甚至可以被某个子网络预测。
想了解更多?
如果这篇文章引起了你的兴趣,请随时查看下面的链接。
我将非常乐意回答任何问题。此外,建设性的批评或帮助发展是非常受欢迎的。
Deepfake 检测超级难!!!
脸书 Deepfake 检测挑战赛回顾与分析。
照片由 stock.adobe.com 斯塔夫罗斯授权
人工智能(AI)和云计算技术的最新进展导致了音频、视频和图像处理技术的快速发展。这种合成媒体内容通常被称为“deep fakes【1】”基于人工智能的工具可以以越来越可信的方式操纵媒体,例如通过复制一个公众人物的声音或将一个人的脸叠加在另一个人的身体上。
立法、政策、媒体素养和技术必须协同工作,为恶意使用 deepfakes 提供有效的补救措施。
用于减轻 deepfakes 影响的技术对策分为三类:媒体认证、媒体出处和 deepfake 检测。
媒体身份验证包括通过使用水印、媒体验证标记、签名和监管链记录来帮助证明整个媒体生命周期的完整性的解决方案。身份验证是防止对可信媒体进行欺骗性操作的最有效方法,因为它可以在整个内容生命周期中验证和跟踪完整性,或者在分发端点进行验证。
媒体出处包括提供关于媒体来源的信息的解决方案,或者在媒体本身中,或者作为媒体的元数据。反向媒体搜索也可以是一个有效的出处工具,一个特定媒体过去出现过的网站列表可以用来证明媒体的来源。出处和认证一起,可以提供重要的取证工具来帮助揭穿 deepfakes。
Deepfake 检测包括利用多模式检测技术来确定目标媒体是否被操纵或合成生成的解决方案。现有的检测技术可以大致分为手动和算法方法。手工技术包括人类媒体法医从业者,通常配备有软件工具。算法检测使用基于人工智能的算法来识别被操纵的媒体。
由于大多数 deepfakes 都是通过对抗性训练(GANs)创建的,因此 creator 算法规避基于人工智能的检测方法的能力将随着它们被引入新的检测系统而提高。如果创建者可以使用它,任何检测器都将有很短的保质期。
业内有一个广泛的共识,即 deepfake 检测可能在短期内解决问题,但从长远来看,实际的解决方案将是认证和出处技术,以及媒体素养。
我将在以后的文章中更详细地讨论技术对策。]
脸书 Deepfake 检测挑战赛(DFDC)结果
最好的模型在真实世界的数据上有 65%的准确率。这些结果增加了 deepfake 检测的难度,并强调了人工智能模型在减轻合成媒体威胁方面的局限性。
2019 年 9 月,脸书与微软、AWS、Partnership on AI 合作,在 Kaggle 宣布了 Deepfake 检测挑战赛( DFDC ),邀请研究人员开发 deepfake 检测算法。为了提供数据来训练潜在的算法,脸书雇佣了 3500 名演员来录制数千个视频,然后使用各种 deepfake cheapfake 创作技术对这些视频进行处理。总共向研究人员发布了 100,000 个原始和被操纵内容的视频剪辑,作为建立 deepfake 检测器算法的训练集。值得注意的是,这个数据集包括了比以前的训练数据集更多样化和包容性的演员。
挑战赛的提交于 3 月 31 日截止,脸书于 6 月 12 日宣布了比赛的结果。
超过 2000 名参与者提交了 35,000+个检测算法。性能最好的模型使用了谷歌的 EfficientNet 算法,这是一种高性能和可扩展的卷积神经网络 (CNN)。
脸书在这里发表了一篇详细介绍这场竞争的论文。
在 DFDC 的训练数据上,获胜团队的准确率达到了 82.56%。虽然这看起来很高,但同样的算法在不可预见的真实世界 deepfakes 中获得了 65.18%的精度* 。
DFDC 结果数据的主要观察结果:
- 约 65%的精度意味着系统识别为阳性(deepfakes)的 deepfakes 中有 35%是假阳性(不是 deepfakes)。被算法归类为 deepfakes 的 1/3 的 deepfakes 不是 deepfakes。
- 在 65%精度的算法中,召回率(或算法识别为真阳性的 deepfakes 的数量与数据集中实际 deepfakes 的数量相比的度量)约为 50%(请参见下面的精度召回率图表)。也就是说,该算法在 50%的情况下将真实视频识别为 deepfake(假阳性)。一半的时间算法不能识别一个深假。
- ROC(受试者操作特征)上的 AUC(曲线下面积)是~0.7,ROC 是真阳性率(TPR)和假阳性率(FPR)的图。获胜的算法并没有表现得特别好,相比之下,一个简单的模型,如扔硬币算法,可以实现 0.5[2]的 AUC。
DFDC 的结果增加了检测 deepfake 的难度。除了媒体识读措施之外,最有希望的技术对策仍然是认证和出处技术。
关于 AI 的伙伴关系(PAI)建议
PAI 在 2019 年末创建了 AI 和媒体完整性指导委员会,作为合作伙伴的正式机构,开发和建议加强错误/虚假信息解决方案的项目,包括检测操纵和合成内容。DFDC 是人工智能和媒体诚信指导委员会的第一个项目。他们发表了一份关于 DFDC 的重要经验的报告。
关于 Deepfake 检测的主要建议:
- 单靠检测无法解决信息完整性挑战。
- 检测应该结合真实世界例子和线索才有意义。
- 检测能力必须以易于理解的界面扩展到记者、事实审查员和民间社会团体。
- Deepfake 检测解决方案的开发面临着开源数据集和模型与阻止对手使用这些资源来改进 deep fake 之间的权衡。
- 在这个问题领域,我们需要一个有意义的多利益攸关方协作方法。
该报告是了解 deepfake 检测挑战和有效对策建议的重要资源。
DFDC 结果的技术分析
一些技术术语的词汇表和机器学习度量的快速指南。
真阳性(TP) : Deepfakes 被检测为 Deepfakes
真阴性(TN) :非 Deepfakes 检测为非 deepfakes。
假阳性(FP) :非 Deepfakes 检测为 deepfakes。
假阴性(FN) : Deepfakes 被检测为非 Deepfakes。
准确率:定义为找到的所有准确数据(TP+TN)与所有数据(TP+FP+TN+FN)的比值。对于 DFDC 上下文,由于类偏斜,不使用精度,而是使用加权精度。
DFDC 的精确测量:由于深度假检测(分类真阳性)比真阴性(非深度假阳性)更关键,并且由于类别偏斜,真实世界中假与真视频的不平衡,假阳性数字(非深度假阳性)将为任何模型提供高精确度。脸书创建了一个加权精度指标来衡量算法的有效性。将权重添加到假阳性以使假阳性标准化,从而使检测模型具有实际效用。
:也称为特异性,由算法分类出的所有阳性 deepfakes (TP)中的真阳性 deep fakes(TP)计算得出,包括假阳性,(TP+FP)。
精度= TP / (TP + FP)
由于 DFDC 模型的精度是 65%,这意味着系统识别为阳性的 deepfakes(deep fakes)中有 35%不是 deep fakes。这些算法有 35%的时候将非 deepfakes 错误分类为 deepfakes,这是非常高的。
回忆:也称为模型的敏感度,计算为真阳性(deepfakes)与数据集中所有真 deepfakes 的比值(TP + FN)。
召回= TP / (TP + FN)
根据下面 0.65 精度的图表,召回率约为 50%,这意味着最好的模型将真实视频归类为 deepfake 的概率为 50%。
F1 得分:理想情况下,我们想要一个没有误报(精度= 1)和漏报(召回= 1)的算法。因此,算法的性能通常由 F1 分数来衡量,F1 分数是精确度和召回率的调和平均值。根据域,您可以调整可接受的误报和漏报的阈值。像在晚期疾病分类场景中,假阴性可能具有可怕的后果,因此更高的召回(低假阴性)是期望的。对于垃圾邮件分类器,误报(错过重要邮件)可能是不可接受的,但误报(收到垃圾邮件)是可以的,因此他们可以同意较低的召回率但较高的精确度。
F1 得分= 2 (精度召回)/(精度+召回)
对于 DFDC 算法来说,F1 值(0.65 的精度和 0.5 的召回率)是 0.56,在我看来,这对于 DFDC 算法来说不是一个好的性能指标。该算法在假阳性和假阴性上都是错误的。
受试者操作者特征(ROC) 曲线:是真阳性率和假阳性率的曲线。曲线下面积(AUC)是算法性能的良好指示。我突出显示了 AUC。
精确召回曲线https://arxiv.org/abs/2006.07397
**ROC (TPR FPR 曲线)【https://arxiv.org/abs/2006.07397 **
喜欢吗? 随便给我买本书
参考文献:
【1】https://www . vice . com/en _ us/article/bjye 8a/Reddit-fake-porn-app-daisy-Ridley