Skip to content

Latest commit

 

History

History
1036 lines (593 loc) · 66 KB

01.md

File metadata and controls

1036 lines (593 loc) · 66 KB

一、深度学习–架构和框架

人工神经网络是一种计算系统,为我们提供了解决诸如图像识别到语音翻译等具有挑战性的机器学习任务的重要工具。 最近的突破,例如 Google DeepMind 的 AlphaGo 击败了最好的围棋玩家,或者卡内基梅隆大学的 Libratus 击败了世界上最好的职业扑克玩家,都证明了算法的进步。 这些算法像人类一样学习狭窄的智能,并达到超人水平的表现。 用通俗易懂的话说,人工神经网络是我们可以在计算机上编程的人脑的松散表示。 确切地说,这是受我们对人脑功能知识的启发而产生的一种方法。 神经网络的一个关键概念是创建输入数据的表示空间,然后在该空间中解决问题。 也就是说,从数据的当前状态开始扭曲数据,以便可以以不同的状态表示数据,从而可以解决有关的问题陈述(例如分类或回归)。 深度学习意味着多个隐藏的表示,即具有许多层的神经网络,可以创建更有效的数据表示。 每一层都会细化从上一层收到的信息。

另一方面,强化学习是机器学习的另一个方面,它是一种学习遵循一系列动作的任何类型的活动的技术。 强化学习智能体从环境中收集信息并创建状态表示; 然后执行一个导致新状态和报酬的动作(即来自环境的可量化反馈,告诉我们该动作是好是坏)。 这种现象一直持续到智能体能够将表现提高到超过特定阈值(即最大化奖励的期望值)为止。 在每个步骤中,可以随机选择这些动作,将其固定或使用神经网络进行监督。 使用深度神经网络对动作预测进行监督将打开一个新领域,称为深度强化学习。 这构成了 AlphaGo,Libratus 和人工智能领域中许多其他突破性研究的基础。

我们将在本章介绍以下主题:

  • 深度学习
  • 强化学习
  • TensorFlow 和 OpenAI Gym 简介
  • 强化学习中有影响力的研究人员和项目

深度学习

深度学习是指训练大型神经网络。 首先,让我们讨论神经网络的一些基本用例,以及即使这些神经网络已经存在数十年,为什么深度学习仍会引起如此激烈的争论。

以下是神经网络中监督学习的示例:

