本文为Python之 AI人工智能初学者指南第二章。
第一章通过DQN所使用的Q动作值函数来讲解了强化学习算法。其中代理是一个驱动。你已然处于AI的DeepMind方法的核心。
DeepMind无疑是应用人工智能的全球领先者。科学、数学和应用研究驱动着它的策略。
DeepMind成立于2010年,并于2014年被Google收购,现是Google整合后的母公司Alphabet的旗下公司。
DeepMind的一个研究重心是强化学习。他们推出一个强化学习的创新版本,称之为DQN,并使用Q函数(贝尔曼方程)来引用深度神经网络。《自然》杂志2015年2月所发表的一篇学术文章(本章结尾处有链接)显示了DQN是如何超越其它人工智能技术并将自己变成为人类游戏的玩家的。DQN随后又打败了真实的人类游戏玩家。
本章中,代理将成为一个自动化导航车辆(automated guided vehicle (AGV))。AGV接管一家仓库的运输任务。案例研究打开了使用DQN来工作和其商业性的一个美好前景。成千上万的仓库需要复杂的强化学习和自定义的运输优化。
本章着重讲解创建回报矩阵,这也是第一章中Python示例的entry point。要完成这一讲解,本章涵盖了如何在TensorFlow中加入原始的麦卡洛克-皮特斯神经元,来创建一个智能适配网络以及将N(网络)加入到Q模型中。这里讲的是小N,在第四章 成为一个打破惯例的创新者中将成为前馈神经网络。目标不是复制DQN,而是使用该模型的强大概念来创建各种解决方案。
本章的挑战是要真的像机器一样思考问题。我们不是致力于模仿人类的思维,而是通过机器来打败人类。本章会将你从人类推理带到遥远的机器思维的腹地。
本章将涵盖如下内容:
- AGV
- 麦卡洛克-皮特斯神经元
- 创建一个回报矩阵
- 逻辑分类器
- softmax函数
- 独热(one-hot)函数
- 如何在现实生活问题如仓库管理中应用机器学习工具
技术准备
- Python 3.6x 64位,官网地址:https://www.python.org/
- Python 3.6x的NumPy
- 来自https://deepmind.com/带有TensorBoard的TensorFlow
以下文件:
- https://github.com/alanhou/ai-beginners/blob/master/Chapter02/MCP.py
- https://github.com/alanhou/ai-beginners/blob/master/Chapter02/SOFTMAX.py
进入以下视频来查看代码实操:
设计数据集 – 梦想止步和体力活开始的地方
如同前面一章所说的,请记住现实生活中的项目经历着某种形式的三维方法。首先,思考并讨论要解决的问题而不是直接跳到电脑旁非常重要。完成了这一步后,请记住机器学习和深度学习的基础是依赖于数学的。最后,一旦讨论了问题并进行了数学展示,就是开发解决方案的时候了。
小贴士:首先,以自然语言来思考问题。然后对问题进行数学描述。只有到这时才开始软件实现。
在自然语言会议中设计数据集
第一章中所描述的强化学习项目可以解决牵涉在非监督决策过程中无标签分类的很多问题。Q函数可以无差异地用于无人机、卡车或汽车派送问题。它也可应用于游戏或现实生活的决策制定中。
但是,现实生活案例研究问题(比如为AGV定义仓库中的回报矩阵),困难在于设计一个大家一致认可的矩阵。
这表示与获取数据的 IT 部门、SME(主题专家)和强化学习专家的大量会议。AGV需要来自多个数据源的信息:日常预测和补时仓储流。
在某一点上,项目会止步不前。为强化学习项目获取正确的数据简直太复杂了。这一个是真实的案例研究,出于商业机密的原因我做了一点修改。
这个仓库管理数千个地点和成千上万个输入与输出。Q函数无法满足它自身的要求。需要一个小型神经网络。
最终,通过与 IT 部门和用户的艰难协商,数据集格式设计为满足强化学习项目的需求并有足够多的属性来满足AGV。
使用麦卡洛克-皮特斯神经元
数学方面依赖于找到一个集团仓库大数据量输入的模型。
在一种形式下,输入可描述如下:
- 数千个产品以低优先级权重预测到达:w1 = 10
- 数千个以高优先级权重确定到达:w2 = 70
- 数千个由销售部门决定的未计划到达:w3 = 75
- 数千个高优先级权重预测到达:w4 = 60
- 数千个低流转因此为低权重的确定到达:w5 = 20
这些权重以向量w展现:
$$w=\begin{bmatrix}w_{1}\\w_{2}\\w_{3}\\w_{4}\\w_{5}\\\end{bmatrix}
=\begin{bmatrix}10\\70\\75\\60\\20\\\end{bmatrix}$$
所有这些产品需要存储在最优的地点,各地距离将近100个码头并且AGV仓库的数千个地点需要达到最小化。
让我们聚焦在我们的神经元上。只会使用这些权重,虽然像这样的一个系统每个神经元会累加至50个以上的权重和参数。
在第一章中,回报矩阵的大小为6×6。描述了6个地点(A到F),现在六个地点(l1到 l6)会在体现在仓库中。
一个6×6的回报矩阵表现了为6个位置实施的麦卡洛克-皮特斯层目标。
同时,这一矩阵是第一章中的输入。现实生活和现实的公司中,你需要寻找一种方式来从头构建数据集。回报矩阵成为过程中这一部分的输出。如下源代码显示在第一章中使用的强化学习项目的输入。本章的目录是描述如何生成如下的回报矩阵。
1 2 3 4 5 6 7 |
# R 是仓库(或其它问题)中每个位置的回报矩阵 R = ql.matrix([ [0,0,0,0,1,0], [0,0,0,1,0,1], [0,0,100,1,0,0], [0,1,1,0,1,0], [1,0,0,1,0,0], [0,1,0,0,0,0] ]) |
就这一仓库问题,麦卡洛克-皮特斯神经元加总前述的优先级向量的权重来填入到回报矩阵中。
每个地点会要求带有权重的它的神经元.
INPUTS ➔ WEIGHTS ➔ BIAS ➔ VALUES
- 输入是仓库中物流或其它形式的数据
- 权重将在这一模型中定义
- 偏置量(Bias)用于稳定权重
- 值是它的输出
ℹ️你可以想到有很多方式来创建这些回报矩阵。本章描述了一种可以生效的一种方式。
麦卡洛克-皮特斯神经元(McCulloch-Pitts neuron)
麦卡洛克-皮特斯神经元可回溯到1943年。它包含输入、权重和一个激活函数 。对于这类问题正是你需要像机器一样思考并忘记人类神经科学脑部思考方式的时候。从第八章 为一些公司设计的变革以及小型到大型公司的颠覆式创新开始,人类认知将会建构在这些模型之上,它基础仍需保留为数学模型。
下图显示了麦卡洛克-皮特斯神经元模型:
这一模型包含一些输入x权重加总来到达一个阀值,在转换后产生y = 0或1的输出。在这个模型中,y会以更复杂的方式计算。
一个Python-TensorFlow程序,MCP.py 会用于描绘该神经元。
在设计神经元时,需要考虑计算性能。以下的源代码配置了线程。你可以按自己的需求优化模型。
1 2 3 4 |
config = tf.ConfigProto( inter_op_parallelism_threads=4, intra_op_parallelism_threads=4 ) |
在如下的源码中,包含输入值(x)、权重(w)和偏置量(b)的占位符会被初始化。一个占位符不止是你声明并在后面需要时使用的一个变量。它代表你的图形的结构:
1 2 3 |
x = tf.placeholder(tf.float32, shape=(1, 5), name='x') w = tf.placeholder(tf.float32, shape=(5, 1), name='w') b = tf.placeholder(tf.float32, shape=(1), name='b') |
在原始的麦卡洛克-皮特斯人工神经元中,输入(x)由如下的权重相乘:
$$w_1x_1 + … + w_nx_n = \sum_{j=1}^n{w_jx_j}$$
这个数学方程变成了一个带有回归激活函数(sigmoid)的单行代码,在本章的第二部分中会进行讲解。偏置量(b)初添加了,这让神经元格式即便在今天也有用,如下所示。
1 2 |
y = tf.matmul(x, w) + b s = tf.nn.sigmoid(y) |
在开启一个会话之前麦卡洛克-皮特斯神经元(1943)需要一个运算符来直接设置它的权重。这是麦卡洛克-皮特斯神经元和感知机(1957)之间的主要区别,后者是现代深度学习神经元的模型。感知机通过优化过程来优化它的权重。第四章 成为一个打破惯例的创新者中描述了现代感知机。
现在提供了权重,以及在仓库中一个地点l1处存储的每个x的数量:
$$x=\begin{bmatrix}w_{1}\\w_{2}\\w_{3}\\w_{4}\\w_{5}\\\end{bmatrix}
=\begin{bmatrix}10\\70\\75\\60\\20\\\end{bmatrix}$$
权重的值会除以100,来以百分比表示指定地点仓库物流值0到1。如下代码处理一个地点的选择,仅为l1,它的值和参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
with tf.Session(config=config) as tfs: tfs.run(tf.global_variables_initializer()) w_t = [[.1, .7, .75, .60, .20]] x_1 = [[10, 2, 1., 6., 2.]] b_1 = [1] w_1 = np.transpose(w_t) value = tfs.run(s, feed_dict={ x: x_1, w: w_1, b: b_1 } ) print ('value for threshold calculation',value) |
会话启动了,仓库物流的权重(w_t)和数量(x_1)被输入了。在这个模型中偏置量设置为1。w_1进行了转置来适配x_1。占位符通过feed_dict进行了请求,并且使用了sigmoid函数来计算神经元的值。
程序返回如下值。
1 2 |
print ('value for threshold calculation',value) value for threshold calculation [[0.99971133] |
这个值表示在指定日期和指定时间地点l1的活动。值越高,该区域饱和率的可能性就越高。这表示留给需要存放产品的AGV的空间也就很少。这是为什么仓库的强化学习程序来这一模型中寻找给定产品的最小负载区域。
每个地点都有一个可用性(availability):
A = Availability = 1 – load
一个给定存储点的负载概率为0到1之间。
可用性的高值接近于1,低概率会如下例所示接近于0:
1 2 |
print ('Availability of lx',1-value) Availability of lx [[0.00028867]] |
例如,l1的的负载量有一个0.99的负载概率并且其可用性为0.002。AGV的目标是搜索并找到最近且最可用的地点来优化其路径。l1显然在当天的那个时间不是一个好的候选项。负载(load) 是生产活动中的一个关键词。
在通过麦卡洛克-皮特斯神经元计算了所有6个地点的可用性时 – 每个都有自己的x数量输入、权重和偏置量 – 会生成这个系统结果的地点向量。这表示该程序需要实现来运行所有6个地点而不仅仅是一个地点:
A(L) = {a(l1 ),a(l2 ),a(l3 ),a(l4 ),a(l5 ),a(l6 )}
可用性(1 – 神经元的输出值)组成了一个6行向量。以下向量通过对所有6个位置运行前述示例代码获取。
$$lv=\begin{bmatrix}0.0002\\0.2\\0.9\\0.0001\\0.4\\0.6\\\end{bmatrix}$$
lv是包含每个给定AGV所选取的地点的值的向量。向量中的值表示可用性,0.0002表示低可用性,0.9表示高可用性。一旦做出了选择,第一章中所展示的强化学习程序会优化AGV路径来获取这个具体的仓库地点。
lv是对AGV的6个潜在地点的权重函数的结果。它也是转换后输入的向量。
Python TensorFlow的架构
麦卡洛克-皮特斯神经元的实现可以通过TensorBoard进行最好的查看,如下图所示(译者注:通过http://localhost:6006查看):
这通过在会话的最后添加如下的TensorBoard代码来获取。这个数据流图助于你在出现问题时优化程序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#___________Tensorboard________________________ #with tf.Session() as sess: Writer = tf.summary.FileWriter(LOG_DIR, tfs.graph) Writer.close() def launchTensorBoard(): import os os.system('tensorboard --logdir='+LOG_DIR) return import threading t = threading.Thread(target=launchTensorBoard, args=([])) t.start() tfs.close() # 打开浏览器并访问http://localhost:6006 # 尝试不同的选项。它是一个很有用的工具。 # 在完成后关闭系统窗口 |
在电脑上打开代码中所提示的 URL 后,你会看到如下的TensorBoard数据流图:
回归激活函数和分类器
现在每个地点的值L={l1,l2,l3,l4,l5,l6}在一个向量中包含其可用性,这些地点可从可用度最高到可用度最低进行排序。至此,可以构建第一章所描述 MDP 过程的回报矩阵。
整体架构
这里,整体架构包含了两个组件:
- 第一章 成为一个随机应变的思考者:使用待计算的回报矩阵的基于动作值Q函数的一个强化学习项目。该回报矩阵在第一章中给出了,但在现实生活中,通常你会需要从头开始构建它。它会需要数周来获取。
- 第二章:一组6个神经元表示在给定时间6个地点的产品物流。可用性概率的输出值为0到1之间。最高值可用性最高。最低值可用性也最低。
至此,从这两个函数中我们可以提取一些真实世界的信息:
- AGV在仓库中移动并等待接收下一个使用MDP的位置,以计算其任务的一个最优路线,如第一章中所示。
- AGV使用第一章中所给出的回报矩阵,但在现实生活中的项目需通过会议、报告以及过程的接受来设计出。
- 一个6个神经元的系统,每个地点一个神经元,权衡真实数量与概率数量来给出一个可用性向量 lv 被进行了计算。几乎准备好提供AGV所需的回报矩阵了。
要在强化学习仓库模型中计算回报矩阵的输入值,lv 和回报矩阵 R 之间少一个桥接函数。
这个桥接函数是基于y 神经元输出的一个回归分类器。
至此,该系统:
- 获取了集团数据
- 使用y 神经元以权重进行了计算
- 应用了一个激活函数
模型中的这个激活函数要求一个常用的回归分类器。
回归分类器
回归分类器会应用于lv(6个地点值)来查找AGV的最佳地点。它基于6个神经元的输出值(输入 x 权重 + 偏置量)。
什么是回归函数?回归分类器的目录是生成一个输出向量各个值从0到1的概率分页。如同你截至目前所看到的,AI 应用使用带有概率值应用数学,而非原生输出值。在仓库模型中,AGV需要选择最佳、最有概率的位置li。即便是在一个组织良好的集团仓库中,许多不确定性(延时到达、产品损坏以及很多计划外的问题)减少了一个选择的概率。概率表现为从0(低概率)到1(高概率)之间的值。回归函数提供将所有数字转化为0到1之间概率归一化数据的工具。
回归函数
回归sigmoid是供了归一化给定输出权重的最好方式之一。这会用作神经元的激活函数。阈值通常是高于在神经元有y=1值或有y=0值时一个值。本例中,最小值为0,因为激活函数会更为复杂。
回归函数表示如下:
$$1 \over {1 + e^{-x}}$$
- e 表示欧位常数,或2.71828,自然对数。
- x是要计算的值。本例中,x是回归sigmoid函数的结果。
下例中的代码被重新进行了排列来显示其推理过程:
1 2 3 4 5 6 7 8 |
# 对于给定变量: x_1 = [[10, 2, 1., 6., 2.]] # 输入值x w_t = [[.1, .7, .75, .60, .20]] # 对应的权重 b_1 = [1] # 偏置量 # 计算了指定的总权重 y y = tf.matmul(x, w) + b # 然后回归sigmoid 应用于 y,它表示回归Sigmoid正式定义中的"x" i s = tf.nn.sigmoid(y) |
通过回归sigmoid函数,模型中第一个地点的值出来的是0.99(该地点的饱和程度)。
考虑0.99并计算地点的可用性,我从总可用性 1 中减去这一负载,如下:
如前所见,在以这种方式计算了所有地点之后,就获取到了最终的可用性向量lv。
$$lv=\begin{bmatrix}0.0002\\0.2\\0.9\\0.0001\\0.4\\0.6\\\end{bmatrix}→[?]$$
在分析 lv时,一个问题导致了进程的停止。单拿出来,每行看上去都没有问题。通过对每个输出权重应用回归sigmoid并被1减后,每个地点显示一个0到1之间的可用性概率。但是,每行相加后大于1。这是不可能的,概率不能超过1。程序需要修复这一问题。在源代码中,lv 会被命名为y。
每行产生一个[0,1]的解,它符合对于有效概率的预设。
本例中,向量lv 包含一个以上的值并成为一个多点分布。lv 的加和不能超过1,需要进行归一化。
Softmax函数提供了一个很好的方法来稳固 lv。Softmax在机器学习和深度学习中被广泛使用。
记住这些数学工具不是规则。只要方案可行你可以根据需要调整它们来适应你的问题。
Softmax
softmax函数在多个人工智能模型中用于归一化数据。这是要理解和掌握的基本函数。在仓库模型的示例中,AGV需要在lv向量的6个位置中做一个概率选择。但是,lv值的总和超过了1。lv要求softmax函数 S的归一化。在这个层面上,softmax函数可被视作回归sigmoid函数的归纳。在代码中,lv向量会被命名为y。
$$S(y_i) = {e^{y_i} \over \sum_{j=1}^ne^{y_j}}$$
以下使用的代码是SOFTMAX.py;如下源代码中 y 表示 lv 向量:
1 2 |
# y 是仓库示例中lv向量的分值向量 y = [0.0002, 0.2, 0.9,0.0001,0.4,0.6] |
\(e^{y_i}\)是 y (仓库示例中的lv)中每个值的exp(i)结果,如下:
1 |
y_exp = [math.exp(i) for i in y] |
\(\sum_{j=1}^ne^{y_j}\)是\(e^{y_i}\)迭代的和,如以下代码所示:
1 |
sum_exp_yi = sum(y_exp) |
现在,向量的每个值可以通过简单的应用除法来对这种类型的多项式分布稳定化进行归一化,如下:
1 2 3 4 |
softmax = [round(i / sum_exp_yi, 3) for i in y_exp] # 要稳定化的向量 [2.0, 1.0, 0.1, 5.0, 6.0, 7.0] # 稳定化的向量 [0.004, 0.002, 0.001, 0.089, 0.243, 0.661] |
$$lv=\begin{bmatrix}0.0002\\0.2\\0.9\\0.0001\\0.4\\0.6\\\end{bmatrix}→softmax(x)→\begin{bmatrix}0.111\\0.135\\0.273\\0.111\\0.165\\0.202\\\end{bmatrix}$$
softmax(lv)提供一个总和等于1的归一化向量,并以代码的压缩版本进行显示。获取的向量通常以包含的logits进行描述。
以下代码详细描述了这一过程:
1 2 3 4 5 6 7 |
def softmax(x): return np.exp(x) / np.sum(np.exp(x), axis=0) y1 = [0.0002, 0.2, 0.9,0.0001,0.4,0.6] print("Stablized vector",softmax(y1)) print("sum of vector",sum(softmax(y1))) # Stabilized vector [0.11119203 0.13578309 0.27343357 0.11118091 0.16584584 0.20256457] # Sum of the normalize vector 1.0 |
softmax函数可用作分类器的输出(例如像素)或做出决策。在仓库的示例中,它将lv转换为一个决策过程。
softmax函数的下一部分要求softmax(lv)四舍五入为0或1。softmax(lv)中的值越高,它的概率也越高。在明确的转换中,最大值会接近于1,其它值会接近于0。在决策制定过程中,需要找到最大值,如下:
1 2 |
print("highest value in transformed y vector",max(softmax(y1))) #highest value in normalized y vector 0.273433565194 |
一旦选择第三行(值0.273)作为最可能的地点,它被设置为1,而其它较低值的则设为0。这称为独热(编码)函数。独热函数对所提供的数据编码极其的有帮助。获取的变量现在可以应用于回报矩阵。概率值1会变成 R回报矩阵中的100,如下:
$$lv=\begin{bmatrix}0.0002\\0.2\\0.9\\0.0001\\0.4\\0.6\\\end{bmatrix}→softmax(x)→\begin{bmatrix}0.111\\0.135\\0.273\\0.111\\0.165\\0.202\\\end{bmatrix}→one-hot→\begin{bmatrix}0\\0\\1\\0\\0\\0\\\end{bmatrix}→R→\begin{bmatrix}0\\0\\100\\0\\0\\0\\\end{bmatrix}$$
现在softmax函数已经完整了。地点 l3或C是AGV的最佳方案。概率值在R函数中乘上了100,现在可以在描述的回报矩阵中接收该输入了。
小贴士:在继续之前,花点时间调整源代码中的值并运行它来熟悉softmax。
我们现在有了一些回报矩阵的数据。理解该项目数学层面最好的方式是使用一张卡片并画出实际仓库 A 到 F 布局的结果。
Locations={l1 -A, l2 -B, l3 -C, l4 -D, l5 -E, l6 -F}
回报矩阵={0,0,100,0,0,0} 中为位置的值,这里C(第三个值)现在是自动驾驶车辆(本例中是仓库中的 AGV)的目标。
我们获取了第一章中描述的如下回报矩阵 R。
状态/值 | A | B | C | D | E | F |
---|---|---|---|---|---|---|
A | - | - | - | - | 1 | - |
B | - | - | - | 1 | - | 1 |
C | - | - | 100 | 1 | - | - |
D | - | 1 | 1 | - | 1 | - |
E | 1 | - | - | 1 | - | - |
F | - | 1 | - | - | - | - |
这个回报矩阵和第一章使用Q 函数的Python强化学习程序中的完全一样。本章中的输出是第一章中 R 矩阵的输入。这些0值在这里让代理避开这些值。这个程序设计来保持概率标准和正值相近,如下面的 R 矩阵所示:
1 2 3 4 5 6 |
R = ql.matrix([ [0,0,0,0,1,0], [0,0,0,1,0,1], [0,0,100,1,0,0], [0,1,1,0,1,0], [1,0,0,1,0,0], [0,1,0,0,0,0] ]) |
至此,组成部分已就绪,可以开始运行强化学习程序的结果了。
总结
使用麦卡洛克-皮特斯神经元与回归激活函数在一层网络中构建强化学习的回报矩阵,显示了如何使用 AI 技术在构建真实世界的应用。
处理真实世界数据通常要求通过softmax以及对logits应用独热函数来编码数据来对回归sigmoid函数进行归纳。
这显示机器学习函数是必须理解的工具,才能够使用它们的所有或部分来解决问题。对人工智能抱有这种实用的态度,整个的项目世界为你敞开大门。
你已经可以使用这两章来展示强大的路线模型,如Amazon仓库以及对你的团队或客户的投递。此外,Amazon, Google, Facebook, Netflix和其它公司在我们讨论的时候不断的增加他们的数据中心。每个数据中心有需要校准的数据流的位置。你可以本章中给出的想法来展示该问题以及校准产品和数据流所需的实时计算。
神经元方法是第五章 管理机器学习和深度学习的能力中会介绍的多层感知机的始祖。在该章中,会做出机器学习到深度学习的转换。
但是,在那之前,机器学习或深度学习要求评估函数。没有评估则无法验证结果,在第三章 将机器思维应用到人类问题上中会进行讲解。下一章中,评估过程会以象棋和真实世界的情况进行描述。