输入(x 输出(y 应用领域 建议的神经网络方法
房屋特征 房子的价格 房地产 在输出层中带有线性整流单元的标准神经网络
广告和点击广告的用户信息 是(1)或否(0) 在线广告 具有二分类的标准神经网络
图像对象 从 100 个不同的对象进行分类,即(1,2,.....,100) 照片标注 卷积神经网络(由于图像,即空间数据)
语音 文字笔录 语音识别 循环神经网络(因为两个输入输出都是序列数据)
英文 中文 机器翻译 循环神经网络(因为输入是序列数据)
图像,雷达信息 其他汽车的位置 自动驾驶 定制的混合/复杂神经网络

在本章的后续部分中,我们将详细介绍前面提到的神经网络,但是首先我们必须了解,根据问题陈述的目的使用了不同类型的神经网络。

监督学习是机器学习中的一种方法,其中,使用输入特征对及其对应的输出/目标值(也称为标签)来训练智能体。

传统的机器学习算法对于结构化数据非常有效,其中大多数输入特征都定义得很好。 对于非结构化数据(例如音频,图像和文本)而言,情况并非如此,其中数据分别是信号,像素和字母。 对于计算机而言,比结构化数据更难理解非结构化数据。 神经网络基于这种非结构化数据进行预测的能力是其普及并产生经济价值的关键原因。

首先,它是当前的规模,即数据,计算能力和新算法的规模,这正在推动深度学习的发展。 互联网已经过去了四十年,导致大量的数字足迹不断积累和增长。 在此期间,研究和技术发展帮助扩大了计算系统的存储和处理能力。 当前,由于这些繁重的计算系统和海量数据,我们能够验证过去三十年来在人工智能领域的发现。

现在,我们需要什么来实现深度学习?

首先,我们需要大量数据。

其次,我们需要训练一个相当大的神经网络。

那么,为什么不对少量数据训练大型神经网络呢?

回想一下您的数据结构课程,其中结构的用途是充分处理特定类型的值。 例如,您将不会在具有张量数据类型的变量中存储标量值。 类似地,鉴于大量数据,这些大型神经网络会创建不同的表示并开发理解模式,如下图所示:

请参考以下数据的图形表示与不同机器学习算法的表现的比较:

  1. 我们看到传统的机器学习算法的表现在一定时间后收敛,因为它们无法吸收超过阈值的数据量的不同表示形式。

  2. 检查图的左下角,靠近原点。 这是算法的相对顺序没有很好定义的区域。 由于数据量小,内部表示形式并没有那么明显。 结果,所有算法的表现指标都一致。 在此级别上,表现与更好的特征工程成正比。 但是这些手工设计的特征随着数据大小的增加而失败。 这就是深度神经网络的来历,因为它们能够从大量数据中捕获更好的表示。

因此,我们可以得出结论,不应该将深度学习架构应用于任何遇到的数据。 所获得数据的数量和种类表明要应用哪种算法。 有时,小数据通过传统的机器学习算法比深度神经网络更有效。

深度学习问题陈述和算法可以根据其研究和应用领域进一步细分为四个不同的部分:

  • 通用深度学习:密集连接的层或全连接网络

  • 序列模型:循环神经网络,长短期记忆网络,门控循环单元等

  • 空间数据模型(例如,图像):卷积神经网络,生成对抗网络

  • 其他:无监督学习,强化学习,稀疏编码等

当前,该行业主要由前三个部分驱动,但是人工智能的未来取决于第四部分的发展。 沿着机器学习的发展历程,我们可以看到直到现在,这些学习模型都将实数作为输出,例如电影评论(情感评分)和图像分类(类对象)。 但是现在,以及其他类型的输出也正在生成,例如,图像字幕(输入:图像,输出:文本),机器翻译(输入:文本,输出:文本)和语音识别(输入:音频, 输出:文本)。

人类水平的表现是必要的,并且通常应用于深度学习。 在一段时间内收敛到最高点之后,人员水平的准确率变得恒定。 这一点称为最佳错误率(也称为贝叶斯误差率,即对于任何随机结果分类器而言,最低的错误率)。

其背后的原因是由于数据中的噪声,许多问题在表现上都有理论上的限制。 因此,人员级别的准确率是通过进行误差分析来改进模型的好方法。 这是通过合并人为误差,训练集误差和验证集误差来估计偏差方差影响(即欠拟合和过拟合条件)来完成的。

数据规模,算法类型和表现指标是一组方法,可以帮助我们针对不同的机器学习算法确定改进水平。 因此,决定是否投资深度学习或采用传统机器学习方法的关键决策。

具有一些输入特征(下图中的三个)的基本感知器如下所示:

上图设置了神经网络的基本方法,即如果我们在第一层中有输入,而在第二层中有输出,则它看起来像。 让我们尝试解释一下。 这里:

  • X1X2X3是输入特征变量,即此处的输入维为 3(考虑到没有偏差变量)。

  • W1W2W3是与特征变量关联的相应权重。 当我们谈论神经网络的训练时,我们的意思是说权重的训练。 因此,这些构成了我们小型神经网络的参数。

  • 输出层中的函数是应用于从前一层接收的信息的聚合上的激活函数。 此函数创建一个与实际输出相对应的表示状态。 从输入层到输出层的一系列过程导致预测输出,称为正向传播。

  • 通过多次迭代,可以最小化激活函数的输出和实际输出之间的误差值。

  • 只有在我们将权重的值(从输出层到输入层)更改为可以使误差函数最小的方向时,才会使误差最小。 这个过程称为反向传播,因为我们正朝相反的方向发展。

现在,牢记这些基础知识,让我们进一步使用逻辑回归作为神经网络对神经网络进行神秘化,并尝试创建具有一个隐藏层的神经网络。

深度学习的激活函数

激活函数是人工神经网络的组成部分。 他们决定特定神经元是否被激活,即神经元接收到的信息是否相关。 激活函数对接收信号(数据)执行非线性变换。

我们将在以下各节中讨论一些流行的激活函数。

Sigmoid 函数

Sigmoid 是一种平滑且连续可微的函数。 这导致非线性输出。 Sigmoid 函数在这里表示:

请查看下图的 Sigmoid 函数观察结果。 该函数的范围是 0 到 1。观察函数的曲线,我们看到x值介于 -3 和 3 之间时,梯度非常高,但超出此范围则变得平坦。 因此,可以说这些点附近的x的微小变化将使 Sigmoid 函数的值产生较大的变化。 因此,函数目标是将 Sigmoid 函数的值推向极限。

因此,它被用于分类问题:

查看下面的 Sigmoid 函数的梯度,我们观察到取决于x的平滑曲线。 由于梯度曲线是连续的,因此很容易反向传播误差并更新参数Wb

Sigmoid 得到广泛使用,但其缺点是该函数趋于 +3 和 -3 平坦。 因此,无论何时函数落在该区域中,梯度都趋于接近零,并且我们的神经网络学习停止。

由于 Sigmoid 函数输出的值从 0 到 1,即全为正,因此它在原点周围是非对称的,并且所有输出信号都是正的,即具有相同的符号。 为了解决这个问题,已将 Sigmoid 函数缩放为 tanh 函数,我们将在下面进行研究。 而且,由于梯度导致的值很小,因此很容易遇到梯度消失的问题(我们将在本章稍后讨论)。

tanh 函数

Tanh 是围绕原点对称的连续函数。 它的范围是 -1 至 1。tanh 函数表示如下:

因此,输出信号将同时为正和负,从而增加了原点周围信号的隔离。 如前所述,它是连续的,也是非线性的,并且在所有点上都是可微的。 在下图中,我们可以在 tanh 函数的图中观察这些属性。 尽管是对称的,但它变得平坦,超过 -2 和 2:

现在看下面的 tanh 函数的梯度曲线,我们发现它比 Sigmoid 函数陡峭。 tanh 函数还具有梯度消失问题:

softmax 函数

softmax 函数主要用于处理分类问题,并且最好在输出层中使用,以输出输出类别的概率。 如前所述,在解决二进制逻辑回归时,我们看到 Sigmoid 函数只能处理两个类。 为了处理多类,我们需要一个可以为所有类生成值的函数,这些值遵循概率规则。 这个目标是通过 softmax 函数实现的,该函数将每个类别的输出缩小在 0 和 1 之间,然后将它们除以所有类别的输出总和:

例如,x ∈ {1, 2, 3, 4},其中x涉及四个类别。

然后,softmax 函数将得出结果(四舍五入到小数点后三位):

因此,我们看到了所有类别的概率。 由于每个分类器的输出都需要所有分类的概率值,因此 softmax 函数成为分类器外层激活函数的最佳候选者。

整流线性单元函数

整流线性单元(更称为 ReLU)是使用最广泛的激活函数:

ReLU 函数具有非线性的优势。 因此,反向传播很容易,因此可以堆叠由 ReLU 函数激活的多个隐藏层,其中对于x <= 0f(x) = 0,对于x > 0f(x) = x

ReLU 函数相对于其他激活函数的主要优势在于,它不会同时激活所有神经元。 这可以从前面的 ReLU 函数图中观察到,在图中我们可以看到,如果输入为负,则输出零,而神经元不会激活。 这导致网络稀疏,并且计算快速简便。

ReLU 的导数图,对于x <= 0f'(x) = 1,对于x > 0f'(x) = 0

查看前面的 ReLU 的前面的梯度图,我们可以看到该图的负侧显示了一个恒定的零。 因此,落入该区域的激活将具有零梯度,因此权重将不会更新。 这将导致节点/神经元不活动,因为它们将不会学习。 为了解决这个问题,我们提供了泄漏的 ReLU,将其修改为:

这防止了梯度在负侧变为零,并且由于a的值较低,权重训练持续但缓慢地进行。

如何选择正确的激活函数

激活函数取决于问题陈述的目的和所关注的属性。 一些推断如下:

  • Sigmoid 函数在浅层网络和二分类器的情况下效果很好。 较深的网络可能会导致梯度消失。

  • ReLU 函数是使用最广泛的函数,请尝试使用 Leaky ReLU 以避免神经元死亡的情况。 因此,从 ReLU 开始,如果 ReLU 无法提供良好的结果,则移至另一个激活函数。

  • 在外层使用 softmax 进行多类分类。

  • 避免在外层使用 ReLU。

作为神经网络的逻辑回归

逻辑回归是一种分类器算法。 在这里,我们尝试预测输出类别的概率。 具有最高概率的类别将成为预测输出。 使用交叉熵计算实际输出和预测输出之间的误差,并通过反向传播将其最小化。 检查下图,了解二进制逻辑回归和多类逻辑回归。 区别基于问题陈述。 如果输出类的唯一数量为两个,则称为二分类;如果输出类的唯一数量为两个以上,则称为多类分类。 如果没有隐藏层,我们将 Sigmoid 函数用于二分类,并获得用于二进制逻辑回归的架构。 类似地,如果没有隐藏层,并且我们使用 softmax 函数进行多类分类,则可以得到多类逻辑回归的架构。

现在出现一个问题,为什么不使用 Sigmoid 函数进行多类逻辑回归?

对于任何神经网络的所有预测输出层而言,答案都是正确的,即预测输出应遵循概率分布。 正常来说,输出具有N个类别。 对于具有例如d维的输入数据,这将导致N个概率。 因此,此一个输入数据的N概率之和应为 1,并且这些概率中的每一个应在 0 到 1 之间(含 0 和 1)。

一方面,在大多数情况下,N个不同类别的 Sigmoid 函数之和可能不为 1。 因此,在二进制的情况下,使用 Sigmoid 函数来获得一个类别的概率,即p(y = 1 | x),而对于另一个类别,则是概率,即p(y = 0 | x) = 1 - p(y = 1 | x)。 另一方面,softmax 函数的输出是满足概率分布属性的值。 在图中,σ指的是 Sigmoid 函数:

还会出现一个后续问题:如果在二进制逻辑回归中使用 softmax 怎么办?

如前所述,只要您的预测输出遵循概率分布规则,一切都会很好。 稍后,我们将讨论交叉熵以及概率分布作为解决任何机器学习问题(尤其是处理分类任务)的基础的重要性。

如果分布中所有值的概率在 0 到 1 之间(含 0 和 1)且所有这些概率的总和必须为 1,则该概率分布有效。

逻辑回归可以在很小的神经网络中查看。 让我们尝试逐步实现二进制逻辑回归,如下所示:

符号

假设数据的格式为(x^(i), y^(i)),其中:

  • x^(i) ∈ Ry^(i) ∈ {0, 1}(类数为 2,因为它是二分类)

  • x^(i)n维,即x^(i) = {x[1]^(i), x[2]^(i), ..., x[n]^(i)}(请参见上图)

  • 训练示例的数量是m。 因此,训练集如下所示:

    • m为训练数据集的大小。

    • 并且,由于x = {x[1], x[2], ..., x[m]},其中每个x^(i) = {x[1]^(i), x[2]^(i), ..., x[m]^(i)}

    • 因此,X是大小为n * m的矩阵,即特征数*训练示例数

    • Y = [y^(1), y^(2), ..., y^(m)]m个输出的向量,其中每个y^(i) ∈ {0, 1}

    • 参数:权重W ∈ R和偏差b ∈ RW = {W[1], W[2], ..., W[n]},其中W[i]b是标量值。

目的

任何监督分类学习算法的目的都是以较高的概率预测正确的类别。 因此,对于每个给定的x^(i),我们必须计算预测的输出,即概率y_hat^(i) = P(y^(i) = 1 | x^(i))。 因此,y_hat^(i) ∈ [0, 1]

参考上图中的二进制逻辑回归:

  • 预测的输出,即y_hat^(i) = σ(Wx^(i) + b)。 在此,Sigmoid 函数将Wx^(i) + b的值缩小为 0 到 1。

  • 这意味着,当Wx^(i) + b -> +∞时,Sigmoid 函数,即σ(Wx^(i) + b) -> 1

  • Wx^(i) + b -> -∞时,它的 Sigmoid 函数即σ(Wx^(i) + b) -> 0

一旦我们计算出y_hat,即预测的输出,就完成了前向传播任务。 现在,我们将使用成本函数计算误差值,并尝试通过梯度下降来更改参数Wb的值,从而反向传播以最小化误差值。

成本函数

代价函数是一个度量,它确定关于实际训练输出和预测输出执行的机器学习算法的好坏。 如果您还记得线性回归,其中误差平方和用作损失函数,即L(y^(i), y_hat^(i)) = 1/2 (y^(i) - y_hat^(i))²。 这在凸曲线上效果更好,但是在分类的情况下,曲线是非凸曲线; 结果,梯度下降效果不好,也不会趋于全局最优。 因此,我们使用交叉熵损失作为成本函数,它更适合分类任务。

交叉熵作为损失函数(对于第i个输入数据),即:

其中C表示不同的输出类别。因此,成本函数=平均交叉熵损失(对于整个数据集),即:

在二元逻辑回归中,输出类别只有两个,即 0 和 1,因为类别值的总和始终为 1。因此(对于第i个输入数据),如果一个类别为y^(i),则其他输出类别将是1 - y^(i)。 类似地,由于类别y^(i)的概率为y_hat^(i)(预测),因此另一类别(即1 - y^(i))的概率将为1 - y_hat^(i)

因此,损失函数修改为:

其中:

  • 如果y^(i) = 1,即L(y^(i), y_hat^(i)) = -log y_hat^(i)。 因此,为了使L最小化,y_hat^(i)应该较大,即接近 1。

  • 如果y^(i) = 0,即L(y^(i), y_hat^(i)) = -log(1 - y_hat^(i))。 因此,为了使L最小化,y_hat^(i)应该较小,即接近于 0。

损失函数适用于单个示例,而成本函数适用于整个训练批量。 因此,这种情况下的成本函数为:

梯度下降算法

梯度下降算法是一种使用一阶导数查找函数最小值的优化算法,也就是说,我们仅将函数的参数微分为一阶。 在此,梯度下降算法的目的是使关于Wb的成本函数J(W, b)最小化。

此方法包括以下步骤,可进行多次迭代以最小化J(W, b)

上式中使用的α是指学习率。 学习率是学习智能体适应新知识的速度。 因此,α,即学习率是需要作为标量值或时间函数分配的超参数。 这样,在每次迭代中,Wb的值都按照上式进行更新,直到成本函数的值达到可接受的最小值为止。

梯度下降算法意味着沿斜率向下移动。 曲线的斜率由关于参数的成本函数J表示。 斜率(即斜率)给出了正斜率(如果为正)和负斜率的方向。 因此,我们必须使用负号与斜率相乘,因为我们必须与增加斜率的方向相反并朝减小斜率的方向相反。

使用最佳学习率α,可以控制下降,并且我们不会过度降低局部最小值。 如果学习率α非常小,那么收敛将花费更多时间,而如果学习率α非常高,则由于迭代次数众多,它可能会过冲并错过最小值和偏差:

计算图

基本的神经网络由前向传播和后向传播组成。 结果,它由一系列步骤组成,这些步骤包括不同节点,权重和偏差的值,以及所有权重和偏差的成本函数导数。 为了跟踪这些过程,图片中出现了计算图。 无论神经网络的深度如何,计算图还可以跟踪链式规则的微分。

使用梯度下降法解决逻辑回归的步骤

将我们刚刚介绍的所有构建模块放在一起,让我们尝试解决具有两个输入特征的二进制逻辑回归。

计算的基本步骤是:

  1. 计算Z^(i) = WX^(i) + b, ∀i

  2. 计算y_hat^(i) = σ(Z^(i)), ∀i,预测输出

  3. 计算成本函数:

假设我们有两个输入特征,即二维和m样本数据集。 因此,将是以下情况:

  1. X = {x[1], x[2]}

  2. 权重W = {w[1], w[2]}和偏差b

  3. 因此,z^(i) = w[1]x[1]^(i) + w[2]x[2]^(i) + by_hat^(i) = σ(z^(i))

  4. 计算J(W, b)(所有示例的平均损失)

  5. 计算关于w[1]w[2]b的导数,分别为∂J/∂w[1]∂J/∂w[2]∂J/∂b

  6. 按照前面的梯度下降部分所述修改w[1]w[2]b

先前m个样本数据集的伪代码为:

  1. 初始化学习率α和周期数e的值
  2. 循环遍历多个周期e(每次完整的数据集将分批通过)
  3. J(成本函数)和b(偏差)初始化为 0,对于W1W2,您可以使用随机正态或 xavier 初始化(在下一节中说明)

在此,ay_hatdw1∂J/∂w[1]dw2∂J/∂w[2]db∂J/∂b。 每个迭代都包含一个循环遍历m个示例的循环。

这里给出了相同的伪代码:

w1 = xavier initialization, w2 = xavier initialization, e = 100, α = 0.0001
for j1 to e :
     J = 0, dw1 = 0, dw2 = 0, db = 0
     for i1 to m :
         z = w1x1[i] + w2x2[i] + b
         a = σ(z)
         J = J - [ y[i] log a + (1-y) log (1-a) ]
         dw1 = dw1 + (a-y[i]) * x1[i] 
         dw2 = dw2 + (a-y[i]) * x2[i]
         db = db + (a-y[i])
     J = J / m
     dw1 = dw1 / m
     dw2 = dw2 / m
     db = db / m
     w1 = w1 - α * dw1
     w2 = w2 - α * dw2 

什么是 Xavier 初始化?

Xavier 初始化是神经网络中权重的初始化,是遵循高斯分布的随机变量,其中方差var(W)

其中,n_in是当前层中的单元数,即传入的信号单元,n_out是下一层中的单元数,即传出的结果信号单元。 简而言之,n_in * n_outW的形状。

为什么我们使用 xavier 初始化?

以下因素要求应用 xavier 初始化:

  • 如果网络中的权重开始很小,则大多数信号将收缩并在随后的层中激活函数处于休眠状态

  • 如果权重开始很大,则大多数信号将大量增长并通过后面各层的激活函数

因此,xavier 初始化有助于产生最佳权重,以使信号在最佳范围内,从而使信号变得既不会太小也不会太大的机会最小。

前述公式的推导超出了本书的范围。 请随时在此处进行搜索,并进行推导以获得更好的理解。

神经网络模型

神经网络模型类似于前面的逻辑回归模型。 唯一的区别是在输入层和输出层之间添加了隐藏层。 让我们考虑使用单个隐藏层神经网络进行分类,以了解该过程,如下图所示:

在这里,第 0 层是输入层,第 1 层是隐藏层,第 2 层是输出层。 这也称为两层神经网络,这是由于以下事实:当我们计算神经网络中的层数时,我们并不将输入层视为第一层。 因此,将输入层视为第 0 层,然后连续的层将获得第 1 层,第 2 层的表示法,依此类推。

现在,想到一个基本问题:为什么输入和输出层之间的层称为隐藏层?

这是因为在训练集中不存在隐藏层中节点的值。 如我们所见,在每个节点上都会进行两次计算。 这些是:

  • 汇总来自先前各层的输入信号

  • 对聚合信号进行激活以创建更深层的内部表示,这些表示又是相应隐藏节点的值

参考上图,我们有三个输入特征x[1], x[2], x[3]。 显示值为 1 的节点被视为偏置单元。 除输出外,每一层通常都有一个偏置单元。 偏置单元可以看作是一个拦截项,在左右激活函数中起着重要作用。 请记住,隐藏层和其中的节点的数量是我们一开始定义的超参数。 在这里,我们将隐藏层数定义为 1,将隐藏节点的数数定义为 3,a[1], a[2], a[3]。 因此,可以说我们有三个输入单元,三个隐藏单元和三个输出单元(h[1], h[2], h[3],因为我们要预测的类别是三类)。 这将为我们提供与层关联的权重和偏差的形状。 例如,第 0 层具有 3 个单元,第 1 层具有 3 个单元。与第i层相关联的权重矩阵和偏差向量的形状如下:

因此,形状如下:

  • w[0, 1]将是3x3b[0, 1]将是3

  • w[1, 2]将是3x1b[1, 2]将是1

现在,让我们了解以下符号:

  • w[a(i)]^d(i+1):此处,是指将第i层中的节点a连接到第i + 1层中的节点d的权重值

  • b[i, i+1]^d:此处,它是指将第i层中的偏置单元节点连接到第i + 1层中的节点d的偏置值。

因此,可以通过以下方式计算隐藏层中的节点:

其中,f函数是指激活函数。 记住逻辑回归,其中我们分别使用 Sigmoid 和 softmax a 激活函数进行二进制和多类逻辑回归。

类似地,我们可以这样计算输出单元:

这使我们结束了正向传播过程。 我们的下一个任务是通过反向传播训练神经网络(即训练权重和偏差参数)。

令实际输出类别为y[1], y[2], y[3]

回顾线性回归中的成本函数部分,我们使用交叉熵来表示成本函数。 由于成本函数定义为

其中,C = 3y[c] = Y[c], y_hat[c] = h[c]m为示例数

由于这是一个分类问题,因此对于每个示例,输出将只有一个输出类别为 1,其余的将为零。 例如,对于i,它将是:

因此,成本函数为:

现在,我们的目标是针对Wb将成本函数J最小化。 为了训练我们给定的神经网络,首先随机初始化Wb。 然后,我们将尝试通过梯度下降来优化J,在此我们将以以下方式以学习率α相应地更新Wb

设置好此结构后,我们必须重复执行这些优化步骤(更新Wb),以进行多次迭代以训练我们的神经网络。

这将我们带到了神经网络基础的结尾,它构成了任何浅或深的神经网络的基本构建块。 我们的下一个前沿将是了解一些著名的深度神经网络架构,例如循环神经网络RNN)和卷积神经网络CNN)。 除此之外,我们还将介绍基准的深度神经网络架构,例如 AlexNet,VGG-net 和 Inception。

循环神经网络

循环神经网络,缩写为 RNN,用于序列数据的情况下,无论是作为输入,输出还是两者。 RNN 之所以如此有效,是因为它们的架构可以汇总来自过去数据集的学习,并将其与新数据一起使用以增强学习。 这样,它可以捕获事件的顺序,这在前馈神经网络或统计时间序列分析的早期方法中是不可能的。

考虑时间序列数据,例如股票市场,音频或视频数据集,其中事件的顺序非常重要。 因此,在这种情况下,除了从整个数据中进行集体学习之外,从时间上遇到的数据中学习的顺序也很重要。 这将有助于捕捉潜在趋势。

执行基于序列的学习的能力是使 RNN 高效的原因。 让我们退后一步,尝试了解问题所在。 考虑以下数据图:

假设您有一系列事件,类似于图中的事件,并且您希望在每个时间点都按照事件序列进行决策。 现在,如果您的序列相当稳定,则可以在任何时间步长使用具有相似权重的分类器,但这就是小故障。 如果您以不同的时间步长数据分别运行同一分类器,则对于不同的时间步长,它不会训练为相似的权重。 如果在包含所有时间步数据的整个数据集上运行单个分类器,则权重将相同,但是基于序列的学习会受到阻碍。 对于我们的解决方案,我们希望在不同的时间步长上共享权重,并利用到最后一个时间步长所学到的知识,如下图所示:

根据问题,我们已经了解到我们的神经网络应该能够考虑过去的经验。 可以在前面的示意图中看到这一概念,在第一部分中,它表明在每个时间步长上,网络训练权重都应考虑从过去学习的数据,而第二部分给出解决方案。 我们使用前一个时间步的分类器输出的状态表示作为输入,并使用新的时间步数据来学习当前状态表示。 状态表示可以定义为递归直到最后一个步骤为止所发生事件的集体学习(或总结)。 状态不是分类器的预测输出。 相反,当它受到 softmax 激活函数时,它将产生预测的输出。

为了回想起更远的地方,将需要更深的神经网络。 取而代之的是,我们将使用一个汇总过去的模型,并将该信息以及新信息提供给分类器。

因此,在循环神经网络中的任何时间步长t处,都会发生以下计算:

  • W[h]b[h]是随时间共享的权重和偏差。

  • tanh是激活函数f

  • [h[t-1]; x[t]]指这两个信息的连接。 假设您的输入x[t]的形状为nxd,即n样本/行和d尺寸/列,h[t-1]n*l。 然后,您的连接将得到形状为n*(d+l)的矩阵。

由于任何隐藏状态h[i]的形状为n*l。 因此,W[h]的形状为(d+l)*lb[h]的形状为l

以来,

在给定的时间步长t中,这些操作构成 RNN 信元单元。 让我们在时间步t可视化 RNN 单元,如下所示:

一旦完成计算直到最后一个时间步,我们的前向传播任务就完成了。 下一个任务是通过反向传播来训练我们的循环神经网络,以使总损失最小化。 一个这样的序列的总损失是所有时间步长上损失的总和,也就是说,给定X值序列及其对应的Y值输出序列,损失如下:

因此,包含m个示例的整个数据集的成本函数为(其中k表示第k个示例):

由于 RNN 合并了序列数据,因此反向传播会随时间扩展到反向传播。 在此,时间是一系列相互连接的有序时间步长,从而可以通过不同的时间步长进行反向传播。

长短期记忆网络

RNN 实际上无法处理长期依赖项。 随着输出序列中的输出数据点与输入序列中的输入数据点之间的距离增加,RNN 无法在两者之间连接信息。 这通常发生在基于文本的任务中,例如机器翻译,音频到文本,以及序列长度较长的更多任务。

长短期记忆网络也称为 LSTM(由 Hochreiter 和 Schmidhuber 引入),能够处理这些长期依赖性。 看一下此处给出的图像:

LSTM 的关键特征是单元状态C[t]。 这有助于信息保持不变。 我们将从遗忘门层f[t]开始,该层将最后一个隐藏状态,h[t-1]x[t]的连接作为输入,并训练一个神经网络,该神经网络对于其中的每个数字得出 0 到 1 之间的数字。 最后一个单元格状态C[t-1],其中 1 表示保留该值,0 表示忘记该值。 因此,该层将识别过去要忘记的信息,并保留哪些信息。

接下来,我们进入输入门层i[t]和 tanh 层C_tilde[t],它们的任务是确定要添加到过去接收到的信息中的新信息以更新信息,即单元状态。 tanh 层创建新值的向量,而输入门层则标识用于信息更新的那些值中的哪一个。 将此新信息与使用“遗忘门”层f[t]保留的信息结合起来以更新我们的信息,即单元状态C[t]

=

因此,新的单元状态C[t]为:

最后,在输出门控层o[t]训练一个神经网络,返回单元状态C[t]的哪些值作为隐藏状态h[t]输出:

因此,LSTM 单元合并了最后一个单元状态C[t-1],最后一个隐藏状态h[t-1]和当前时间步输入x[t],并输出了更新后的单元状态C[t]和当前隐藏状态h[t]

LSTM 是一项突破,因为人们可以通过将 RNN 合并为单元单元来对 RNN 的显着结果进行基准测试。 这是朝着解决与长期依赖有关的问题迈出的重要一步。

卷积神经网络

卷积神经网络或卷积神经网络是在计算机视觉中提供成功结果的深度神经网络。 它们的灵感来自动物视皮层中神经元的组织和信号处理,也就是说,单个皮层神经元会对其相关小区域(视野)中的刺激做出反应,称为感受域 ,并且不同神经元的这些感受域完全重叠,覆盖了整个视野。

当输入空间中的输入包含相同类型的信息时,我们将共享权重并针对这些输入共同训练这些权重。 对于空间数据(例如图像),这种权重共享会导致 CNN。 同样,对于序列数据(例如文本),我们目睹了 RNN 中的这种权重共享。

CNN 在计算机视觉和自然语言处理领域具有广泛的应用。 就行业而言,Facebook 在其自动图像标记算法中使用了它,在图像搜索中使用了 Google,在产品推荐系统中使用了亚马逊,对家用提要进行个性化的 Pinterest,以及用于图像搜索和推荐的 Instagram。

就像神经网络中的神经元(或节点)从最后一层接收输入信号的加权聚合一样,最后一层接受激活函数导致输出。 然后我们反向传播以最小化损失函数。 这是应用于任何类型的神经网络的基本操作,因此适用于 CNN。

与输入为向量形式的神经网络不同,CNN 的输入图像是多通道的,即 RGB(三个通道:红色,绿色和蓝色)。 假设有一个像素大小为a×b的图像,则实际张量表示将为a×b×3形状。

假设您的图片与此处显示的图片相似:

它可以表示为具有宽度,高度的平板,并且由于具有 RGB 通道,因此其深度为 3。 现在,拍摄此图像的小片段,例如2×2,并在其上运行一个微型神经网络,其输出深度为k。 这将导致形状为1×1×k的图形表示。 现在,在不改变权重的情况下在整个图像上水平和垂直滑动此神经网络,将生成另一幅宽度,高度和深度为k的图像(也就是说,现在有k个通道)。

这种整合任务统称为卷积。 通常,ReLU 在以下神经网络中用作激活函数:

在这里,我们将 3 个特征映射(即 RGB 通道)映射到k个特征映射

斑块在图像上的滑动运动称为步幅,而每次移动的像素数(水平或垂直)都称为步幅。 如果补丁没有超出图像空间,则将其视为有效填充。 另一方面,如果色块超出图像空间以映射色块大小,则在该空间之外的色块像素将填充零。 这称为相同填充

CNN 架构由一系列这些卷积层组成。 如果这些卷积层中的跨步值大于 1,则会导致空间缩小。 因此,步幅,斑块大小和激活函数成为超参数。 除卷积层外,有时还会添加一个重要的层,称为池化层。 这将附近的所有卷积合并起来。 池化的一种形式称为最大池化

在最大池中,特征映射会查看补丁中的所有值,并返回其中的最大值。 因此,池大小(即池补丁/窗口大小)和池跨度是超参数。 下图描述了最大池化的概念:

最大池化通常会产生更准确的结果。 类似地,我们具有平均池化,其中取最大值而不是取池窗口中值的平均值,以提供特征映射的低分辨率视图。

通过合并和全连接层来操纵卷积层的超参数和排序,已经创建了许多不同的 CNN 变体,这些变体正在研究和工业领域中使用。 其中一些著名的是 LeNet-5,Alexnet,VGG-Net 和 Inception 模型。

LeNet-5 卷积神经网络

LeNet-5 的架构,来自 LeCunn 等人的《用于文档识别的基于梯度的学习》

LeNet-5 是一个七级卷积神经网络,由 Yann LeCunn,Yoshua Bengio,Leon Bottou 和 Patrick Haffner 于 1998 年组成的团队发布,对数字进行了分类,银行将其用于识别支票上的手写数字。 这些层按以下顺序排序:

  • 输入图片 -> 卷积层 1(ReLU) -> 池化 1 -> 卷积层 2(ReLU) -> 池化 2 -> 全连接(ReLU)1 -> 全连接 2 -> 输出
  • LeNet-5 取得了令人瞩目的结果,但是处理高分辨率图像的能力需要更多的卷积层,例如在 AlexNet,VGG-Net 和 Inception 模型中。

AlexNet 模型

AlexNet 是 LeNet 的一种改进,由 SuperVision 小组设计,该小组由 Alex Krizhevsky,Geoffrey Hinton 和 Ilya Sutskever 组成。 在 2012 年 ImageNet 大规模视觉识别挑战赛中,AlexNet 的前 5 位错误率达到 15.3%,比第二名高出 10 个百分点,创造了历史记录。

该架构使用五个卷积层,三个最大池化层和最后三个全连接层,如下图所示。 该模型总共训练了 6000 万个参数,训练了 120 万张图像,在两个 NVIDIA GTX 580 3GB GPU 上花费了大约五到六天的时间。 下图显示了 AlexNet 模型:

Hinton 等人《用于 ImageNet 分类的深度卷积神经网络的 AlexNet 架构》

卷积层 1 -> 最大池化层 1 -> 归一化层 1 -> 卷积层 2 -> 最大池化层 2 -> 归一化层 2 -> 卷积层 3 -> 卷积层 4 -> 卷积层 5 -> 最大池化层 3 -> 全连接 6 -> 全连接 7 -> 全连接 8 -> 输出

VGG-Net 模型

VGG-Net 由牛津大学视觉几何组VGG)的 Karen Simonyan 和 Andrew Zisserman 引入。 他们使用大小为3 x 3的小型卷积过滤器训练深度为 16 和 19 的网络。他们的团队分别在 ImageNet Challenge 2014 的本地化和分类任务中获得了第一和第二名。

通过向模型添加更多非线性来设计更深层的神经网络的想法导致合并了较小的过滤器,以确保网络没有太多参数。 在训练时,很难收敛模型,因此首先使用预先训练的简单神经网络模型来初始化较深架构的权重。 但是,现在我们可以直接使用 xavier 初始化方法,而无需训练神经网络来初始化权重。 由于模型的深度,训练起来很慢。

Inception 模型

Inception 由 Google 团队于 2014 年创建。其主要思想是创建更广泛的网络,同时限制参数数量并避免过拟合。 下图显示了完整的 Inception 模块:

Szegedy 等人的《从卷积开始深入研究》

它为单个输入应用多个卷积层,并输出每个卷积的堆叠输出。 使用的卷积大小主要为1x13x35x5。 这种架构允许您从相同大小的输入中提取多级特征。 早期版本也称为 GoogLeNet,该版本在 2014 年赢得了 ImageNet 挑战。

深度学习的局限性

深度神经网络是权重和偏置的黑盒,它们经过大量数据训练,可以通过内部表示找到隐藏的模式。 对于人类来说这将是不可能的,即使有可能,那么可伸缩性也是一个问题。 每个神经可能都有不同的权重。 因此,它们将具有不同的梯度。

训练在反向传播期间进行。 因此,训练的方向始终是从较后的层(输出/右侧)到较早的层(输入/左侧)。 与早期的层相比,这导致后面的层学习得很好。 网络越深入,情况恶化的程度就越大。 这引起了与深度学习相关的两个可能的问题,它们是:

  • 梯度消失问题
  • 梯度爆炸问题

梯度消失问题

当早期层中存在的神经元无法学习时,梯度梯度消失是与人工神经网络训练相关的问题之一,因为训练权重的梯度缩小到零。 这是由于神经网络的深度较大,加上带有导数的激活函数导致值较低。

请尝试以下步骤:

  1. 创建一个隐藏层神经网络
  2. 一层一层地添加更多隐藏层

我们观察了所有节点的梯度,发现当我们从后面的层移动到早期的层时,梯度值变得相对较小。 随着层数的增加,这种情况变得更糟。 这表明与后一层神经元相比,前一层神经元学习缓慢。 此条件称为梯度消失问题

梯度爆炸问题

梯度爆炸问题是与训练人工神经网络有关的另一个问题,当在早期层中存在的神经元的学习发生分歧时,因为梯度变得太大而导致权重发生严重变化,从而避免了收敛。 如果权重分配不正确,通常会发生这种情况。

在遵循针对梯度消失问题提到的步骤时,我们观察到梯度在早期层中爆炸,也就是说,它们变大了。 早期层发散的现象称为梯度爆炸问题

克服深度学习的局限性

这两个可能的问题可以通过以下方法克服:

  • 减少使用 Sigmoid 和 tanh 激活函数
  • 使用基于动量的随机梯度下降
  • 权重和偏差的正确初始化,例如 xavier 初始化
  • 正则化(将正则化损失与数据损失一起添加并最小化)

有关更多详细信息,以及消失和梯度爆炸的数学表示,您可以阅读本文:《智能信号:不稳定的深度学习,为什么以及如何解决它们》

强化学习

强化学习是人工智能的一个分支,它与以状态空间和动作空间的形式感知环境信息并作用于环境的主体进行处理,从而产生新的状态并获得作为该动作的反馈的奖励 。 该收到的奖励被分配给新状态。 就像当我们必须最小化成本函数以训练我们的神经网络时一样,在这里强化学习智能体必须最大化整体奖励以找到解决特定任务的最佳策略。

这与有监督和无监督学习有何不同?

在监督学习中,训练数据集具有输入特征X及其对应的输出标签Y。 在此训练数据集上训练一个模型,将具有输入特征X'的测试用例作为输入给出,并且模型预测Y'

在无监督学习中,为训练目的给出了训练集的输入特征X。 没有关联的Y值。 目标是创建一个模型,该模型可通过了解底层模式来学习将数据隔离到不同的群集中,从而对数据进行分类以找到某种用途。 然后将该模型进一步用于输入特征X',以预测它们与聚类之一的相似性。

强化学习与有监督的和无监督的都不同。 强化学习可以指导智能体如何在现实世界中行动。 接口比训练向量更广泛,例如在有监督或无监督学习中。 这是整个环境,可以是真实的世界也可以是模拟的世界。 智能体以不同的方式进行训练,即目标是达到目标状态,这与监督学习的情况不同,后者的目的是使可能性最大化或成本最小化。

强化学习智能体会自动从环境中获得反馈,即从环境中获得奖励,这与监督学习中的标注需要耗时的人力不同。 强化学习的更大优势之一是,以目标的形式表述任何任务的目标有助于解决各种各样的问题。 例如,视频游戏智能体的目标是通过获得最高分数来赢得比赛。 这也有助于发现实现目标的新方法。 例如,当 AlphaGo 成为围棋世界冠军时,它发现了新颖独特的取胜方法。

强化学习智能体就像人一样。 人类进化非常缓慢。 智能体可以增强力量,但它可以很快完成任务。 就感知环境而言,人类和人工智能智能体都无法立即感知整个世界。 感知环境创建了一种状态,在该状态中,智能体执行操作并落入新状态,即新感知的环境不同于早期环境。 这将创建一个既可以有限也可以无限的状态空间。

对此技术感兴趣的最大部门是国防。 强化学习智能体人可以代替不仅步行,还能战斗并做出重要决定的士兵吗?

基本术语和约定

以下是与强化学习相关的基本术语:

  • 智能体:我们是通过编程创建的,因此它能够感知环境,执行动作,接收反馈并尝试获得最大回报。
  • 环境:智能体程序所在的世界。 它可以是真实的或模拟的。
  • 状态:智能体感知的环境感知或配置。 状态空间可以是有限的或无限的。
  • 奖励:座席采取任何措施后收到的反馈。 智能体的目标是最大化整体奖励,即立即和将来的奖励。 奖励是预先定义的。 因此,必须正确创建它们才能有效实现目标。
  • 操作:智能体在给定环境中能够执行的任何操作。 动作空间可以是有限的或无限的。
  • SAR 三元组:(状态,动作,奖励)称为 SAR 三元组,表示为(s, a, r)
  • 剧集:代表整个任务的一次完整运行。

让我们推断下图所示的约定:

每个任务都是一系列的 SAR 三元组。 我们从状态S(t)开始,执行动作A(t),从而收到奖励R(t + 1),然后进入新状态S(t + 1)。 当前状态和动作对为下一步提供了奖励。 由于S(t)A(t)产生了S(t + 1),因此我们有了(当前状态,作用, 新状态),即[S(t), S(t), S(t + 1)](s, a, s')

最优标准

最优性标准是根据数据创建的模型的拟合优度的度量。 例如,在监督分类学习算法中,我们将最大似然性作为最优性标准。 因此,根据问题陈述和客观最优标准不同。 在强化学习中,我们的主要目标是最大化未来的回报。 因此,我们有两个不同的最优性标准,分别是:

  • 值函数:根据未来可能的回报来量化状态
  • 策略:指导智能体在给定状态下应采取的措施

我们将在接下来的主题中详细讨论这两个方面。

最优值函数

智能体应该能够考虑立即和未来的回报。 因此,还会为每个遇到的状态分配一个值,该值也反映了此将来的信息。 这称为值函数。 延迟奖励的概念来了,目前,现在采取的行动将导致未来的潜在奖励。

V(s),即状态的值定义为,从该状态到后续状态直到智能体到达目标状态之前,所有将来在该状态下将要收到的奖励的期望值。 基本上,值函数告诉我们处于这种状态有多好。 值越高,状态越好。

分配给每个(s, a, s')三元组的奖励是固定的。 状态值不是这种情况。 它会随着剧集中的每个动作以及不同剧集而变化。

我们想到一个解决方案,而不是值函数,为什么我们不存储每个可能状态的知识呢?

答案很简单:这既耗时又昂贵,而且成本成倍增长。 因此,最好存储当前状态的知识,即V(s)

V(s) = E[all future rewards discounted | S(t)=s]

关于值函数的更多详细信息将在第 3 章,“马尔可夫决策过程和部分可观察的 MDP”中进行介绍。

最优策略模型

策略被定义为指导智能体在不同状态下进行操作选择的模型。 策略被表示为ππ本质上是在特定状态下某种动作的概率:

因此,策略图将提供给定特定状态的不同操作的概率集。 该策略与值函数一起创建了一个解决方案,可根据策略和状态的计算值来帮助智能体导航。

强化学习的 Q 学习方法

Q 学习是尝试学习在特定状态下向智能体提供的特定操作的值Q(s, a)。 考虑一个表,其中行数代表状态数,而列数代表动作数。 这称为 Q 表。 因此,我们必须学习值,以找出对于给定状态下的智能体而言,哪种行动最合适。

Q 学习涉及的步骤:

  1. 用统一的值(例如全零)初始化Q(s, a)的表。

  2. 观察当前状态s

  3. 通过 ε 贪婪或任何其他动作选择策略选择一个动作a,然后采取该动作

  4. 结果,收到了a的奖励r,并且感知到了新状态s'

  5. 使用以下 Bellman 公式更新表中(s, a)对的Q值:

    其中γ是折扣因子。

  6. 然后,将当前状态的值设置为新状态,并重复该过程以完成一个剧集,即达到终端状态

  7. 运行多个剧集来训练智能体

为简化起见,我们可以说,给定状态s和动作a的 Q 值由当前奖励r以及新状态在其所有操作中的折扣(γ)最大Q最大值。 与当前奖励相比,折扣因子延迟了来自未来的奖励。 例如,今天的 100 奖励在将来值将超过 100。 同样,将来的 100 奖励的当前值必须不到 100。 因此,我们将折扣未来的奖励。 连续重复此更新过程会导致 Q 表值收敛到给定状态下给定操作的预期未来奖励的准确率量。

当状态空间和动作空间的数量增加时,很难维护 Q 表。 在现实世界中,状态空间无限大。 因此,需要另一种无需 Q 表即可生成Q(s, a)方法。 一种解决方案是用函数替换 Q 表。 该函数将状态作为向量形式的输入,并输出给定​​状态下所有动作的 Q 值向量。 该函数逼近器可以由神经网络表示,以预测 Q 值。 因此,当状态和动作空间变大时,我们可以添加更多的层并适合于深度神经网络,以更好地预测 Q 值,这对于 Q 表来说似乎是不可能的。 这样就产生了 Q 网络,如果使用了更深层的神经网络(例如卷积神经网络),那么它会导致深度 Q 网络DQN)。

有关 Q 学习和深度 Q 网络的更多详细信息,将在第 5 章, “Q 学习和深度 Q 网络”中进行介绍。

异步优势演员评论家

A3C 算法由 Google DeepMind 和 MILA 的联合团队于 2016 年 6 月发布。 它更简单并且具有更轻的框架,该框架使用异步梯度下降来优化深度神经网络。 它速度更快,并且能够在多核 CPU 而非 GPU 上显示出良好的结果。 A3C 的一大优势是它可以在连续动作空间和离散动作空间上工作。 结果,它为许多具有复杂状态和动作空间的新挑战性难题打开了门户。

我们将在此处重点讨论,但是我们将在第 6 章,“异步方法”中进行更深入的探讨。 让我们从名称开始,即异步优势演员评论家A3C)算法,然后将其解压缩以获得该算法的基本概述:

  • 异步:在 DQN 中,您还记得我们将神经网络与我们的智能体一起使用来预测动作。 这意味着只有一个智能体,并且它正在与一个环境交互。 A3C 所做的是创建智能体环境的多个副本,以使智能体更有效地学习。 A3C 具有一个全球网络和多个工作器智能体,其中每个智能体都有其自己的一组网络参数,并且每个参数都与其环境副本同时进行交互,而无需与另一个智能体的环境进行交互。 它比单个智能体更好的原因是每个智能体的经验独立于其他智能体的经验。 因此,所有工作器智能体的总体经验导致了各种各样的训练。
  • 演员评论家:演员评论家结合了值迭代和策略迭代的优势。 因此,网络将为给定状态 s 估计值函数V(s)和策略π(s)。 函数逼近器神经网络的顶部将有两个单独的全连接层,分别输出状态的值和状态策略。 智能体使用值,该值充当批评者来更新策略,即,智能角色。
  • 优势:策略梯度使用折扣收益告诉智能体该行动是好是坏。 用优势代替它不仅可以量化操作的好坏状态,而且可以更好地鼓励和劝阻操作(我们将在第 4 章,“策略梯度”中进行讨论)。

TensorFlow 和 OpenAI Gym 简介

TensorFlow 是 Google 的 Google Brain 团队创建的数学库。 由于其数据流编程,它已被用作研究和开发部门的深度学习库。 自 2015 年成立以来,TensorFlow 已发展成为一个非常庞大的社区。

OpenAI Gym 是一个由 OpenAI 团队创建的强化学习操场,旨在提供一个简单的接口,因为创建环境本身是强化学习中的繁琐任务。 它提供了一个很好的环境列表来测试您的强化学习算法,以便您可以对它们进行基准测试。

TensorFlow 中的基本计算

TensorFlow 的基础是我们在本章前面讨论过的计算图张量。 张量是 n 维向量。 因此,标量和矩阵变量也是张量。 在这里,我们将尝试从 TensorFlow 开始的一些基本计算。 请尝试在 python IDE(例如 Jupyter 笔记本)中实现本节。

有关 TensorFlow 的安装和依赖项,请参考以下链接

通过以下命令导入tensorflow

import tensorflow as tf

tf.zeros()tf.ones()是实例化基本张量的一些函数。 tf.zeros()采用张量形状(即元组),并返回该形状的张量,所有值均为零。 同样,tf.ones()采用张量形状,但返回仅包含一个形状的该张量。 在 python shell 中尝试以下命令来创建张量:

>>> tf.zeros(3)

<tf.Tensor 'zeros:0' shape=(3,) dtype=float32>

>>>tf.ones(3)

<tf.Tensor 'ones:0' shape=(3,) dtype=float32>

如您所见,TensorFlow 返回对张量的引用,而不是张量的值。 为了获得该值,我们可以通过运行会话来使用eval()run()(张量对象的函数):

>>> a = tf.zeros(3)
>>> with tf.Session() as sess:
        sess.run(a)
        a.eval()

array([0., 0.,0.], dtype=float32)

array([0., 0.,0.], dtype=float32)

接下来是tf.fill()tf.constant()方法,以创建具有一定形状和值的张量:

>>> a = tf.fill((2,2),value=4.)
>>> b = tf.constant(4.,shape=(2,2))
>>> with tf.Session() as sess:
        sess.run(a)
        sess.run(b)

array([[ 4., 4.],
[ 4., 4.]], dtype=float32)

array([[ 4., 4.],
[ 4., 4.]], dtype=float32)

接下来,我们有一些函数可以随机初始化张量。 其中,最常用的是:

  • tf.random_normal:从指定平均值和标准差的正态分布中采样随机值
  • tf.random_uniform():从指定范围的均匀分布中采样随机值
>>> a = tf.random_normal((2,2),mean=0,stddev=1)
>>> b = tf.random_uniform((2,2),minval=-3,maxval=3)
>>> with tf.Session() as sess:
        sess.run(a)
        sess.run(b)

array([[-0.31790468, 1.30740941],
[-0.52323157, -0.2980336 ]], dtype=float32)

array([[ 1.38419437, -2.91128755],
[-0.80171156, -0.84285879]], dtype=float32)

TensorFlow 中的变量是张量的持有者,并由函数tf.Variable()定义:

>>> a = tf.Variable(tf.ones((2,2)))
>>> a

<tf.Variable 'Variable:0' shape=(2, 2) dtype=float32_ref>

如果使用变量,则评估失败,因为必须在会话中使用tf.global_variables_initializer明确初始化它们:

>>> a = tf.Variable(tf.ones((2,2)))
>>> with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        a.eval()

array([[ 1., 1.],
[ 1., 1.]], dtype=float32)

队列中的下一个,我们有矩阵。 身份矩阵是对角线为 1 且其他位置为零的正方形矩阵。 这可以通过function tf.eye()完成:

>>> id = tf.eye(4) #size of the square matrix = 4
>>> with tf.Session() as sess:
         sess.run(id)

array([[ 1., 0., 0., 0.],
[ 0., 1., 0., 0.],
[ 0., 0., 1., 0.],
[ 0., 0., 0., 1.]], dtype=float32)

同样,也有对角矩阵,其对角线的值和其他地方的零,如下所示:

>>> a = tf.range(1,5,1)
>>> md = tf.diag(a)
>>> mdn = tf.diag([1,2,5,3,2])
>>> with tf.Session() as sess:
        sess.run(md)
        sess.run(mdn)

array([[1, 0, 0, 0],
[0, 2, 0, 0],
[0, 0, 3, 0],
[0, 0, 0, 4]], dtype=int32)

array([[1, 0, 0, 0, 0],
[0, 2, 0, 0, 0],
[0, 0, 5, 0, 0],
[0, 0, 0, 3, 0],
[0, 0, 0, 0, 2]], dtype=int32)

我们使用tf.matrix_transpose()函数对给定矩阵进行转置,如下所示:

>>> a = tf.ones((2,3))
>>> b = tf.transpose(a)
>>> with tf.Session() as sess:
        sess.run(a)
        sess.run(b)

array([[ 1., 1., 1.],
[ 1., 1., 1.]], dtype=float32)

array([[ 1., 1.],
[ 1., 1.],
[ 1., 1.]], dtype=float32)

下一个矩阵运算是矩阵乘法函数,如下所示。 这是通过函数tf.matmul()完成的:

>>> a = tf.ones((3,2))
>>> b = tf.ones((2,4))
>>> c = tf.matmul(a,b)
>>> with tf.Session() as sess:
        sess.run(a)
        sess.run(b)
        sess.run(c)

array([[ 1., 1.],
[ 1., 1.],
[ 1., 1.]], dtype=float32)

array([[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.]], dtype=float32)

array([[ 2., 2., 2., 2.],
[ 2., 2., 2., 2.],
[ 2., 2., 2., 2.]], dtype=float32)

使用tf.reshape()函数将张量从一个重塑为另一个,如下所示:

>>> a = tf.ones((2,4)) #initial shape is (2,4)
>>> b = tf.reshape(a,(8,)) # reshaping it to a vector of size 8\. Thus shape is (8,)
>>> c = tf.reshape(a,(2,2,2)) #reshaping tensor a to shape (2,2,2)
>>> d = tf.reshape(b,(2,2,2)) #reshaping tensor b to shape (2,2,2) 
#####Thus, tensor 'c' and 'd' will be similar
>>> with tf.Session() as sess:
        sess.run(a)
        sess.run(b)
        sess.run(c)
        sess.run(d)

array([[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.]], dtype=float32)

array([ 1., 1., 1., 1., 1., 1., 1., 1.], dtype=float32)

array([[[ 1., 1.],
[ 1., 1.]],
[[ 1., 1.],
[ 1., 1.]]], dtype=float32)
&gt;
array([[[ 1., 1.],
[ 1., 1.]],
[[ 1., 1.],
[ 1., 1.]]], dtype=float32)

TensorFlow 中的计算流程表示为一个计算图,作为tf.Graph的实例。 该图包含张量和操作对象,并跟踪涉及的一系列操作和张量。 图的默认实例可以通过tf.get_default_graph()获取:

>>> tf.get_default_graph()

<tensorflow.python.framework.ops.Graph object at 0x7fa3e139b550>

在接下来的章节中,我们将在 TensorFlow 中探索复杂的操作,神经网络的创建以及更多内容。

OpenAI Gym 简介

由 OpenAI 团队创建的 OpenAI Gym 是一个在不同环境中运动的场所,您可以在其中开发和比较强化学习算法。 它与 TensorFlow 和 Theano 等深度学习库兼容。

OpenAI Gym 由两部分组成:

  • Gym 开源代码库:它包含许多环境,可以解决不同的测试问题,您可以在其中测试您的强化学习算法。 这足以满足状态和操作空间的信息。
  • OpenAI Gym 服务:这使您可以将座席的表现与其他经过训练的座席进行比较。

有关安装和依赖项,请参考以下链接

在介绍了基础知识之后,现在我们将从下面的第 2 章“使用 OpenAI Gym 训练强化学习智能体”开始使用 OpenAI Gym 实现强化学习。

强化学习的先驱与突破

在继续进行所有编码之前,让我们阐明一些在深度强化学习领域中的先驱,行业领导者和研究突破。

David Silver

David Silver 博士的 H 指数为 30,是 Google DeepMind 强化学习研究团队的负责人,也是 AlphaGo 的首席研究员。 David 共同创立了 Elixir Studios,然后在艾伯塔大学获得了强化学习博士学位,在那里他共同介绍了第一个大师级9x9围棋程序中使用的算法。 此后,他成为伦敦大学学院的讲师。 在 2013 年加入全职之前,他曾为 DeepMind 担任顾问。David 领导了 AlphaGo 项目,该项目成为在围棋游戏中击败顶级职业玩家的第一个程序。

Pieter Abbeel

Pieter Abbeel 是加州大学伯克利分校的教授,也是 OpenAI 的研究科学家。 Pieter 在 Ng 的带领下完成了计算机科学博士学位。 他目前的研究重点是机器人技术和机器学习,尤其是深度强化学习,深度模仿学习,深度无监督学习,元学习,学习到学习和 AI 安全。 Pieter 还获得了 NIPS 2016 最佳论文奖。

Google DeepMind

Google DeepMind 是一家英国人工智能公司,成立于 2010 年 9 月,并于 2014 年被 Google 收购。它们是深度强化学习和神经图灵机领域的行业领导者。 当 AlphaGo 计划击败了 9 段围棋选手 Lee Sedol 时,他们在 2016 年发布了新闻。 Google DeepMind 已将重点转移到两个大领域:能源和医疗保健。

以下是其一些项目:

  • 2016 年 7 月,Google DeepMind 与 Moorfields 眼科医院宣布合作,使用眼部扫描技术研究导致失明的疾病的早期征兆
  • 2016 年 8 月,Google DeepMind 宣布与伦敦大学学院医院合作研究和开发一种算法,以自动微分头部和颈部的健康组织和癌性组织
  • Google DeepMind AI 将 Google 的数据中心散热费用降低了 40%

AlphaGo 程序

正如 Google DeepMind 先前所述,AlphaGo 是一种计算机程序,它首先击败了 Lee Sedol,然后击败了当时在围棋中排名世界第一的 Ke Jie。 在 2017 年的改进版本中,AlphaGo Zero 发布,击败了 AlphaGo 100 场比赛至 0 局。

Libratus

Libratus 是由卡内基梅隆大学的 Tuomas Sandholm 教授带领的团队设计的人工智能计算机程序,用于玩扑克。 Libratus 和它的前身克劳迪科有着相同的含义,平衡。

2017 年 1 月,它在一场为期 20 天的马拉松比赛中击败了世界上最好的四名职业扑克选手,创造了历史。

尽管 Libratus 专注于玩扑克,但其设计师提到了它能够学习任何信息不完整且对手参与欺骗的游戏的能力。 结果,他们提出该系统可以应用于网络安全,商务谈判或医疗计划领域中的问题。

总结

在本章中,我们涵盖了构建模块,例如包括逻辑回归的浅层和深度神经网络,单隐藏层神经网络,RNN,LSTM,CNN 及其其他变体。 针对这些主题,我们还介绍了多个激活函数,正向和反向传播的工作方式以及与深度神经网络训练相关的问题,例如消失和梯度爆炸。

然后,我们涵盖了强化学习中非常基本的术语,我们将在接下来的章节中对其进行详细探讨。 这些是最优标准,即值函数和策略。 我们还了解了一些强化学习算法,例如 Q 学习和 A3C 算法。 然后,我们在 TensorFlow 框架中介绍了一些基本计算,这是 OpenAI Gym 的简介,还讨论了强化学习领域的一些有影响力的先驱者和研究突破。

在下一章中,我们将对几个 OpenAI Gym 框架环境实现基本的强化学习算法,并更好地理解 OpenAI Gym。