梯度观点中的正则化[张量流中的手动反向传播]
正则化对渐变有什么影响?
GIF from this website
正则化就像上面展示的那只猫,当一些权重想要变得“大”时,我们惩罚它们。今天我想看看正则项给梯度带来了什么样的变化。下面是我们将要比较的不同正则化术语的列表。(θ是每层的重量。).
Z .基线 (无正则化) a .θ*【岭回归】* b . ABS(θ)+sqrt(ABS(θ)(弹性网) c .θ (来自论文“ 【比较稀疏度】” e . ABS(θ)(p 值为 1 的 p-norm) f . sqrt(ABS(θ))(p-norm 带 p-的 (来自论文“**”* I .-tanh(θ)(来自论文“ 比较稀疏度” j*
简介
为了防止过拟合,或者控制过拟合的程度(过拟合的严重程度),我们使用正则化,例如去掉或增加 L1 或 L2 正则化项。正则化背后的一般思想(除了退出),是在最小化目标函数的同时最小化权重的大小,当然,一些正则化旨在创建‘稀疏’权重,这意味着大多数权重值为零。
接下来,对于神经网络架构中的任何训练过程,都有一些共同的元素,例如激活前后的值。相对于权重的梯度,以及传递到前面层的梯度。权重本身,以及使用 Adam 优化器时每个权重的动量值。
所以把两个和两个放在一起,正则项对那些值有什么样的影响?它们的均值、标准差、偏度、峰度和非零元素的数量,它们会随着基线表现增加、减少还是保持不变?
相关作品
关于如何解释正则化项,最有趣的观点之一是将其视为权重之前的贝叶斯。这篇的博文详细描述了我们理解正则化术语的不同观点。(我怀疑正则化的程度取决于先验的知情/不知情程度,我还认为随着训练的进行,最终可能性将对权重产生更大的影响。).
此外,如果有人对 L1 和 L2 正规化背后的基本直觉以及一些命名历史感兴趣,请查看此博客帖子。
实验设置
蓝色球体 →来自 STL 数据集的输入图像(20,96,96,3)的形状
黄色矩形 →带有 ReLU 激活的卷积层
红色正方形 →交叉熵损失项
整个实验只是一个分类任务,根据我们添加的正则项,黄色矩形在计算梯度时会有一个附加项。在继续之前,我希望澄清我将要用到的每个单词的意思。
**
结果
训练/测试准确性
**
当我们查看训练和测试数据的准确度图时,我们可以观察到……
添加时达到最高训练精度:sqrt(θ)/θ
添加时达到最高测试精度:-tanh(θ)*
添加时达到最低性能:θ*
当我们添加术语 θ 时,每个权重的导数值就变成 1,我怀疑这可能会导致超调。
gradientp 的平均统计值(传递到上一层的梯度)
当我们查看传递到上一层的渐变值时,有一种颜色非常突出,那就是灰色。加上 -log(1+θ ) 这一项,似乎让梯度值变化很大。
梯度的平均统计值 w(相对于重量的梯度)
当我们将注意力集中在非零元素的数量上时,我们观察到,在没有任何正则化项的情况下,关于每个权重的梯度主要由零组成。(这也可能是造成收敛慢的原因。).
当我们把注意力集中在平均标准偏差值上时,我们注意到在训练的最后区域,粉红色和黄色的线相交。然而,案例 H(粉色)在训练/测试数据上的表现比案例 B(黄色)好得多。
层的平均统计数据(激活前的层值)
当我们查看每一层的值(激活函数之前)时,我们马上注意到,随着训练的继续,情况 C(绿色)的平均值不断下降。我不认为这种减少本身是一件坏事,但是,与其他情况相比,这是极端的,另外请注意,我们正在使用 ReLU 激活,这意味着任何小于零的值,都将被丢弃并被零取代。
层 a 的平均统计数据(激活后的层值)
我们已经知道,添加 -tanh(θ) (粉红色线)在测试图像上给了我们最好的结果,当我们将注意力集中在激活层之后的非零元素的数量时,情况 H(粉红色线)在其自己的区域中。
当其他案例高于或低于 60,000 时,奇怪的是案例 H 似乎集中在该区域。与其他情况相比,数据的内部表示更加稀疏。
重量的平均统计(每种情况下的重量值)
由于情况 C(绿线)过冲,我们得到了一个扭曲的图表,其中其他值被压缩,以适应情况 C 中重量的减少,因此在下一个图中,我已将情况 C 从平均重量图中移除。
移除后,我们可以清楚地看到不同权重值如何随时间变化。同样,我们注意到情况 H(粉线)位于它自己的区域,我不知道它为什么这样做,也没有意义,因为正则化的要点是最小化权重,为什么值比其他情况高?
矩的平均统计数据(Adam 优化器的动量部分)
从上面的图中,我们(也许能够)得出结论,情况 C(绿线)已经过冲。好像都是?或者说动量的大部分值为零。标准差都是零,表明动量内没有太多的变化。
讨论
我想以这句话开始这一部分,
我不能得出任何结论,这只是一个实验,因此从一个样本得出任何结论都是错误的。此外,我的实验的一个关键缺陷是,所有的权重没有被同等地初始化!我给出了完全相同的种子值和标准偏差(如下所示),但我不确定是否所有的权重都被同样初始化了。**
从所有这些实验来看,似乎没有规则可以保证一个模型在测试数据上表现良好。(或者会有更高的泛化能力)。然而,似乎有一个模型可以很好地概括的独特模式。
我将只关注情况 H(粉红色),通常,我们理解正则化是为了限制权重大小的增长,然而,从上图中我们可以清楚地看到情况 H 权重的平均值高于其他情况…所以…?问题就变成了它规范得好吗?使用 tanh 术语可能是这背后的原因吗?
但是另外,我们注意到在 ReLU 激活后,案例 H 的 layera 值比其他案例更稀疏。这意味着健康剂量的零被混合在内部表示中。我真的很想知道为什么案例 H 给出了最好的测试精度,目前只能用“因为它被很好地正则化了”来解释,但是我知道还有更多。
结论/代码
总之,权重大小和稀疏性之间的正确平衡似乎给出了良好的泛化性能。(手动波浪形)。
要访问 google collab 中的代码,请点击此处,要访问我的 GitHub 中的代码,请点击此处。
遗言
在做这些实验时,我不禁想到这些类型的正则化有一个(不那么关键的)缺陷。
它们都是被动正规化方法。
更具体地说,网络中的每个权重,不管它们位于何处,它们倾向于捕捉什么样的特征,它们都被正则化。我当然相信这是一个有趣的研究领域,例如,我们可以有一个简单的条件语句,即“如果权重的大小大于 x,则执行正则化”或更复杂的语句“如果该权重和类标签之间的互信息已经很高,则执行正则化”。我想知道这些方法将如何改变训练的整体动力。
最后,我要感谢我的导师,Bruce 博士给我推荐了论文“稀疏度的比较”。更多文章请访问我的网站。
附录(每种情况下每层的 GIF 动画)
情况 Z:按梯度、梯度、层、层 a、力矩、重量的顺序
**
情况 A:按梯度 p、梯度 w、层、层 A、力矩、重量顺序
**
情况 B:按梯度 p、梯度 w、层、层 a、力矩、重量顺序
**
情况 C:按梯度 p、梯度 w、层、层 a、力矩、重量顺序
**
情况 D:按梯度 p、梯度 w、层、层 a、力矩、重量顺序
**
情况 E:按梯度 p、梯度 w、层、层 a、力矩、重量顺序
**
情况 F:按梯度 p、梯度 w、层、层 a、力矩、重量顺序
**
情况 G:按梯度 p、梯度 w、层、层 a、力矩、重量顺序
**
情况 H:按梯度 p、梯度 w、层、层 a、力矩、重量顺序
**
情况一:按梯度、梯度、层、层、力矩、重量的顺序
**
情况 J:按梯度 p、梯度 w、层、层 a、力矩、重量的顺序
**
附录(衍生品)
参考
- n .布鲁斯(2016)。尼尔·布鲁斯。尼尔·布鲁斯。检索于 2019 年 1 月 4 日,来自http://www.scs.ryerson.ca/~bruce/
- Hurley 和 s . Rickard(2008 年)。稀疏度的比较。arXiv.org。检索于 2019 年 1 月 4 日,来自https://arxiv.org/abs/0811.4706
- 用 Python 进行数值和科学计算:用 Python 和 Matplotlib 创建子图。(2019).python-course . eu . 2019 年 1 月 4 日检索,来自https://www . python-course . eu/matplotlib _ multiple _ figures . PHP
- SciPy . stats . Kurt osis—SciPy v 1 . 2 . 0 参考指南。(2019).Docs.scipy.org。检索于 2019 年 1 月 4 日,来自https://docs . scipy . org/doc/scipy/reference/generated/scipy . stats . Kurt osis . html
- scipy.stats.skew — SciPy v0.13.0 参考指南。(2019).Docs.scipy.org。检索于 2019 年 1 月 4 日,来自https://docs . scipy . org/doc/scipy-0 . 13 . 0/reference/generated/scipy . stats . skew . html
- numpy.count _ 非零—NumPy 1.15 版手册。(2019).Docs.scipy.org。2019 年 1 月 4 日检索,来自https://docs . scipy . org/doc/numpy-1 . 15 . 1/reference/generated/numpy . count _ 非零值. html
- 数组?,E. (2017)。高效计算 numpy 数组中的零元素?。堆栈溢出。检索于 2019 年 1 月 4 日,来自https://stack overflow . com/questions/42916330/efficiency-count-zero-elements-in-numpy-array
- 解析,S. (2013)。语法错误:分析时出现意外的 EOF。堆栈溢出。检索于 2019 年 1 月 4 日,来自https://stack overflow . com/questions/16327405/syntax error-unexpected-eof-while-parsing
- Matplotlib . py plot . legend-Matplotlib 3 . 0 . 2 文档。(2019).Matplotlib.org。检索于 2019 年 1 月 4 日,来自https://matplotlib . org/API/_ as _ gen/matplotlib . py plot . legend . html
- 行与列——谷歌搜索。(2019).Google.com。2019 年 1 月 4 日检索,来自https://www.google.com/search?q=row+vs+column&rlz = 1 C1 chbf _ enca 771 ca 771&OQ = row+vs+col&aqs = chrome . 0.35 i39 j 69 I 60j 69 I 57j 0l 3.2289j 1j 7&sourceid = chrome&ie = UTF-8
- 图例指南— Matplotlib 2.0.2 文档。(2019).Matplotlib.org。检索于 2019 年 1 月 4 日,来自https://matplotlib.org/users/legend_guide.html
- 正则项导数的随机注释。(2019).中等。检索于 2019 年 1 月 4 日,来自https://medium . com/@ SeoJaeDuk/archived-post-random-notes-for-derivative-for-regulation-terms-1859 B1 faada
- IPython r .(2013 年)。IPython 中释放大数组内存。堆栈溢出。检索于 2019 年 1 月 5 日,来自https://stack overflow . com/questions/16261240/releasing-memory-of-huge-numpy-array-in-ipython
- 内置神奇命令— IPython 7.2.0 文档。(2019).ipython . readthe docs . io . 2019 年 1 月 5 日检索,来自https://ipython . readthe docs . io/en/stable/interactive/magics . html
- j . Chapman(2017 年)。如何用 Python 制作 gif?多余的六分仪。检索于 2019 年 1 月 5 日,来自http://superfluoussextant.com/making-gifs-with-python.html
- 岭回归、套索和弹性网之间的区别是什么?。(2017).兼收并蓄的秘传。检索于 2019 年 1 月 5 日,来自https://blog . alexlenail . me/what ’ s-the-difference-the-ridge-regression-the-lasso-and-elastic net-EC 19 c 71 c 9028
- (2019).Web.stanford.edu。检索于 2019 年 1 月 5 日,来自https://web . Stanford . edu/~ hastie/Papers/b 67.2% 20% 282005% 29% 20301-320% 20 Zou % 20&% 20 hastie . pdf
- 面向数据科学的 L1 和 L2 正则化方法。(2017).走向数据科学。检索于 2019 年 1 月 5 日,来自https://towards data science . com/L1-and-L2-regulation-methods-ce 25 e 7 fc 831 c
- 岭回归、套索和弹性网之间的区别是什么?。(2017).兼收并蓄的秘传。检索于 2019 年 1 月 5 日,来自https://blog . alexlenail . me/what ’ s-the-difference-the-ridge-regression-the-lasso-and-elastic net-EC 19 c 71 c 9028
- STL-10 数据集。(2019).Cs.stanford.edu。检索于 2019 年 1 月 5 日,来自https://cs.stanford.edu/~acoates/stl10/
- plot,H. (2010 年)。如何更改 matplotlib 绘图的字体大小?堆栈溢出。检索于 2019 年 1 月 5 日,来自https://stack overflow . com/questions/3899980/how-to-change-the-font-size-on-a-matplotlib-plot
- matplotlib?,H. (2015)。如何使用 matplotlib 在同一行中绘制多个图形?。堆栈溢出。检索于 2019 年 1 月 5 日,来自https://stack overflow . com/questions/34291260/how-can-I-plot-multiple-figure-in-the-same-line-with-matplotlib
- 正文,I. (2016)。IPython 笔记本键盘快捷键搜索文本。堆栈溢出。检索于 2019 年 1 月 5 日,来自https://stack overflow . com/questions/35119831/ipython-notebook-keyboard-shortcut-search-for-text
- 创建和导出视频剪辑— MoviePy 0.2.3.2 文档。(2019).zulko . github . io . 2019 年 1 月 5 日检索,来自https://zulko . github . io/movie py/getting _ started/video clips . html
- 用 Python 制作视频文件的 gif—_ _ del _ _(self)。(2014).zulko . github . io . 2019 年 1 月 5 日检索,来自http://zulko . github . io/blog/2014/01/23/making-animated-gifs-from-video-files-with-python/
权重观点中的正则化[张量流中的手动反向传播]
不同的正则化如何影响最终的权重值?
GIF from this website
我要感谢我的导师布鲁斯博士鼓励我进一步研究这个想法。此外,我想感谢我的实验室成员,在瑞尔森视觉实验室、贾森关于正规化的有益讨论。
更多类似的文章,请访问我的网站, Jaedukseo.me 。
简介
为了防止我们的模型过度拟合,我们可以使用不同种类的正则化技术。其中一种技术是在我们想要优化的损失函数中加入一个正则项。因此,当我们对模型中的权重求导时,我们会对权重添加额外的梯度。
但是不同的正则项如何影响权重呢?更具体地说,它会如何影响价值观的传播?意味着直方图的形状。
实验设置
蓝色球体 →输入图像数据( STL10 或 CIFAR10 )
黄色矩形 →带 ReLU 激活的卷积层
红色方块 →交叉熵损失项用于分类
网络本身只由六层组成,并不是一个大网络。然而,我们将使用两个不同的数据集,CIFAR 10 和 STL 10。
此外,我们将在有和没有批量标准化的情况下训练网络 10 集,这是为了观察相同的现象是否会反复发生。(现象是,权重收敛到直方图的特定形状。).最后,下面是我们要比较的所有正则项的列表。
Z:基线(无正则化)
A:ABS(Theta)
B:Theta
C:sqrt(Theta)
D:—log(1+Theta)
E:—tanh(Theta)
F:—tanh(Theta)
G:—tanh(ABS(Theta))
H:—tanh(ABS(Theta)
I:sin(Theta)
J:ABS(sin
结果位移
最左边的 gif 显示了 10 集的重量直方图和粉红色的平均直方图。
如上所述,从红色开始,它代表使用 Adam optimizer 150 个周期后的最终重量。粉色直方图代表平均重量值的直方图。现在放大可视化中最右边的图像。
每个方框显示了每一层的最终直方图,最终图显示了最大/最小/平均训练(红色)/测试(蓝色)性能。
结果
Z:基线(无调整)
without Batch Normalization (STL)
With Batch Normalization (STL)
without Batch Normalization (CIFAR)
with Batch Normalization (CIFAR)
答:ABS(θ)
without Batch Normalization (STL)
with Batch Normalization (STL)
without Batch Normalization (CIFAR)
with Batch Normalization (CIFAR)
B:θ
without Batch Normalization (STL)
with Batch Normalization (STL)
without Batch Normalization (CIFAR)
with Batch Normalization (CIFAR)
C: sqrt(Theta )
without Batch Normalization (STL)
with Batch Normalization (STL)
without Batch Normalization (CIFAR)
with Batch Normalization (CIFAR)
D:——log(1+Theta)
without Batch Normalization (STL)
with Batch Normalization (STL)
without Batch Normalization (CIFAR)
with Batch Normalization (CIFAR)
E:——tanh(Theta)
without Batch Normalization (STL)
with Batch Normalization (STL)
without Batch Normalization (CIFAR)
with Batch Normalization (CIFAR)
F:–tanh(Theta)
without Batch Normalization (STL)
with Batch Normalization (STL)
without Batch Normalization (CIFAR)
with Batch Normalization (CIFAR)
G:——tanh(ABS(Theta))
without Batch Normalization (STL)
with Batch Normalization (STL)
without Batch Normalization (CIFAR)
with Batch Normalization (CIFAR)
H: -tanh(abs(Theta) )
without Batch Normalization (STL)
with Batch Normalization (STL)
without Batch Normalization (CIFAR)
with Batch Normalization (CIFAR)
I:sin(θ)
without Batch Normalization (STL)
with Batch Normalization (STL)
without Batch Normalization (CIFAR)
with Batch Normalization (CIFAR)
J: abs(sin(Theta))
without Batch Normalization (STL)
with Batch Normalization (STL)
without Batch Normalization (CIFAR)
with Batch Normalization (CIFAR)
K:对数(θ)
without Batch Normalization (STL)
with Batch Normalization (STL)
without Batch Normalization (CIFAR)
with Batch Normalization (CIFAR)
L: Theta * log(Theta )
without Batch Normalization (STL)
with Batch Normalization (STL)
without Batch Normalization (CIFAR)
with Batch Normalization (CIFAR)
讨论/代码
虽然没有任何明确的证据或定理,我可以从这个实验中证明。我能够做出一些经验性的观察。
- 批量标准化(没有任何 alpha 或 beta 参数)很可能导致模型过度拟合。
- 增加批次归一化,使训练更加稳定。此外,它还使权重收敛于类高斯分布。(我们怀疑这可能和中心极限定理有关。)
- 小批量导致更严重的过度拟合。
- 在权重的稀疏性和过度拟合程度之间似乎存在微弱的负相关。(如果权重值稀疏,意味着权重中有许多零值,过度拟合程度越低)。
事后看来,最后的观察非常有意义,如果网络权重本身包含大量零值,并且有一些约束将权重保持在那些区域中,那么网络自然很难过度拟合。
我想提出的一些有趣的联系是关于我们的大脑是如何编码视觉输入的。从多个实验中,我们知道 V1 细胞创建了给定视觉输入的稀疏表示,这与具有稀疏权重集非常不同,然而,在稀疏的名义下,它似乎有一些联系。也许,仅仅是也许,对于任何有效的学习模型来说,可能需要一个好的稀疏的权重集。
要访问 CIFAR 10 的代码请点击这里,要访问 STL 10 的代码请点击这里。
最后,如果您希望访问 CIFAR 10 和 STL 10 的每一层的完整结果,无论是否进行批规格化。
请点击此处访问 CIFAR 10 的完整结果。
请点击此处访问 STL 10 的完整结果。
超级有用的数学推理,关于你完全(不应该)信任的每个正则化子在做什么
在这一节中,我想简单介绍一下每个正则项对权重的影响。但是,请注意,这不是一个数学定义。直线代表调节项的值,而虚线代表梯度大小。
上面显示了正则化项 abs(x),x,和 sqrt(x)的样子以及它的导数。需要注意的一点是,当导数的幅度结束时,特别是对于 abs(x),我们注意到,当 x 位于 0 时,梯度的幅度停止。
因此,该模型将不得不平衡它应该具有多少稀疏权重和它将从没有稀疏权重得到多少惩罚。而具有 x 正则项的网络可以承受多个小数量级的权重。
对于涉及 log 的正则化项,我们注意到,由于梯度增加接近无穷大,训练会极不稳定。(对于正无穷大和负无穷大)
对于带有双曲正切的正则化项,我们可以看到只有某些区域的梯度值大于零。
最后,对于 sin 类型的正则项,我们可以看到,网络试图收敛到某些数字,目标并不真正涉及稀疏性。
最后的话
在 ICA 中,目标之一是对给定数据进行稀疏表示。虽然使网络的权重稀疏,可以达到类似的结果,我想知道他们的性能会有什么不同。
具有稀疏性约束可以在增加神经网络的泛化能力方面发挥巨大作用。然而,不同风格的稀疏约束可能是一个更重要的问题来解决。
更多类似的文章,请访问我的网站, Jaedukseo.me 。
参考
- 笔记本,o .,&达利,S. (2017)。覆盖 jupyter 笔记本中以前的输出。堆栈溢出。检索于 2019 年 1 月 15 日,来自https://stack overflow . com/questions/38540395/overwrite-previous-output-in-jupyter-notebook
- n .布鲁斯(2016)。尼尔·布鲁斯。尼尔·布鲁斯。检索于 2019 年 1 月 15 日,来自http://www.scs.ryerson.ca/~bruce/
- 在和 Alpha 之间填充— Matplotlib 3.0.2 文档。(2019).Matplotlib.org。检索于 2019 年 1 月 15 日,来自https://matplotlib . org/gallery/recipes/fill _ between _ alpha . html
- Matplotlib . py plot . plot-Matplotlib 3 . 0 . 2 文档。(2019).Matplotlib.org。检索于 2019 年 1 月 15 日,来自https://matplotlib . org/API/_ as _ gen/matplotlib . py plot . plot . html
- plots,h .,Raviv,o .,Castro,s .,Isaac,é。,& Twerdochlib,N. (2010 年)。在 matplotlib 图中隐藏轴文本。堆栈溢出。检索于 2019 年 1 月 17 日,来自https://stack overflow . com/questions/2176424/hiding-axis-text-in-matplotlib-plots
- NumPy . histogram—NumPy 1.15 版手册。(2019).Docs.scipy.org。检索于 2019 年 1 月 17 日,来自https://docs . scipy . org/doc/numpy-1 . 15 . 0/reference/generated/numpy . histogram . html
- Matplotlib . axes . axes . hist 2d-Matplotlib 3 . 0 . 2 文档。(2019).Matplotlib.org。检索于 2019 年 1 月 17 日,来自https://matplotlib . org/API/_ as _ gen/matplotlib . axes . axes . hist 2d . html
- matplotlib——条形图、散点图和直方图——生物学家的实用计算。(2019).People.duke.edu。检索于 2019 年 1 月 17 日,来自http://people . duke . edu/~ CCC 14/pcfb/numpympl/matplotlibbarplots . html
- mplot3d 示例代码:bars3d_demo.py — Matplotlib 1.3.1 文档。(2019).Matplotlib.org。检索于 2019 年 1 月 17 日,来自https://matplotlib . org/1 . 3 . 1/examples/mplot3d/bars 3d _ demo . html
- mplot3d 示例代码:poly 3d _ demo . py—Matplotlib 1 . 3 . 0 文档。(2019).Matplotlib.org。检索于 2019 年 1 月 17 日,来自https://matplotlib . org/1 . 3 . 0/examples/mplot3d/polys3d _ demo . html
- 直方图?,P. (2017)。绘制一系列直方图?。Mathematica 堆栈交换。检索于 2019 年 1 月 17 日,来自https://Mathematica . stack exchange . com/questions/158540/plot-a-sequence-of-histograms
- 图形?,W. (2013)。“np.histogram”和“plt.hist”有什么区别?为什么这些命令不绘制相同的图形?。堆栈溢出。检索于 2019 年 1 月 17 日,来自https://stack overflow . com/questions/20531176/what-is-the-difference-between-NP-histogram-and-PLT-hist-why-dont-these-co
- NumPy . Lin space—NumPy 1.15 版手册。(2019).Docs.scipy.org。检索于 2019 年 1 月 17 日,来自https://docs . scipy . org/doc/numpy-1 . 15 . 0/reference/generated/numpy . linspace . html
- 结果,第(2017)页。PLT . hist()vs NP . histogram()-意外结果。堆栈溢出。检索于 2019 年 1 月 17 日,来自https://stack overflow . com/questions/46656010/PLT-hist-vs-NP-histogram-unexpected-results
- plot,c .,& Navarro,P. (2012 年)。更改 matplotlib 3D 绘图的轴平面的背景颜色。堆栈溢出。检索于 2019 年 1 月 17 日,来自https://stack overflow . com/questions/11448972/changing-the-background-color-of-a-matplotlib-3d-plot-planes/12623360
- NumPy . arange—NumPy 1.11 版手册。(2019).Docs.scipy.org。检索于 2019 年 1 月 17 日,来自https://docs . scipy . org/doc/numpy-1 . 11 . 0/reference/generated/numpy . arange . html
- LLC,I. (2019)。命令行工具:Convert @ ImageMagickImagemagick.org。检索于 2019 年 1 月 17 日,来自 https://imagemagick.org/script/convert.php
- 使用 Python 的 Matplotlib 制作 3D 绘图动画。(2012).糖分过高。检索于 2019 年 1 月 17 日,来自https://zulko . WordPress . com/2012/09/29/animate-your-3d-plots-with-python-matplotlib/
- 鼠,H. (2017)。如何在 python 中旋转 3d 绘图?(或作为动画)使用鼠标旋转三维视图。堆栈溢出。检索于 2019 年 1 月 17 日,来自https://stack overflow . com/questions/43180357/how-to-rotate-a-3d-plot-in-python-or-as-a-a-animation-rotate-3d-view-using-mou?noredirect=1 & lq=1
- 贾,S. (2019)。贾森——概述。GitHub。检索于 2019 年 1 月 28 日,来自https://github.com/SenJia
- 瑞尔森视觉实验室。(2018).Ryersonvisionlab.github.io 于 2019 年 1 月 28 日检索,来自https://ryersonvisionlab.github.io/
- STL-10 数据集。(2019).Cs.stanford.edu。检索于 2019 年 1 月 28 日,来自https://cs.stanford.edu/~acoates/stl10/
- https://www.cs.toronto.edu/~kriz/cifar.html
- 德斯莫斯图表。(2019).德斯莫斯图形计算器。检索于 2019 年 1 月 29 日,来自https://www.desmos.com/calculator
神经网络的正则化技术
在我们的上一篇文章中,我们学习了前馈神经网络以及如何设计它们。在这篇文章中,我们将学习如何解决机器学习领域中出现的一个最核心的问题,即如何使我们的算法不仅找到训练集的完美匹配,而且找到测试集的完美匹配。当一个算法在训练集上表现很好,但在测试集上表现很差时,该算法被称为在训练数据上过度拟合。毕竟,我们的主要目标是在从未见过的数据上表现良好,即减少过度拟合。为了解决这个问题,我们必须使我们的模型在训练数据上一般化,这是使用各种正则化技术完成的,我们将在本文中学习。
以增加训练误差为代价减少测试集误差的策略或技术统称为正则化。深度学习实践者可以使用许多这样的技术。事实上,开发更有效的正则化策略一直是该领域的主要研究工作之一。
正则化可以定义为我们对学习算法进行的任何修改,其目的是减少其泛化误差,而不是训练误差。这种正则化通常是通过对机器学习模型施加一些额外的约束来完成的,例如对参数值添加限制,或者通过在目标函数中添加额外的项,这些额外的项可以被认为对应于对参数值的软约束。如果选择正确,这些可以减少测试误差。一个有效的规则化者被认为是通过显著减少方差而不过度增加偏差来进行盈利交易的人。
参数范数惩罚
这种技术是基于限制模型的容量,通过添加一个参数范数惩罚到目标函数 j。
其中α是一个超参数,它对范数惩罚ω的相对贡献进行加权。将 alpha 设置为 0 意味着没有正则化,alpha 值越大,正则化程度越高。
对于神经网络,我们选择使用参数范数惩罚,该惩罚对仿射变换的权重进行惩罚,并使偏差不被调节。这是因为偏差比权重需要更少的数据来精确拟合。由于权重用于表示两个变量之间的关系,并要求在各种条件下观察两个变量,而偏差仅控制单个变量,因此可以不进行调整。
L2 参数正则化
这种正则化通常被称为权重衰减。该策略通过添加正则化项ω来驱动权重更接近原点,正则化项ω定义为:
这种技术也称为岭回归或吉洪诺夫正则化。
正则化后的目标函数表示为:
相应的参数梯度:
更新权重的单一梯度步骤:
我们可以看到,在执行通常的梯度更新之前,权重衰减项现在在每一步上以常数因子倍增地收缩权重向量。
L1 正则化
这里正则项定义为:
这使得我们的目标函数为:
相应的梯度:
通过观察梯度,我们可以注意到梯度是如何通过符号等于符号(wi)的常数因子来缩放的。
数据集扩充
使模型一般化的最好和最简单的方法是在大量数据上训练它,但大多数情况下我们只能获得有限的数据。一种方法是创建假数据,并将其添加到我们的训练数据集中,对于某些领域来说,这相当简单明了。
这种方法主要用于分类问题,分类器需要接受复杂的高维输入 x,并用单个类别标识 y 对其进行总结。这意味着分类器面临的主要任务是对各种变换保持不变。我们可以通过转换训练集中的 x 输入来轻松生成新的(x,y)对。这种方法并不总是适合于诸如密度估计任务的任务,除非我们已经解决了密度估计问题,否则很难生成虚假数据。
数据集扩充是用于诸如图像分类或对象识别的计算机视觉任务的非常流行的方法,因为图像是高维的,并且包括大量变化因素,其中许多可以容易地模拟。像在每个方向上将训练图像平移几个像素、旋转图像或缩放图像这样的操作通常可以极大地提高泛化能力,即使已经通过使用卷积和池化技术将模型设计为部分平移不变的。
噪声鲁棒性
噪声通常作为数据集扩充策略引入到输入中。在模型的输入端添加具有无穷小方差的噪声相当于对权重的范数施加惩罚。噪声注入比简单地收缩参数要强大得多,尤其是当噪声被添加到隐藏单元时。
噪声被用于正则化模型的另一种方式是将其添加到权重中。这种技术主要用于递归神经网络。这可以解释为贝叶斯推理在权重上的随机实现。
半监督学习
在半监督学习中,来自 P (x)的未标记样本和来自 P (x,y)的标记样本都用于估计 P (y | x)或从 x 预测 y。深度学习的上下文中,半监督学习通常指学习一种表示 h = f (x)。目标是学习一种表示法,这样来自同一个类的例子就有相似的表示法。无监督学习提供了关于如何在表示空间中对训练样本进行分组的线索。在应用我们的分类器之前,使用主成分分析作为预处理步骤是这种方法的一个例子。
代替对无监督和有监督组件使用单独的模型,可以构建这样的模型,其中 P (x)或 P(x,y)的生成模型与 P(y | x)的判别模型共享参数。现在,P(x)的结构与 P(y | x)的结构以一种被共享参数化捕获的方式相连接。通过控制在总标准中包含多少生成标准,可以找到比使用纯生成或纯区别训练标准更好的折衷。
多任务学习
多任务学习是一种通过汇集几个任务中产生的例子来提高概括能力的方法。同样地,额外的训练示例对模型的参数施加更大的压力,使其趋向于概括得好的值,当模型的一部分在任务之间共享时,模型的该部分更倾向于好的值,通常产生更好的概括。
该模型一般可分为两类部分和相关参数:
特定于任务的参数只有从其任务的实例中受益才能实现良好的泛化。
所有任务共享的通用参数受益于所有任务的池化数据。
提前停止训练
当在足够大的数据集上训练大型模型时,如果训练进行了很长时间而不是增加模型的泛化能力,则会增加过度拟合。在训练过程中,训练误差不断减少,但在某个点之后,验证误差开始增加,因此表明我们的模型已经开始过度拟合。
Loss comparison of training and Validation
考虑提前停止的一种方式是作为一种非常有效的超参数选择算法。提前停止训练的想法是,一旦验证误差开始增加,我们就冻结参数并停止训练过程。或者,我们也可以在每次验证集上的误差改善时存储模型参数的副本,并在训练终止时返回这些参数,而不是最新的参数。
早期停止比权重衰减具有优势,早期停止自动确定正则化的正确量,而权重衰减需要具有不同超参数值的许多训练实验。
制袋材料
Bagging 或 bootstrap 聚合是一种通过组合几个模型来减少泛化误差的技术。想法是分别训练几个不同的模型,然后让所有的模型对测试示例的输出进行投票。这是机器学习中一个叫做模型平均的一般策略的例子。采用这种策略的技术是已知的
作为集合方法。这是一种有效的方法,因为不同的模型不会产生相同类型的错误。
打包包括构建 k 个不同的数据集。每个数据集都具有与原始数据集相同数量的示例,但是每个数据集都是通过从原始数据集进行替换采样来构建的。这意味着,每个数据集很可能会丢失原始数据集中的一些示例,并且还包含几个重复的示例。然后,在数据集 I 上训练模型 I。每个数据集中包括的示例之间的差异导致训练模型之间的差异。
拒绝传统社会的人
Dropout 是一种计算成本低廉但功能强大的正则化方法,dropout 可以被认为是一种使 bagging 适用于非常多的大型神经网络的方法。bagging 方法不能直接应用于大型神经网络,因为它涉及训练多个模型,并对每个测试示例评估多个模型。因为训练和评估这样的网络在运行时间和存储器方面是昂贵的,所以这种方法对于神经网络是不切实际的。Dropout 为训练和评估指数型神经网络的袋装集合提供了一种廉价的近似方法。Dropout 训练由所有子网络组成的集合,这些子网络可以通过从底层基础网络中移除非输出单元来形成。
在大多数现代神经网络中,基于一系列仿射变换和非线性,我们可以通过将其输出值乘以零来有效地从网络中删除一个单元。这一过程需要对模型(如径向基函数网络)稍加修改,径向基函数网络采用单元状态和某个参考值之间的差值。在这里,我们呈现
为了简单起见,dropout 算法是用零的乘法来表示的,但是它可以被简单地修改以与从网络中移除单元的其他操作一起工作。
辍学训练和打包训练不太一样。在装袋的情况下,模型都是独立的。在丢失的情况下,模型共享参数,每个模型从父神经网络继承不同的参数子集。这种参数共享使得用易处理的存储量来表示指数数量的模型成为可能。dropout 的一个优点是计算量非常小。在训练期间使用丢弃只需要每次更新每个例子 O(n)次计算,以生成 n 个随机二进制数并将它们乘以状态。辍学的另一个显著优势是,它不会显著限制可以使用的模型或培训程序的类型。它几乎适用于任何使用分布式表示的模型,并且可以通过随机梯度下降进行训练。
对抗性训练
在许多情况下,神经网络似乎已经达到了人类水平的理解任务,但为了检查它是否真的能够在人类水平上执行,网络在对立的例子上进行测试。对立例子可以定义为,如果对于数据点 x 附近的输入 a,模型输出在 a 处非常不同,那么 a 被称为对立例子。通过使用优化过程有意地构造对立的例子,并且模型在这些例子上具有接近 100%的错误率。
对抗训练有助于模型的正则化,因为当模型在用对抗例子扩充的训练集上被训练时,它改善了模型的泛化。
数据科学和机器学习中的法规和伦理
Artwork by: Nina Michailidou
不管我们喜欢与否,机器学习改变了我们的生活。
统计推断、强化学习、深度神经网络和其他术语最近吸引了很多关注,事实上,这是有根本原因的。统计推断扩展了我们决策的基础,并改变了决策的审议过程。这种变化构成了从我称之为前数据科学到随后的数据科学时代的本质区别。在数据科学时代,决策是基于数据和算法做出的。通常情况下,决策完全由算法做出,只有在收集、清理、构建数据和建立算法选择框架的过程中,人类才是重要的参与者(通常情况下,算法本身是通过一个指标来选择的)。鉴于这一根本性变化,在数据科学时代做出决策时,密切关注决策的扩展基础以及在考虑这一扩展基础时思维过程的变化非常重要。
“所有的模型都是错的,但有些是有用的。”
额外的步骤导致:
“所有的模型都是错误的,有些是有用的,但有些也可能是危险的.”
另一方面,大量研究证明,人类行为——以及决策——是情境驱动的[cit]。当将人类的准确性与算法的预测进行比较时,算法的预测准确性一贯甚至将专家的判断打得落花流水。对这一点的详尽讨论超出了本文的范围,但是在**附录 1、**中有一些不错的资料,以防读者有兴趣进一步研究这个主题。
好吧,接下来是什么?就像每一次技术进步一样,在某个时刻,关于西方资本主义最关键的辩论,一些悄悄话会变成声音:我们把监管的门槛放在哪里?我们需要更多的监管吗?具体来说:我们应该审核我们的算法和数据,以确保它们满足准确性、有效性和偏差的最低要求吗?
为什么监管至关重要?
每个统计学习算法都应该满足三个要求,即准确性、有效性和偏倚。简而言之,准确性表示模型的性能与基于可用数据集的可接受基线或预定义正确答案的比较。有效性考虑如何收集数据的更广泛背景,以及由于测量误差、校准失败等,数据在多大程度上没有反映真实世界。偏差是指对特定人群的预测系统性地偏低或偏高的情况,通常是由人工标注和不完善的数据质量、缺失数据,以及更一般地说,采样偏差和模型设定错误造成的。
那么,我们可以安全地假设算法应该被审计,并且它们满足上面提到的要求吗?最后,我认为与社会和健康决策系统相关的算法需要监管。然而,从数据科学的角度来看,我们应该以更广阔的视角开始开发算法,而不是仅仅依赖 MSE 和 AUC 来说明准确性。遵循并向风险评估工具延伸*负责任的机器学习原则,*算法需要确保我们的预测满足以下要求:
- 数据科学和机器学习过程应该通过设计包括人在内的系统来尽可能地增加人的干预。此外,特别是对于风险评估工具,统计决策工具的关键挑战之一是自动化偏差现象,即机器提供的信息被认为是内在可信的,不容置疑的。这可能导致人类过度依赖自动化系统的准确性或正确性。最后,主题专家应该能够验证结果和过程。他们还应该接受足够的教育,以便理解伴随算法开发的潜在假设。
- 统计模型中的偏差必须在估计值的方差容许范围内进行测量和减轻。在风险评估工具中训练算法时应该考虑的一个关键因素是所谓的遗漏变量偏差问题。每当从不包括所有相关因果因素的数据中训练模型时,就会出现遗漏变量偏差。
- 工具不得合并多个不同的预测。对于不同的风险,应衡量不同的得分,而不是反映各种结果风险的单一风险。
- 模型再现性。使机器学习模型可再现需要抽象其组成组件的过程,即数据、配置/环境和计算图。如果把这三点都抽象出来,就有可能有模型再现性的基础。决定抽象级别通常是至关重要的,因为可以专注于构建非常复杂的层来抽象具有特定数据输入/输出格式的多个机器学习库。
- 信任靠隐私。适当级别的隐私。与用户和相关利益方建立信任的一个基本方法是通过展示适当的流程和技术来保护个人数据。技术专家应该做出明确的努力来理解所涉及的元数据的潜在含义,以及元数据是否会暴露相关用户或利益相关者的意外个人信息。
给我问题而不是解决方案,尽管有时后者会有所帮助。
为了应对这些挑战并降低其对业务的风险(包括道德实践的实施),通过算法开发风险评估的公司应在以下方面投入时间:
首先,在探索性数据分析 (EDA)阶段,应进行适当的数据分析,以确定数据不平衡。此外,对特征进行相关性分析以及适当地平衡训练-验证-测试分割是非常重要的。
第二个,模型可解释性至关重要,尤其是对于复杂的数据集,它包含了所谓的黑色模型(梯度推进、神经网络等)。).为此,开发了不同的方法,包括 SHapley Additive explainions(SHAP)和 LIME 等模型。前者基于可能的联盟如何有助于作为一个整体的群体的影响的想法,这是一个从合作博弈论借用的概念,而后者侧重于局部近似。(LIME 更快,但不太准确,目前不在讨论范围内)。而且很少有像 Pachyderm 和 ModelDB 这样优秀的开源库,可以帮助数据科学家和机器学习工程师在透明性和模型再现性的基础上进行构建。
第三,当将模型投入生产时,应结合性能的连续诊断,以捕捉与模型训练数据集的任何偏差。例如,学习系统的行为应该包括随着时间的推移腐蚀发生的漂移。此外,KL Divergence 和 Wasserstein 等分数也应该用于捕捉数据偏差。
最后、在处理关键事件诊断和行动时,应始终考虑自动化偏差。结果应该由主题专家阅读,他们可以批判性地质疑结果并理解输入/输出和遵循的过程。
Ps 1:这篇文章的内容旨在告诉读者一个相当活跃的话题,所有数据科学家迟早都要解决这个问题。我试图涵盖我用作参考资料的大部分材料,以供希望进一步加深知识的读者参考。
Ps 2:请联系我以获得更正和讨论点。
参考文献
【2】:https://ethical.institute/
[4]:https://sloanreview . MIT . edu/article/the-regulation-of-ai-should-organizations-be-worried/
[5]:https://sloanreview . MIT . edu/article/the-risk-of-machine-learning-bias-and-how-to-prevent-it/
用 NLP 重构 Plutarch:第 1 部分
普鲁塔克的《高贵的希腊人和罗马人的生活》通过自然语言处理;这部分包括 NLTK 和词云
序文
普鲁塔克的《高贵的希腊人和罗马人的生活*,*也叫平行生活或简称普鲁塔克的《生活*,是一系列著名的古希腊人和罗马人的传记,从忒修斯和吕库古到阿非利加努斯·戈狄亚努斯二世。在这篇文章/教程中——继上一篇关于文本生成的文章之后——我将继续这种文本类型,并使用一些自然语言处理技术来探索这本书。*
为了便于复制,我修改了代码以适应 Google Colab,并强调了平台的独特之处——否则整个代码可以在 Python 3.6+上本地运行。代码在整篇文章中依次出现,Github 文件的链接嵌入在文章的最后,因为我可能会跳过一些次要的细节或代码。
探测
首先,让我们设置基础…
在 Colab 上,让我们将运行时类型更改为 GPU,然后导入 OS 库并保存+打印文件路径以备将来参考:
让我们将文本导入到 Google Colab 驱动器中——我们需要记住,我们在那里的文件是短暂的,我们需要在每次使用该平台较长时间后上传它们:
当执行这段代码时,我们将看到 Colab 上传文件,然后我们可以单击左边的 Colab Files 选项卡,以确保该文件与 Google 的默认示例数据目录在一起。
在这个阶段,我们将把重点放在单词级分析上,即忽略字符和句子级。因此,我们需要将文本分割成单独的单词——这就是标记化。此外,我们需要删除英语停用词,并可以对词频进行排序——所有这些都是通过使用 NLTK 和 matplotlib 实现的。
在下面的代码中,我们读取原始文本文件,对其进行标记化,删除英语停用词(NLTK 标准加上一些额外的词),绘制一个包含 40 个最常用词的图表,并将标记化的文件保存为“Plutarch_tokens.txt”以供将来使用:
整篇文章超过 674,000 字,下面是 40 个最常用单词的图表:
不出所料,凯撒是最受皇帝们欢迎的,紧随其后的是庞贝——他们是仅有的两个进入前 40 名的人。没有真正读过这本书——向那些非常熟悉文本的人道歉——人们可以很容易地感觉到,由于“战争”、“敌人”、“军队”、“朋友”、“士兵”、“权力”和“战斗”等词的出现频率,这本书在很大程度上专注于战争和冲突;我推测甚至“男人”这个词——第三个最常见的——也经常被用来指士兵。
成对的单词怎么样?
我推测“三百”——第二个最常见的词——在一个或几个例子中指的是传说中的塞莫皮莱战役(其主要历史来源是希罗多德)和在那里战斗的三百名斯巴达战士,但经过“低技术”检查(查找文本中的表达),结果证明情况并非如此。这个数字似乎在各种情况下普遍流行:罗穆卢斯征募所有成年人携带武器进入军事公司(又名军团),每个公司由三千名步兵和三百名骑兵组成,Numa 重新计算一年的天数,建议饲养蜜蜂时不要把它们放在三百英尺内,Mucius 智胜 Porsenna,威胁(不存在)三百名罗马人等待攻击,三百艘船来支持 Demetrius,Cato 召集三百名罗马人作为他的议会等。所有类型的数字评估在整个作者的文本中都很流行——有几个是最常见的二元模型,有几个是最常见的三元模型。
词干化和词汇化
为了更深入的理解,我们可能不需要担心基本相同的单词的时态和其他形式/派生词。这时词干化和词汇化就来帮忙了。
词干化通常通过砍掉单词的一部分(例如,以“-ing”结尾,复数结尾)或改变成可能与实际单词不同的词干形式(例如,“citi”代表“城市”和“city”)来帮助将单词简化为其词根(词干)。
词汇化与词干化不同,它关心单词的预期含义(包括词性和使用该单词的上下文),找到词根只是一部分,因此它是一种更复杂的算法,相对于词干化可能有更大的发展空间。幸运的是,在我们的例子中,词干化和词汇化都很容易应用,这是 NLTK 的优点:
我们会注意到,原始标记化文本有 20,214 个唯一单词,平均 6.48 个字母,而词汇化文本有 17,864 个,平均 6.34 个字母,词干化文本有 12,722 个,平均 5.49 个字母;砍真的在后一个里表现出来了。现在,我们有三组标记可供选择,以进行进一步的分析。
以上代码如下:
词云
单词云是可视化文本的一种很好的方式,但在处理大型书籍时显然有其局限性——很难在一个计算机屏幕上看到 20,000+的单词。此外,可能不属于 NLTK 或 wordcloud 库的无用(用于频率计数)单词可能会脱颖而出,并从其他单词那里夺走不动产——幸运的是,NLTK 和 wordcloud 库都可以轻松增加它们的停用词;前者的调整在前面展示过,后者包含在 Github 笔记本中。
让我们在标记化的文本上运行基本的单词云:
请注意,当我使用预定义的停用词时,没有必要将它包含在代码中,因为文本本身就是停用词。然而,我想保留这一行作为提醒,以防单词 cloud 独立于 NLTK 运行,或者需要应用库自己的停用词。
现在让我们运行词干词的词云:
wordcloud library 的一个很酷的功能是叠加图片的能力——示例库给了我们各种可能性的感觉,包括使用图片和自定义颜色。有了上面的代码,我利用机会把 cloud 这个词和罗马皇帝奥古斯都的一张图片结合起来。
对于词汇化的单词集,单词云图片在文章的顶部——我不确定这种美学是不是库作者的本意,但它起作用了。代码与上面的非常相似,但如果你需要查找,它在 Github 上。
中断
在本文的第 1 部分中,我们着重于利用 NLTK 和 wordcloud 库来探索一个文本示例——本文中显示的全部代码以及更多内容可以在 Github 上找到。在第 2 部分中,我们将深入研究单词嵌入和可视化,
用 NLP 重构 Plutarch:第 2 部分
普鲁塔克通过自然语言处理研究希腊和罗马贵族的生活:这部分包括 word2vec、降维(PCA 和 t-SNE)和 Tensorflow 投影仪
序文
普鲁塔克的《高贵的希腊人和罗马人的生活,也被称为平行生活或者仅仅是普鲁塔克的生活*,是一系列著名的古希腊人和罗马人的传记,从忒修斯和吕库古到阿非利加努斯·戈狄亚努斯二世。在这篇文章/教程中——继最近出版的第 1 部分之后——我将继续使用一些自然语言处理技术来探索这本书。*
为了便于复制,我将代码改编为 Google Colab,并强调了该平台的独特之处——否则整个代码都可以在 Python 3.6+上本地运行。代码在整篇文章中依次出现,Github 文件的链接嵌入在文章的最后,因为我可能会跳过一些次要的细节或补充代码。
古登堡计划已经提供了本分析中使用的文本。
设置事物
在 Colab 上,我们先把运行时类型改成 GPU,然后导入 OS 和正则表达式库,保存+打印文件路径备查:
*import os
import re
fpath = os.getcwd(); fpath*
让我们将文本(Plutarch.txt)导入到 Google Colab 驱动器中——我们需要记住,我们在那里的文件是短暂的,我们需要在每次使用该平台较长时间后上传它们:
上面的代码也可以在 Colab 的 Code Snippets 选项卡下找到——还有许多其他非常有用的代码。当执行这段代码时,我们将看到 Colab 上传文件,然后我们可以单击左边的 Colab Files 选项卡,以确保该文件与 Google 的默认示例数据目录在一起。
接下来,我们需要对文本进行标记—但是,与上一篇文章不同,我们希望保持类似句子的结构,并且不希望删除停用词:
通常在 NLP 任务中,停用词不经思考就消失了,而且在许多情况下是有意义的。然而,由于我们将处理单词嵌入,其中单词的训练和它的上下文是相互依赖的,我们希望确保这样的上下文(停用词是其中的一部分)得到保留。
单词嵌入和相似性
让我们继续训练文本,以便我们可以例如计算彼此之间的单词相似度(被算法理解为几何邻近度)。如果你更喜欢从更理论化的方法开始,我认为这个斯坦福大学 word2vec 讲座非常棒——可能最好是喝一杯你最喜欢的饮料。我获得的信息金块之一是每个单词都有两个向量:作为中心单词和上下文单词(视频中的 41:37),因此当我在一个散点图的两个地方看到同一个单词时,我最初的困惑得到了解决。
接下来,让我们使用 word2vec 模型的四个变体:连续单词包(CBOW,基于上下文单词预测当前单词)和 skip-gram(CBOW 的逆-基于当前单词预测上下文单词),每个都具有负采样和分层 softmax 选项:
在上面的代码中, min_count 允许根据单词的频率忽略它们,所以在这种情况下,我们希望每个单词都被计算在内;尺寸表示尺寸的数量;窗口是当前字和预测字之间的最大距离; iter 是文本上的历元/迭代次数; sg=1 表示我们正在使用 skip-gram,否则为 CBOW hs=1 表示我们在使用分层 softmax,否则就是负采样(分层 softmax 对于不常用的词更好)。如果你想更深入了解,还有更多选择。
四个选项的结果差异很大,但为了时空的利益,让我们更深入地研究第一个选项,负采样的 CBOW:
我们会注意到“凯撒”和“国王”之间的相似度非常高,考虑到这两个词是统治者的同义词,这是有道理的——尽管当时罗马人厌恶“国王”的称号。下面是上面代码中的类似单词:
正如我们将看到的,皇帝的名字与其他皇帝和政治家的名字非常相似。“百”是接近其他数字和货币名称。“国王”与皇帝的名字和“死亡”联系在一起——可能部分是因为那时政治中的暗箭伤人更加字面化。真理接近上帝,反之亦然。
您的结果可能与我的不同,因为哈希随机化和模型不局限于单个工作线程(这里的解决方案)。
降维
除非你是《星际迷航》中的 Q,为了可视化你的单词嵌入,你需要大幅减少维数,理想情况下最多两到三个。现在,我们有 100 个。有两种流行的方法,我们将在本文中提到:主成分分析和 t-SNE。
PCA ( 主成分分析)是一种线性和无监督的方法,允许提取数据的低维表示,从说明数据中大部分可变性的主成分开始:
该片段将产生一个数据帧,每个单词有两个坐标。
t-SNE(t-分布式随机邻居嵌入)是一种非线性且无监督的降低数据维数的方法。它主要集中在可视化上,所以——不像 PCA——我们不能在超过三个维度上运行它。有一篇关于如何有效使用 t-SNE 的优秀文章。
运行下面的代码需要一段时间,所以请确保您有时间:
如果你想试验各种超参数的变化,代码很容易操作;这对于 SNE 霸王龙来说尤其重要,因为它可以更好地了解自己的行为。t-SNE 的另一个棘手之处是它的非确定性(概率性)本质,这意味着每次运行时,我们可能会对相同的数据得到不同的结果——这是因为用于最小化目标函数的梯度下降优化是随机启动的。然而,尽管它比 PCA 年轻 75 岁(SNE 霸王龙是在 2008 年发明的,而 PCA 是在 1933 年发明的),SNE 霸王龙还是很管用。
形象化
现在我们已经控制了尺寸,我们可以开始画一些图了。然而,如果我们试图绘制整个唯一单词集,我们将得到这个(PCA 版本):
即使在扩大图片后,也很难提取东西——我甚至没有贴标签,因为这样散点图看起来简直糟透了。我们稍后将使用 Tensorflow 投影仪解决这个问题,但现在让我们只关注相似词子集,从 PCA 二维图开始:
*from matplotlib.pyplot import figure
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
from sklearn.decomposition import PCAfig = matplotlib.pyplot.gcf()
fig.set_size_inches(18, 14)simwords = sum([[k] + v for k, v in similar_words.items()], [])
wvs = model_cbow.wv[simwords]pca_wvs = PCA(n_components=2, random_state=0)
np.set_printoptions(suppress=True)
Tpca = pca_wvs.fit_transform(wvs)
labels = simwordsplt.figure(figsize=(16, 12))
plt.scatter(Tpca[:, 0], Tpca[:, 1], c='purple', edgecolors='purple')
for label, x, y in zip(labels, Tpca[:, 0], Tpca[:, 1]):
plt.annotate(label, xy=(x, y), xytext=(0, 0), textcoords='offset points')*
我们看到数词聚集在图的右侧。在左上角,我们看到许多皇帝,随着我们沿着 Y 轴往下走,皇帝的名字越来越与地理名称混在一起。t-SNE 当量看起来不同,但相似的距离逻辑是显而易见的:
使用张量流投影仪进行可视化
如果不提到谷歌的一个令人惊叹的可视化工具——tensor flow Projector,我们会觉得很不妥;它允许动态地与单词嵌入进行交互,并通过点击按钮进行更深入的挖掘。
在左上角,我们选择 Word2Vec All,在右边的搜索栏中,我们键入并单击“caesar”。原始空间中最近的点显示在下面,我们可以在平台上进行切换,在 PCA 和 t-SNE 之间切换,增加邻居的数量,选择球形化数据,选择余弦或欧几里德距离等。让我们根据我们的普鲁塔克分析将这些结果与“ceasar”进行比较。
但首先我们应该为投影仪准备数据,即两个 csv / tsv 文件,其中一个包含向量,另一个包含这些向量表示的单词(投影仪称之为元数据):
*import pandas as pd
project_wvs = [(term, voc.index, voc.count) for term, voc in model_cbow.wv.vocab.items()]
project_wvs = sorted(project_wvs, key=lambda k: k[2])
ordered_terms, term_indices, term_counts = zip(*project_wvs)
df_cbow100 = pd.DataFrame(model_cbow.wv.vectors[term_indices, :], index=ordered_terms)df_cbow100['word'] = df_cbow100.index
df_cbow100['word'].to_csv('df_cbow100word.tsv', sep='\t', encoding='utf-8', index=False, header=False)df_cbow100vector = df_cbow100.iloc[:,0:100].copy()
df_cbow100vector.to_csv('df_cbow100vector.tsv', sep='\t', encoding='utf-8', index=False, header=False)*
上面,我们从之前生成的 word2vec 输出中创建了一个 dataframe (df_cbow100)。然后,我们将数据帧分成所需的仅标签(df_cbow100word.tsv)和仅矢量(df_cbow100vector.tsv)文件。要将文件下载到我们的本地机器上,我们只需双击 Colab 中相应的文件名。
然后,让我们回到投影仪,点击左上角的“加载”按钮,上传两个文件。瞧——现在我们自己的单词嵌入被反映出来了,我们可以使用投影仪工具来操纵我们认为合适的可视化。正如所料,与“caesar”最近的点相对于 Word2Vec All 有很大不同,word 2 vec All 是在更大的数据集上训练的。
结论
Github 上的提供了完整的代码和更多内容,而《重新想象普鲁塔克》的第 1 部分可以在这里阅读。在 Reimagining Plutarch 的两个部分中,我们谈到了使用 NLTK、Wordcloud、Word2Vec 嵌入和可视化来分析文本的方法,并为那些有兴趣深入研究的人提供了额外的资源。NLP 相关知识和编程诀窍的可访问性,以及像 Google 的 Colab 这样的工具,使得实现高级概念和跟踪该领域的进展比以往任何时候都更容易。
用 Tensorflow 2.0 重新想象 Plutarch
Original photo by Sandra Povilaitis; Vincent van Gogh style transferred using VGG19
通过 TensorFlow 2.0 中的单词嵌入看普鲁塔克的希腊和罗马贵族生活
序文
普鲁塔克的《高贵的希腊人和罗马人的生活,也被称为平行生活或者仅仅是普鲁塔克的生活*,是一系列著名的古希腊人和罗马人的传记,从忒修斯和吕库古到阿非利加努斯·戈狄亚努斯二世。*
在最近发表的文章中,我们研究了使用 gensim 库训练我们自己的单词嵌入。这里,我们将主要关注利用 TensorFlow 2.0 平台的单词嵌入层;目的是更好地理解该层是如何工作的,以及它如何有助于大型 NLP 模型的成功。
* [## 用 NLP 重构 Plutarch:第 2 部分
普鲁塔克通过自然语言处理研究希腊和罗马贵族的生活:这部分包括 word2vec…
towardsdatascience.com](/reimagining-plutarch-with-nlp-part-2-dc4e360baa68) [## 用 NLP 重构 Plutarch:第 1 部分
普鲁塔克通过自然语言处理研究希腊和罗马贵族的生活:这部分包括 NLTK 和 word…
towardsdatascience.com](/reimagining-plutarch-with-nlp-part-1-24e82fc6556)
为了便于复制,我将代码改编成了适用于 Google Colab 的代码,并强调了该平台的独特之处——否则,整个代码可以使用 Python 3.6+和相关包在您的本地机器上运行。整篇文章中都有代码,但我会跳过一些补充或次要的代码——完整的代码可以在我的 Github 库中找到。
古登堡计划已经提供了本分析中使用的文本。
设置事物
在 Colab 上,让我们将运行时类型更改为 GPU,然后导入最新的 TensorFlow 版本——下面的代码片段仅适用于 Colab,否则只需使用 pip 或 conda install 命令在您的机器上上传最新的 TensorFlow 。
我们还需要 OS 和正则表达式库,然后保存&打印文件路径以备将来参考:
import os
import re
fpath = os.getcwd(); fpath
让我们将文本(Plutarch.txt)导入到 Google Colab 驱动器中——我们需要记住,我们在那里的文件是短暂的,我们需要在每次使用该平台较长时间后上传它们:
上面的代码也可以在 Colab 的 Code Snippets 选项卡下找到——还有许多其他非常有用的代码。当执行这段代码时,我们将看到 Colab 上传文件,然后我们可以单击左边的 Colab Files 选项卡,以确保该文件与 Google 的默认示例数据目录在一起。
让我们阅读文本并做一些基本的正则表达式操作:
import recorpus = open(fpath + '/Plutarch.txt', 'rb').read().lower().decode(encoding='utf-8')corpus = re.sub('\n', ' ', corpus) #remove new line
corpus = re.sub('\r', ' ', corpus) #remove "return"
因为我们将把文本分成句子,所以新行对我们的分析没有意义。此外,在使用文本标记器时,我注意到“\r”(表示回车)会产生错误的唯一单词,比如“we”和“we \ r”——同样,这在我们的例子中并不重要。因此“\n”和“\r”都需要删除。
建立字典
随着我们逐渐接近实际的单词嵌入,让我们将文本标记成句子:
import nltk
from nltk.tokenize import sent_tokenize
nltk.download('punkt') #need in Colab upon resetting the runtime
# tokenize at sentence level
sentences = nltk.sent_tokenize(corpus)
print("The number of sentences is {}".format(len(sentences)))
我们会看到这篇课文总共有 16989 个句子。接下来,我们需要计算最长句子中的单词数——原因将在本教程的后面变得显而易见:
from nltk.tokenize import word_tokenizeword_count = lambda sentence: len(word_tokenize(sentence))
longest_sentence = max(sentences, key=word_count)
length_longest_sentence = len(word_tokenize(longest_sentence))print("The longest sentence has {} words".format(length_longest_sentence))
原来最长的句子有 370 个单词长。接下来,让我们将整个文本转换为正数,以便我们可以开始使用 TensorFlow 说一种通用语言:
从上面我们还发现,该文本有 20241 个唯一的单词,因为记号赋予器对每个相同的单词只赋予一个数字。为了标准化所有句子的长度(即,将输入数据转换为单个相同形状的张量,以使其可处理/更容易用于模型——我们在这里是为了满足机器的需求),我们需要将表示单词的数字列表(sent_numeric)转换为实际的字典(word_index),并添加填充。我们也可以将截断很长的句子和填充短句子结合起来,但是在这种情况下,我们只填充最长句子的长度。
词汇大小(也称为独特单词的数量)将增加 1,达到 20,242,这是添加 0 进行填充的结果。键入“data[0]”(即第一句话),看看第一句话在填充后会是什么样子。
为了能够在单词和它们的数字表示之间来回转换,我们需要为查找添加反向单词索引:
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])def decode_data(text):
return ' '.join([reverse_word_index.get(i, '?') for i in text])
仔细检查单词 indexing 和 conversion 是有意义的——一个错误就可能使整个数据集混乱不堪,让人无法理解。在我的 Github 库中可以找到转换前后的交叉检查的例子。
Photo by Sandra Povilaitis
模型
最后,让我们构建并运行模型。TensorFlow 提供了一个不错的教程,我们正在根据自己的需要进行修改。
但是首先,我们可以简单地只运行嵌入层,这将产生一个嵌入的数组。我读到过这样一个数组可以被保存并在另一个模型中使用——是的,它可以,但是除了跳过新模型中的嵌入步骤之外,我不太确定它的实用性,因为为每个单词生成的向量对于所解决的问题是不可知的:
我们不会在上面花太多时间,而是将重点放在嵌入只是第一部分的模型上。
在导入相关库之后,让我们继续构建新的、非常基本的模型架构:
嵌入层(通常可用作模型中的第一层)会将数字编码的唯一单词序列(提醒一下,其中 20,241 个单词加上填充编码为零)转换为向量序列,后者在模型训练时被学习。每个向量将有 100 个维度(embedding_dim=100),因此我们将得到一个 20242 x 100 的矩阵…输入长度将固定为最长句子的长度,即 370 个单词,因为每个单词由于填充而被模型感知为具有相同的大小。Mask_zero 通知模型输入值 0 是否为应被屏蔽的特殊填充值,这在模型可以处理可变输入长度的重复图层中特别有用。
在对足够多的有意义的数据进行训练之后,具有相似含义的单词将可能具有相似的向量。
下面是模型总结(带有额外密集层的模型在 github 库中):
在模型摘要中,我们将看到嵌入层的参数数量是 2,024,200,这是 20,242 个单词乘以嵌入维度 100。
前面提到的 TensorFlow 教程使用了一个评论数据集,每个评论根据积极或消极的情绪标记为 1 或 0。我们没有奢侈的标签,但仍然希望测试这个模型,所以将简单地创建一个 0 的数组,并附加到每个句子;模型需要这样的结构。这不会是机器智能第一次也不会是最后一次遇到无法解决的任务,但仍然会迫使我们找到解决方案。让我们来训练这个模型:
import numpy as npadam = tf.keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False)
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])batch_size = 16989 #number of sentences
data_labels = np.zeros([batch_size, 1])history = model.fit(
data,
data_labels,
epochs=200,
batch_size=batch_size,
verbose = 0)
嵌入被训练。在我们转向可视化之前,让我们快速检查一下 gensim 上的单词相似性。首先,我们需要创建 vectors 文件——临时保存在 Colab 中或下载到本地机器:
f = open('vectors.tsv' ,'w')
f.write('{} {}\n'.format(vocab_size-1, embedding_dim))
vectors = model.get_weights()[0]
for words, i in tokenizer.word_index.items():
str_vec = ' '.join(map(str, list(vectors[i, :])))
f.write('{} {}\n'.format(words, str_vec))
f.close()# download the file to the local machine by double-clicking the Colab file or using this:
try:
from google.colab import files
except ImportError:
pass
else:
files.download('vectors.tsv')
第二,让我们
import gensimw2v = gensim.models.KeyedVectors.load_word2vec_format('./vectors.tsv', binary=False)w2v.most_similar('rome')
最后,让我们检查一下庞贝和凯撒之间的相似性,这在我们之前培训的 CBOW 模型中显示得很高:
round(w2v.similarity('pompey', 'caesar'),4)
词与词之间的关系很高。同样,正如人们所料,凯撒表现出与罗马高度相似。
对于那些对更复杂的模型感兴趣的人来说,额外的变体,包括递归神经网络(长短期记忆)可以在我的 Github 文件中找到,但请记住,它们的训练速度将比上面的简单模型慢得多。
形象化
对于嵌入的可视化来说,TensorFlow Projector 无与伦比,因此让我们创建矢量和元(即对应于这些矢量的单词)文件供其使用:
在本地导入文件,然后我们可以前往 TensorFlow 的投影仪,上传文件以替换默认数据,并尝试网站上可用的各种选项。这里是文本的整个向量空间的主成分分析视图:
这是 100 个单词的向量空间,这些单词和“罗马”最相似。
结论
在本文中,我们简要地看了一下单词嵌入层在深度学习模型中的作用。在这种模型的上下文中,该层支持解决特定的 NLP 任务,例如文本分类,并通过迭代训练单词向量,使其最有助于最小化模型损失。一旦模型被训练,我们可以通过相似性计算和可视化来检查嵌入层输出。
嵌入层还可以用于加载预训练的单词嵌入(例如 GloVe、BERT、FastText、ELMo),我认为这通常是利用需要这种嵌入的模型的更有效的方式,部分原因是生成它们所需的“工业级”工作和数据量。然而,在专门文本的情况下,尤其是如果可以训练单词嵌入的语料库相当大,训练自己的嵌入仍然会更有效。*
强化学习:微妙的介绍
1996 年 2 月 10 日,IBM 的深蓝人工智能在一场国际象棋比赛中击败了世界冠军加里·卡斯帕罗夫。
谷歌的阿尔法围棋人工智能是世界上最好的围棋选手,一次又一次地击败了世界冠军。
但是这怎么可能呢?计算机怎么可能比人类聪明?答案… 强化学习。
什么是强化学习?
强化学习是机器学习和 AI 的一个分支。创建模型来做某些事情需要一种非常特殊的方法。强化学习的目标是教会计算机/机器以高度成功的方式执行某项任务。(例如。赢得一场国际象棋比赛,玩马里奥赛车并获胜,等等。)
注意什么是强化学习也很重要。这些模型是人工特定智能(ASIs),这意味着它们只能执行非常特定的任务。这些不是普通的人工智能机器(AGIs),不能执行任何任务。这是人工智能的下一个目标,然而在本文中不会讨论。
A reinforcement learning model playing Mario
强化学习是如何工作的?
为了理解强化学习的本质,让我们用这个简单的类比来分解它:
想象一个孩子第一次看到壁炉。孩子对壁炉充满了好奇和好奇…所以他很自然地靠近了壁炉。当孩子靠近时,它感觉到壁炉的温暖,因此孩子感到温暖和快乐。
此外,孩子想感受更多的快乐和温暖,所以孩子靠近壁炉,直到它能碰到壁炉。* 🔥* 孩子受伤了,从壁炉边退了回来。
下一次孩子遇到壁炉时,它已经学会了不要靠得太近,而是保持一个合理的距离,这样孩子就会得到温暖的奖励,而不会受到被烫伤的惩罚。这个动作是取悦孩子的。
感受温暖的回报是这个场景中孩子的目标。如果我们从人工智能的角度来看,人工智能或代理希望通过执行一些动作序列来最大化一些奖励值。
人工智能就像孩子一样,受到奖励的激励。他们都想获得尽可能多的奖励,这可以通过试错来实现,在试错过程中,他们学习寻找奖励时的模式。在儿童场景中,儿童很快了解到靠得太近会牺牲奖励,不值得。一台计算机也可能做同样的事情,尝试不同的事情,直到它找到一种给予持续高回报的模式。它强化了给予高回报的模式,并持续完成特定的任务。
环境是行动发生或任务执行的地方。例如,在我们上面的场景中,环境是有壁炉的房间。该环境还可以是视频游戏环境、诸如保龄球馆或厨房的某些场景房间以及其他一切。特定任务的环境范围。
代理是控制某个实体的计算机或机器。例如,在我们的场景中,代理是孩子。另一个例子是计算机控制超级马里奥兄弟中的马里奥。代理对实体可以执行的控制是有限制的。它只能使用一组预定义的规则。
动作是由代理执行的一个移动或一组连续移动。例如,在我们的场景中,它靠近或远离壁炉。简单地说,这是我们试图解决的问题的实际部分。我们如何创造适合任务的最佳行动。
奖励是对它在一个环境中完成一项任务的表现以及如何激励代理变得更好的衡量。在我们的场景中,奖励是壁炉的温暖,这也是代理做了好事的一个指标。
最后,状态是提供给代理的数据的计算,基本上告诉它在环境中的位置。在我们的场景中,是让孩子在完成一个动作后知道它在哪里。它是用来计算更多的行动,并达到一个总体目标。
它们都通过一个简单的程序连接起来。首先,我们的代理做一个动作。该动作通过环境进行处理,然后将奖励和状态反馈给代理。奖励告诉它动作做得有多好,以及代理在环境中的位置,所以它知道将来要做什么。
代理人不断尝试,直到有人奖励高价值。它将开始更多地实现这些模式,直到为环境创建一个系统。在这一点上,它将知道如何在环境中的任何状态下执行任务,从根本上解决我们的问题!
然而,仍然有一个问题需要回答……我们如何创造有效的奖励,使代理能够完成任务?
奖励——强化学习的原则。
奖励是智能体/计算机在特定任务中变得更好的动机,例如,在国际象棋中,奖励可以是获胜。因为奖励的必要性是强化学习的基础,所以了解如何通过一个叫做奖励形成的过程来创建有效的奖励系统是很重要的
对于机器来说,收敛于某些行为,重要的是学会知道什么是想要的,什么不是。比如玩单人纸牌或者跳棋的时候想要的目标是什么?这对我们来说似乎是显而易见的,但对计算机来说就不那么清楚了。在这些情况下,目标就是简单地获胜,这意味着达到某些参数。所以在给机器塑造奖励模型的时候,你可以告诉它,当它赢的时候,给它+1 奖励,输的时候,-1。这迫使机器想办法总是达到+1,这是我们的预期目标。
但是,我们如何为不像游戏那样明确的东西制定奖励,比如自动驾驶汽车?诀窍是始终考虑更大的目标。在这种情况下,它是在不坠毁或造成伤害的情况下到达 a 点到 b 点。这本身就是对机器的奖励,不管它能走多远而不崩溃。因此,无论何时你试图创建一个奖励函数,只要简单地问自己机器的目标是什么,并为这些参数编写一个程序。理论上计算机应该会变得更好。
因此,我们具备了创建这些代理/机器来执行特定任务的知识…所以,让我们开始吧!
嗯…还有一件事要弄清楚…
模拟和如何训练强化学习模型
很容易看出很多游戏都经过了强化学习。经典的视频游戏,如国际象棋、乒乓球、马里奥、跳棋、围棋……(你明白了)都是电脑碾压人类的游戏。
为什么?因为很简单。
在一个游戏中,有规则可循,有许多迭代。一次模拟许多游戏很容易,计算机可以以指数速度学习。电脑不会累,饿,困等。不像人类那样只有有限的时间来学习,计算机可以连续学习几个小时。更不用说,他们能够每秒钟玩多个游戏。这就是为什么计算机可以轻易胜过我们的根本原因。难怪一个 40 天的国际象棋程序能够击败国际象棋冠军加里·卡斯帕罗夫。
但是那些没有具体规则,可以应用到现实世界的任务呢?我们如何应用强化学习?
以开车为例。如果让一台机器在现实生活中“试错”一辆汽车,那就太傻了。你只能想象它会带来的恐惧。那么我们如何应用强化学习呢?同样的方法,用模拟。
“trial and error” approach in real life 😬
我们可以在一个游戏引擎中模拟我们世界的物理,比如 Unity。我们可以给计算机特定的规则,比如前进和后退。我们可以把机器放入一个类似真实世界的环境,比如道路。我们用我们的奖励系统在环境中训练机器,直到它变得足够好,几乎不犯错误。
然后我们把我们的模型放入真实世界的机器中,在那里它做完全相同的事情。不需要真实世界的混乱!
嗯…有一点不好的地方…
这样做的缺点是模拟只是…模拟。没有什么能完全模拟我们的世界。如果环境和现实世界之间有一点点差异,这个模型可能在现实世界中不起作用(看看 gif 就知道了)。在为现实世界中的应用程序训练模型时,如果你能克服这个障碍,你就能成功。但是为了确保它能正常工作,你必须仔细观察环境,以确保它是正确的。
这就引出了一个问题…有了创建真实世界钢筋模型和机器的能力…在真实世界中有哪些应用?
真实世界的应用
自动驾驶汽车
通过模拟训练,自动驾驶汽车成为强化学习的对象已经有一段时间了。从自动驾驶汽车到自动驾驶飞机,自动驾驶汽车的领域是无限的。
卫生保健
强化学习已经被用来通过在模拟中反复试验来找出哪种诊断对某些药物最有效。随着 AI 接管医疗行业,试错将变得更加有用。
制造业
在传统制造中,机器会执行定时程序移动。强化学习的加入,让这些机器更能适应做某项任务,随心所欲地改变任务。这模仿了许多行业的快速变化。
关键要点
- 强化学习是通过在一个环境中使用奖励系统来训练一个智能体执行某个任务。
- 奖励是强化学习的原则,我们使用奖励成形来创建强化学习模型的奖励模型。
- 模拟可以用来训练代理
- 强化学习如今在很多行业都有应用。
用井字游戏进行强化学习和深度强化学习
在这篇文章中,我想分享我在井字游戏中实现强化学习和深度强化学习方法的项目。
该文章包含:
1.将博弈严格定义为马尔可夫决策过程。
2.如何实现称为 TD(0)的强化学习方法,以创建一个在游戏的每个状态下都发挥最佳行动的代理。
3.如何实现深度强化学习,这与第 2 节非常相似,但这里我使用了神经网络来学习价值函数(什么是价值函数将在后面定义)。
所以让我们开始…
井字游戏的马尔可夫决策过程
为了简单起见,让我们将第一个玩家定义为玩 X 符号的玩家,将第二个玩家定义为玩 O 符号的玩家,让我们将注意力集中在 X 玩家上。
首先要注意这不是一个对称博弈,X 有优势,因为他先玩,他最多有 5 次机会,而 O 最多有 4 次机会。
MDP(马尔可夫决策过程)是一个 4 元组,它包含:
- 状态设置
当轮到玩家 X 出牌时,他的状态集包含所有的棋盘,所以在我们的例子中,状态集包含所有具有相同数量的 X 和 O 的棋盘。例如,空板处于 set 状态。此外,当游戏结束时,所有的棋盘也在状态集中,它们被称为结束状态。
我们将把一个状态写成一个 9 字符串,其中包含数字 1-9,从左上到右下代表棋盘上的空白点,用 X 和 O 代替玩家所在位置的数字。例如,字符串 X234O6789 表示 X 在左上角播放,O 在中间播放的状态。
2。 动作设定(一)
动作集包含了玩家 X 可以玩的所有选项,也就是特定状态下的所有数字。
这里要注意的是,玩家 X 出牌后的棋盘不是玩家 X 的状态集中的状态,因为 X 不能在这个棋盘上执行某个动作(轮到 O 了)。该动作将导致的新状态将是玩家 O 完成其回合后的棋盘。
3。概率函数§
概率函数,定义通过采取行动从 S 到 S 的转移概率*a-*p:s✕s✕a→【0,1】。在我们的例子中,S 取决于 O 的话轮。我们可以把它想成:X 采取一个动作,环境做出反应,在 O 的回合后返回一个新的状态。每个可能的状态都有自己的概率,而概率取决于 O 的玩家。
这里需要注意的是,我们的目标是找到一个函数,将一个状态映射到 X 可以采取的最佳动作。这个动作显然取决于 O 怎么玩(因为它改变了概率函数)。举例来说,如果我们和一个人类玩家或者一个同样随机的玩家进行游戏,那么这个动作可能会有所不同。
例如,假设我们开始了一个新游戏(新一集),状态是空板,我们需要执行一个动作。我们有 9 个选择。假设现在,我们选择在棋盘中间玩。现在参与人 O 有 8 个选择。如果 O 是一个同样随机的玩家,他将以同样的概率从 8 个选择中挑选一个。对于那些熟悉条件概率的人,我们可以这样写:
P(S =O234X6789|S =0123456789,a = 5)= P(S = 1 o 34 x 6789 | S = 0123456789,a=5) = …=1/8
对于人类玩家来说,在角落玩比在边缘中间玩更有可能,所以概率函数会不同。
4。奖励®
奖励:我们将它定义为 1 如果 X 赢了,-1 如果 O 赢了,0.5 如果是平局,否则 0。
政策和价值功能
策略是从状态集映射到动作集的功能。最优策略是使每个州的未来回报最大化的策略。
当从状态 S 开始并遵循策略π时,策略π的价值函数是将状态 S 映射到期望回报(未来回报的平均值)的函数。最优价值函数是最优策略的价值函数。
我们的目标是学习这个最优值函数,然后根据这个函数作用于每个状态。但首先,让我们假设我们已经知道这个函数,我们如何从一个给定的状态中选择我们的最优行动?
我们假设对手,O 玩家是一个理性的玩家,在 X 的回合之后,他会采取使下一个状态的价值最小化(从而使他的价值最大化)的行动。我们将选择使所有可能的下一个状态的最小值最大化的动作。
比如在空板,X 有 9 个选项可以玩。每个选项可以导致 8 种不同的状态(O 有 8 个选项可以玩)。对于每个 X 移动,我们将从下一个状态计算 8 个可能的值,并记住这些值的最小值。我们将有 9 个价值,我们将决定采取最大化这 9 个价值的行动。
强化学习代理
我们现在的目标是学习最优值函数,并创建一个根据该函数进行最优移动的代理。为了学习价值函数,我们将使用 TD(0)方法:
首先,我们将每个状态的值函数初始化为 0。对于游戏访问的每一个状态,我们都会按照更新后的规则更新前一个状态的值函数:v(s)= v(s)+α(v(s ')+R-v(s))
其中 s 是要更新的状态(前一状态)*s’*是当前状态, R 是奖励, α 是学习率。我们将选择我们的下一步棋作为概率为 0.8 的最优棋和概率为 0.2 的随机棋,以鼓励探索。
每学习 100 集,我们将随机播放 100 集最佳动作,以检查我们的学习。
在下图中,我们可以看到学习过程。左图对应 X 玩家,右图对应 O 玩家。开始时,我们有两个随机的玩家,由于游戏的性质,X 赢的多一点。在学习过程之后,我们可以看到每个玩家几乎总是在学习和获胜。
深度强化学习代理
现在我们可以尝试用不同的方法来学习价值函数。我们不需要学习一个将每个状态映射到一个值的值函数,而是可以尝试将这个函数学习为一个神经网络,它接受一个状态并返回一个值。
馈送给网络的状态是长度为 9 的向量。x 标记为 1,空点标记为 0,O 标记为-1。
该网络包含两个隐藏的密集层,第一层包含 27 个具有 Relu 激活功能的神经元,第二层包含 18 个具有 Relu 激活功能的神经元。网络的最后一层是具有 1 个输出神经元的密集层,该输出神经元具有线性激活函数。
为了训练网络,我们为每个状态计算一个目标值:*target = v(s)+α(v(s ')+R-v(s))*其中 v(s) 和 v(s’) 是从神经网络本身计算的。每次目标计算后,执行一次随机梯度下降迭代。这就是为什么在这个井字游戏的特殊例子中,与以前的方法相比,需要更多的片段来训练网络以执行良好的结果。
这种方法被称为深度强化学习,因为我们在这里使用的是深度学习方法。
为了实现神经网络,我使用了 Keras 框架。
下图显示了深度学习方法的学习过程:
摘要
在这篇文章中,我们看到了两种创建完美井字游戏玩家的方法。第一种方法使用直接的方法——在每个状态学习状态的值。这种方式需要多次访问每个状态,以便了解完整的值函数。在这种情况下是可能的,因为游戏没有很多状态。
第二种方式是一种更通用的方式:训练一个将状态映射到值的神经网络。神经网络学习闭合状态(如旋转、镜像等。)有相同的价值观。这意味着我们不需要访问所有国家。然而,因为我们使用随机梯度下降,我们需要播放更多的剧集,以便学习一个完美的神经网络。
原代码可以在:https://github.com/giladariel/TicTacToe_RL.git找到
你现在可以自己和代理人比赛,看看你是否能赢。
用一个简单的游戏强化学习和可视化
Photo by Chris Ried on Unsplash
游戏是学习强化学习(RL)概念的最佳方式。但是选择极其琐碎的游戏作为例子并不能反映这种技术的真正力量。另一方面,选择一个有很多图形组件的复杂游戏是一个很酷的演示,但是对于新手来说很难跟上。
本文将通过一个简单的游戏来指导你,这个游戏使用基于 Q 表的强化学习,并且很容易使用 Tkinter 来可视化。游戏的目标是让一个随机移动的绿色球学会如何到达一个小圆圈的中心。如果球没有在 200 步内到达现场,它就输了,游戏重新开始。
运行 RL 训练及其可视化的所有代码都可以在这里获得
Basic Gameplay
要进行任何 RL 培训,需要明确 3 件事情。
- 代理:它是游戏的组件,会学习一个策略并做出决定。对于我们的游戏来说,代理就是绿球。
- 状态:把状态想象成代理在游戏中特定点的“描述”。状态需要捕捉决定代理的最终目标(或中间目标)是否实现所需的所有信息。这些信息应该是必要和充分的。在我们的游戏中,州被绿球的 2D 坐标捕获。它们足以告诉我们球是否到达了期望的最终位置。
- 动作:动作是改变代理状态的任何事情。通常一个代理在任何给定的状态下都有一个有限的可能动作集。最佳行动的选择最初是随机的(探索阶段),代理人试图找出采取所选行动的后果。一旦代理开始通过多轮游戏获得经验,它就开始制定一个政策来指导它的行动选择,而不是随机探索。这就是我们所说的剥削阶段。对于我们的游戏,代理只有 8 个可能的方向可以选择。但是我们给它一个选择,让它每边移动 10 个像素或者 20 个像素。因此,动作集的大小为 16。
让我们检查一下为我们的游戏设置状态空间(所有可能状态的集合)和动作空间(所有可能动作的集合)的代码。
mov_list = [-20,-10,10,20]
#Set up Q table
state_space = {}
temp_list = []
for n in range(0,500,10):
for m in range(0,360,10):
temp_list.append((n,m))
for k in range(1800):
state_space[k] = temp_list[k]action_space = {}
temp_list = []
for n in mov_list:
for m in mov_list:
temp_list.append((m,n))
for k in range(16):
action_space[k] = temp_list[k]
这段代码假设游戏窗口为 500 像素 x 360px 像素。所以,我们的状态空间应该有 18000 的大小(代理可以到达的每个 x,y 像素)。但是我们已经定义了可能的移动(mov_list)仅仅是 10 的倍数。所以,这将我们的状态空间缩小了 10 倍到 1800。动作空间类似地由所有可能的运动(x 和 y 的组合)组成,给出一组 16 个。
好了,现在我们已经为游戏定义了代理、状态和动作。但问题是代理人如何知道它所采取的行动是有益的还是无益的?这就是奖励功能发挥作用的地方。奖励(或惩罚)可以在每次行动后或游戏结束时提供。一般来说,保持奖励系统简单是个好主意。例如,在我们的游戏中,球最多有 200 步才能到达圆圈。每一步都没有奖励。如果球在 200 步之前找到圆圈,则奖励 100。
那么,这种奖励是如何用来制定政策的呢?有多种方法可以做到这一点,但我们使用了 Q 表,这是最简单的策略更新工具之一。Q 表只是状态空间 x 动作空间的矩阵。
q_table = np.zeros([len(state_space),len(action_space)])
对于我们的游戏,它是一个 1800 x 16 的矩阵,每个单元初始化为 0。如果任何动作导致奖励,我们更新对应状态的 Q 表,动作对。
old_q_value = q_table[state, action]
next_state = list(state_space.keys())[list(state_space.values()).index((pos_x1, pos_y1))]
next_max = np.max(q_table[next_state])
q_target = reward + gamma * next_max
q_delta = q_target - old_q_value
q_table[state, action] = old_q_value + alpha * q_delta
我在这里引入了两个新术语。“alpha”设置算法的学习率,“gamma”是未来奖励的折扣因子。gamma 值越高,可能的未来回报就越重要。我们使用了 0.9 的 alpha 和 1 的 gamma。
这留给我们最后一件事。设定勘探与开发比率。这是由项ε设定的。如果随机数(0 到 1)低于ε,那么代理可以根据 Q 表自由探索和忽略当前策略。
if random.random() < epsilon:
x1 = random.choice(mov_list)
y1 = random.choice(mov_list)
action = list(action_space.keys())[list(action_space.values()).index((x1, y1))]
else:
action = np.argmax(q_table[state])
x1, y1 = action_space[action]
整个脚本可在这里获得
可视化强化学习如何进行的最好方法是通过一些 GUI 跟踪球的运动。我将 RL 代码与可视化代码分开,这样 RL 运行起来非常快。你可以在一定数量的游戏中运行 RL(代码中的剧集参数),然后运行 GUI 来观察球的行为。GUI 是基于 Tkinter 的,应该可以在任何平台上轻松工作。需要记住的主要事情是,对于 RL 运行,epsilon 设置为 0。因此,它在 RL 训练期间全面探索所有游戏(并建立策略)。请随意将它设置得更高,并在 GUI 上观察结果。
如果你想想象探索之后的渐进开发,在同一个报告中查看这个脚本。注意不要设置太少的探索集,否则小球学不到多少东西,开始钻政策的空子。
就是这样!摆弄参数,一旦你适应了,就开始创建更复杂的游戏。你很快就会意识到,一旦状态空间变得太大,Q 表的更新就会变得非常慢。这就是深度 Q 网络的用武之地。改天再讨论的话题。
强化学习基础:平稳和非平稳多臂土匪问题
Photo by Benoit Dare on Unsplash
多臂(也称为 k 臂)bandit 是一个介绍性的强化学习问题,其中代理必须在 k 个不同的选项中做出 n 个选择。每个选项都提供了(可能)不同于未知分布的回报,该分布通常不随时间变化(即它是固定的)。如果分布随时间变化(即,它不是静态的),问题会变得更难,因为先前的观察(即,先前的游戏)几乎没有用处。无论哪种情况,目标都是获得最大的总回报。
这篇文章回顾了一个简单的解决方案,包括 1000 个游戏中的固定和非固定的 5 臂强盗。注意这里只展示了部分完整代码的备注,完整功能的笔记本请看这个 github 库。
5 个固定的强盗
首先,让我们来定义下图中显示的 5 个固定土匪,这将成为代理的选项。
class Bandit:
def __init__(self, mean, std):
self.mean = mean
self.std = std
def sample(self, n=None):
return np.random.normal(self.mean, self.std, n)
Distribution of each bandit (unknown for the algorithm)
为了简单起见,它们中的每一个分别遵循均值为 1、2、3、4 和 5 的正态分布,并且它们都具有 5 的标准偏差。这意味着,比如说,在一次拉动中,所有的强盗都很有可能获得 3 英镑的奖励,但是 1000 场游戏的预期奖励在不同的强盗之间会有很大的差异。事实上,如果一个人总是选择强盗 b1,预期奖励是 1000,而如果一个人选择强盗 b5,那么预期奖励上升到 5000(5 倍增长)。记住,在这个例子中,最好的强盗是 5 号。
当然,如果一个人事先知道这些分布,那么问题将是微不足道的:只需选择期望值最高的土匪并坚持下去。这就是探索和利用之间的权衡所在:假设一个人对环境的信息不完善,那么就有必要继续探索(即尝试不同的强盗),以便获得关于最佳选择的知识,或者很可能陷入局部最优(纯粹的利用,贪婪的算法),但如果一个人只探索,那么所获得的信息就没有被使用,也不会获得最优(纯粹的探索)。
为了确保上述概念得到理解,假设在尝试每个土匪一次后,他们的结果是:
那么一个纯粹的利用算法会拉真正的最差土匪(b1)很长一段时间(直到 b1 的平均值低于 0,可能永远不会),只是因为它在初始化步骤中随机地碰巧是最好的。相反,纯探索算法将对五个盗匪进行均匀采样,并且其期望值将为:
这是次优的结果。
一个简单的解决方案是结合这两种方法,只是贪婪,但探索的时间比例为ε。在下图中,可以看到ε = 0(纯剥削)、ε = 0.01 和ε = 0.10 的实现。贪婪算法在搜索的早期阶段占主导地位,但那些探索的人很快意识到有更好的强盗,并胜过贪婪算法。
# Plays the bandits n times during t time steps
datas = {}
n = 20
t = 1000
es = [0, 0.01, 0.10]for e in es:
# Play n times
for i in range(n):
# Get t time-steps of each bandit
if i == 0:
data = sample_bandits(bandits, e, t)
else:
data = data.append(sample_bandits(bandits, e, t))
datas[e] = data
Average score for ε = 0, ε = 0.01 and ε = 0.10
由于问题是固定的,一旦一个人有信心成为最好的强盗,就不再需要探索;因此,在极限情况下(即有∞步),ε = 0.01 算法将是最好的算法。然而,如果对问题的平稳性有信心,那么最佳策略将是进行初始搜索(ε = 0.10),然后切换到利用模式(ε = 0)!
下图显示,通过玩这个游戏 20 次,混合算法在更高的时间百分比内一致地采样到最好的强盗。请注意,ε = 0.10 看起来停滞在 90%附近,这很自然,因为它被编码为在 10%的时间里选择一个非最优的 bandit。相反,ε = 0.01 不断增加,随着时间的推移,它将达到 99%。
Percentage of optimal action for each ε policy across 20 games.
另一种方式是检查 20 个游戏中每个土匪的样本数,如下所示,贪婪算法通常会混淆土匪 4 和土匪 5,而ε = 0.10 很容易找到最好的土匪。
Number of samples per bandit per policy.
5 个不稳定的强盗
在现实生活中,发现随时间变化的分布是很常见的。在这种情况下,问题变得更难解决,只是因为以前的观察不太有用:它们可能没有反映出土匪当前状态的真相。处理这个问题的一个简单(但非常严格)的方法是只考虑 m 个先前的观察,这就是这里使用的方法。请注意,这引发了许多问题,例如:
- 变化可能与 m 非常不同,在这种情况下,信息要么被混淆,要么被浪费。
- 这种方法假设 bandit 的新发行版与以前的发行版无关,但事实往往并非如此。
考虑到问题的性质,使用指数加权平均法、加权块平均法或甚至拟合时间序列模型来寻找分布何时改变的指标并相应调整勘探率等替代方法可能更准确。
为了将这些土匪调整为非平稳的,使用了对分布的平均值和标准偏差的简单概率突变(具有 1%的突变概率),但是变化也可以每 X 步发生一次,或者具有不均匀的概率,或者它们甚至可以改变分布的形状。
def mutate_bandit(bandits, proba):
for bandit in bandits:
if np.random.random() < proba:
bandit.mean += np.random.randint(-100,200)/100
bandit.std += np.random.randint(-50,75)/100
在这种情况下,人们会认为纯粹的利用算法性能很差。这个直觉用下图证实了,图中显示ε = 0 算法只在 30%左右的时候选择了最好的 bandit,比纯粹的随机选择(20%)好不了多少。ε = 0.10 设法发现最佳 bandit 何时更频繁地改变,并保持为最佳执行算法。另一方面,ε = 0.01 不再提高,因为它的低探测率不允许它快速找到变化的最佳 bandit。
Percentage of optimal action for each ε policy across 20 games on a non-stationary bandit problem.
外卖
最后,如果你需要记住这篇文章的一些东西,那应该是:就像 k-bandit 问题一样,真实世界的问题,其中的真实性质是未知的,需要探索和利用的混合才能有效地解决。
强化学习:超越监督和非监督方式
在机器学习中,根据提供给你的数据类型,有两种主要的方法来训练你的模型:
- 监督学习:你被提供了一组输入和输出,因此你的数据已经被标记,你知道它们背后的“基本事实”。这意味着,一旦你的算法在训练集上得到训练,并在测试集上做出预测,你就可以立即得到它的性能反馈:事实上,你已经知道了真实的输出。让我们用一个简单的例子来形象化它,其中我们的数据被标记为“三角形”和“正方形”,因此我们的算法将被要求为新数据分配一个现有的类:
- 无监督学习:在这个场景中,你被提供的数据既没有被标记也没有被分类。基本上,你事先不知道你的数据点是正方形还是三角形*。因此,无监督算法的目标是推断这些数据的内部结构,找到共同的模式,并试图将它们归类(记住,没有目标!).也就是说,我们的无监督算法可能能够从三角形中分离出正方形,但实际上并不称它们为“正方形”和“三角形”。*
到目前为止一切顺利。但是如果根本没有给你提供数据,而你又想让你的算法从周围环境中学习,那会怎么样呢?如果你想一想许多自动化系统,像自动驾驶汽车和机器人,你可以看到那些机器(汽车、机器人)没有提供历史数据:它们必须在工作时收集这些数据。因此,这个想法是,这些机器必须通过几次尝试来完成任务,从它们的错误中学习(即撞向墙壁),并在下一次尝试中避免它们。
让我们通过考虑下图(指的是马尔可夫决策过程)来稍微解释一下这个概念:
想法是我们有一个代理*(机器人)和一个环境(迷宫)。那个代理有一个环境的个人表示,称为状态。然后,它需要与环境互动,其方式是通过动作。在每一个行动之后,代理将会有一个新的环境状态,以及对其行动的反馈,以奖励或惩罚的形式。*
为了简单起见,想象你第一次参观一个公寓,突然,环境变暗了,你什么也看不见。你想到达门口,但你不知道路。你会怎么做?你可能会从非常缓慢和随意地行走开始(第一组动作),记住公寓的某种表现(状态)。然后,你撞上了右边的一堵墙:现在你可以在精神上更新环境的状态,同时,你正在接收对你的行动的负面反馈(惩罚)。现在,你知道你所做的动作是不正确的,因此你将朝着另一个方向前进,令人惊讶的是,你到达了门口!现在你将会收到积极的反馈(奖励),因为你已经达到了目标。
这个小机器人(代理人)试图穿过迷宫(环境)并到达奖品(任务的目标)时也会发生同样的情况。
所以,强化算法的思想是这样的:找到一套行动(所谓的政策),使奖励的现值(或贴现值)最大化。
正如预期的那样,RL 有各种各样的应用,但在我看来,最具革命性的元素是它不同于任何其他 ML 方法的方式。事实上,如果你考虑分类或聚类方法(分别是有监督的和无监督的),你基本上是在试图让模型“模仿”你完成任务的方式。然而,在 RL,故事是不同的。在这里,代理将自己探索环境,并且根据响应,它将更新它的策略,这不是对该过程背后的某些人的策略的模仿。
强化学习、大脑和心理学:导论
强化学习、人工智能和人类
强化学习与人类联系系列介绍。
“甚至在天气预报中也能找到灵感。”
人脑可能是世界上最复杂的系统之一,因此它是任何人工智能研究人员的灵感源泉。几十年来,强化学习不仅从自然中,也从我们自己的心理学中借鉴思想,在技术和人类之间架起了一座桥梁。
在这些系列中,我们将深入探究是什么激发了 RL 领域的发展,以及是什么在未来引发了它的发展。
本主题分为 9 个部分:
- 第一部分:引言。
- 第 2 部分:古典和仪器条件反射。
- 第 3 部分:延迟强化、认知地图和行为。
- 第 4 部分:神经科学基础 1。
- 第 5 部分:神经科学基础 2。
- 第六部分:多巴胺。
- 第七部分:演员-评论家。
- 第八部分:上瘾。
- 第九部分:边境。
在本系列中,我们不打算研究 RL 本身,假设您已经对它有所了解。希望会有另一个系列,这将是 RL 的重点,将涵盖一切从动态编程开始,并以复杂的事情结束,如 AlphaZero。
这里所有的想法都来自不同的来源,包括我自己的经历和对这个话题的思考。但我必须强调我最推崇的来源,也是我获取最多知识的来源——理查德·萨顿和安德鲁·巴尔托的“强化学习:简介”。这是少数几本关于 RL 的书之一,也是唯一一本涵盖了 RL 基础和起源的书。
在这篇文章中,我们将使用一些真实世界的例子来介绍 RL 的基础知识,因为这个系列不是关于数学、神经网络或编程的。它更多的是关于理解我们自己的思想和我们可以应用于人工智能的事物。
"在我们了解我们的大脑如何工作之前,我们很可能会建造 AGI . "
强化学习
RL 关键概念对我们来说非常简单,因为我们看到它并将其应用于我们生活的几乎每个方面。一个初学走路的小孩就是一个例子。
你可能在每个 RL 课程中都看到过类似的图片,这里没有什么新的东西,但它给了我们一个想法。
一个蹒跚学步的小孩坐在地板上(这是他目前的状态做出一个动作,a 试图站起来,在这个之后得到一个奖励*。*三个字就是强化学习。
蹒跚学步的孩子不知道如何走路,但他通过反复试验来学习。当他跌倒时,环境会给予他疼痛的反馈,当他迈出一步时,环境会给予他一个充满爱心的母亲的拥抱。这听起来熟悉吗?是的,这就是许多人所知的正负强化,或者更一般的说法操作性条件反射。例如,当我们教狗叫或打滚时,我们也会用到它。
RL 的关键词
代理 是许多人所说的人工智能,但它基本上是在环境中运行的算法的化身。一个人、一只狗或一个蹒跚学步的孩子都可能是一个代理人。
环境 是围绕代理的东西,也是代理从那里拿奖励的东西。比如我们周围的世界或者你玩的一个游戏。
政策 是逻辑、道德和大脑的代理*。它给了代理人一个洞察力,告诉他为了成功应该做什么。更专业地说,它试图预测在某种给定情况下代理人行动的结果。
奖励 是代理做某事时得到的。这可能是积极的,也可能是消极的,取决于代理的表现。给打滚的狗一块饼干是积极奖励的一个例子,而你的教练的一声怒吼是消极奖励的一个例子。
状态 是代理进入的一种情况。它是你所拥有的信息的某种表现,比如你有多少钱,你住的离工作的地方有多远,你有多懒。代理根据状态决定做什么。*
因此,基本上 RL 研究人员所做的是试图创建这样一个智能体(就 RL 而言,我们的幼儿是一个智能体),它将在环境(例如幼儿的世界)中运行,并能够理解在给定情况下什么是最佳举措。回到蹒跚学步的例子,他应该如何摆放他的身体以保持平衡并迈步。
是什么让我们这些人与众不同
我们这些人和 RL 特工不同的是,我们环境给的奖励并不是那么清晰易懂。事实上,我们在这个问题上有很多说法:“每个人都有自己版本的真相”,“真相到底意味着什么?”、*“善恶只在一个角度不同”*等。
简而言之,我们不知道哪些行为是好的,哪些是坏的。我们总是用一种经验主义的方式来解决这个问题,没有人能告诉你你做得有多好。很明显,我们有老师和父母帮助我们学习,但总的来说,我们在这个黑暗可怕的世界里是孤独的。没有人能告诉你我们的哪些行为会导致成功,哪些会导致失败。
外在和内在奖励
所以,就像我说的,与强化学习代理不同,我们无法从我们的环境中获得可解释的奖励,也称为 外在奖励 ,但是我们有所谓的 内在奖励 。
从人类的角度来看, 内在奖励 是自我激励、好奇心、完成目标的欲望,只是因为而没有任何理由。它就在我们内心的某个地方,它是一个火花,我们中的一些人会把它变成火。
当然,我们想出了给 RL 代理商这种奖励的办法。例如,在 OpenAI 的这篇漂亮的论文中——好奇心驱动学习的大规模研究——研究人员制作了一个对世界好奇的智能体。长话短说,当代理到达之前未被发现的位置时,它会得到一份内在奖励。结果是惊人的,智能体设法解决了 蒙特祖马的复仇 ,这对于强化学习算法来说是极其复杂的,因为它的分层遍历(去拿钥匙,然后找到门,打开它等等。).
当然,有更多的技术解释为什么 蒙特祖马的复仇 如此难以解决,但它在本系列之外,需要更多关于强化学习算法的知识。
结论
强化学习可能是通往 AGI 的道路,也可能不是。老实说,我不知道,可能也没人知道。我相信这是我们拥有的机器学习技术中最接近 AGI 的技术,但是我有什么资格去评判呢?
我可以肯定的是,RL 不断受到我们自身本性的影响,在这个系列中,我们将揭示我们大脑和思想中发生的事情,并发现人工智能领域从我们人类那里借鉴了什么。
跟我连线上 推特 , 领英 , 脸书 并关注上GitHub!
强化学习—悬崖行走实现
开和关策略比较
强化学习的本质是代理通过试验迭代更新其状态估计、动作对的方式(如果您不熟悉值迭代,请查看我之前的示例)。在以前的帖子中,我一直在重复谈论 Q-learning 以及代理如何基于这种方法更新其 Q 值。事实上,除了在 Q-learning 中定义的更新方法之外,还有更多其他方法来更新状态、动作对的估计。在这篇文章中,我们将一起探索另一种叫做 SARSA 的方法,将这种方法与 Q-learning 进行比较,看看更新方法的不同如何影响代理的行为。
先说时差,这是一个更新方法的核心。我们知道,在每次迭代或事件中,代理通过遵循策略(比如ϵ-greedy)采取行动来探索环境,并基于其最新观察(概括为状态-行动的值),它通过将当前估计向最新观察调整一点来更新其当前估计,最新观察值和上次观察值之间的差异称为时间差异。正是从这个时间差中,我们的代理学习和更新自己。
时间差异的定义将各种方法区分开来。为了给你一个更具体的感觉,让我们直接进入算法定义,并检查不同之处。
SARSA & Q-学习
SARSA(from Sutton’s book)
Q-learning(from Sutton’s book)
很明显,唯一的区别在于更新 Q 函数。在 SARSA 中(顺便说一下,SARSA 这个名字明确来自于代理的过程,即状态、动作、奖励、状态、动作…),时间差异被定义为:
[R + Q(S', A') - Q(S, A)]
其中下一状态、动作对的观察 Q 值直接有助于当前状态的更新。 SARSA 也称为 on-policy,因为更新过程与当前策略一致。
然而,Q-learning 中定义的时间差异是:
[R + max_a(Q(S', a)) - Q(S, A)]
其中观察到的下一状态、动作对的 Q 值可能不会直接有助于当前状态的更新。Q-learning 总是使用下一个状态的最大值,在这种情况下,更新 Q 值所采取的状态、动作可能与当前策略不一致,因此被称为非策略方法。
事实上,这种差异会导致代理的不同行为。直觉认为,Q-learning(非策略)在价值评估方面更乐观,它总是假设在过程中采取最佳行动,这可能导致代理人更大胆的行动。而 SARSA(非策略)在值估计上更保守,这导致代理的储蓄器动作。
悬崖漫步
为了清楚地证明这一点,让我们来看一个例子,悬崖行走,它摘自 强化学习入门 。
Cliff Walking
这是一个标准的不打折扣的、偶发的任务,有开始和目标状态,以及引起向上、向下、向右和向左运动的常见动作。除了进入标有悬崖的区域外,所有转换的奖励都是-1。进入该区域将获得最佳路径 100 的奖励,并使代理立即返回起点。
履行
这是一个典型的二维棋盘游戏,所以棋盘设置与我在这里描述的例子基本相同。在接下来的章节中,我将主要强调 SARSA 和 Q-learning 的实现,以及这两种方法所产生的 agent 行为的比较。
悬崖背景
在坚果壳中,我们将有一个 Cliff 类,它代表能够:
- 跟踪代理的当前位置
- 给定一个动作,决定代理的下一个位置,并判断是否游戏结束
- 给予反馈作为奖励
这些是课件中的主要功能。nxtPosition
函数接受一个动作,并返回代理在棋盘上的下一个位置,如果代理将其头部撞到墙上(到达边界),它将保持在同一位置。giveReward
函数将奖励-1 赋予除悬崖区域之外的所有状态,悬崖区域的结果是奖励-100。
让我们看看我们实现的板。
Cliff Walk Board
代理人从棋盘左端的符号 S 开始,结束游戏的唯一方法是到达棋盘右端的符号 G 。而 ***** 代表悬崖区域。
博弈
就玩游戏而言,我们将有一个代理类来代表我们的代理,在代理类中,有一个函数决定代理的动作,这也是ϵ-greedy 策略。(点击查看完整实施
关键区别在于play
功能:
在每一集(游戏的每一轮)中,我们在列表self.states
中记录我们的代理的行动、状态和奖励。在游戏结束时,我们以相反的方式更新 Q 函数(T1),如果方法是 SARSA(on-policy),新更新的 reward
(本质上是 Q(S', A')
)将直接应用于下一次更新,如果方法是 Q-learning,还有一个步骤
reward = np.max(list(self.state_actions[pos].values()))
取该位置所有动作的最大值到下一轮更新。最大化操作塑造了代理的行为,并使其能够采取更冒险的行动。
开/关策略比较
我用探索率为 0.1 的两种方法运行了 500 轮,并采用了他们学习的最后一个(state, action)
。
Result of SARSA
Result of Q-learning
我学到的结果与书中的最优结果略有不同,但这足以清楚地看出两者之间的差异。
结论
结论第一部分将引用 Sutton 的书,该书完美地总结了两种方法之间的差异:
Q-learning 学习沿着悬崖边缘行进的最优策略的值。不幸的是,这导致它偶尔会因为“ε-贪婪”的行动选择而掉下悬崖。另一方面,SARSA 将动作选择考虑在内,并通过网格的上部学习更长但更安全的路径。虽然 Q-learning 实际上是学习最优策略的值,但是它的在线性能比学习迂回策略的 SARSA 差。当然,如果ϵ逐渐减小,那么这两种方法都将渐近收敛于最优策略。
最后,请点击查看完整代码。欢迎您投稿,如果您有任何问题或建议,请在下面发表评论!
参考
[1]http://incompleteideas.net/book/the-book-2nd.html
基于 DQN 的车杆强化学习概念
深度 Q-网络简介
CartPole,也称为倒立摆,是一种游戏,你要尽可能长时间地平衡杆子。据推测,在杆子的顶端,有一个物体使它不稳定,很可能摔倒。此任务的目标是左右移动手推车,以便杆子可以尽可能长时间站立(在某个角度内)。
Figure 1: We can move the cart ONLY to the left and right.
在这篇文章中,我们将看看强化学习,这是人工智能中的一个领域,人工智能通过多次玩游戏来探索环境,直到它学会正确的游戏方式。
(Figure 2) Left: start of the training. Center: After a few episode of training. Right: Agent fully trained
正如您在此处看到的,在培训开始时,代理不知道将推车移动到哪里。过了一会儿,代理向一个方向移动,但是,当然,不可能以这样的速度把杆子带到另一边。对于最后一个问题,代理知道平衡杆子的正确方法,即反复左右移动。
奖励
让我们试着多理解一下这个游戏。同样,目标是尽可能长时间地活着。你撑竿的时间越长,你得到的分数就越多。这个分数,也叫奖励,是我们给代理人的,用来知道它的动作好不好。基于此,代理将尝试优化并选择正确的操作。请注意,当杆子超过 12 度角或手推车飞出屏幕时,游戏结束。
但是代理如何知道杆子的当前状态呢?数据应该是什么样的?
州
车杆的当前状态(向左或向右倾斜)被称为状态。一个状态可以是当前帧(以像素为单位),也可以是能够表示推车杆的一些其他信息,例如,推车的速度和位置、杆的角度和尖端的杆速度。对于这篇文章,让我们假设购物车的状态是上面提到的 4 个属性。
根据我们采取的行动,它可以导致不同的其他状态。假设极点开始是直的,如果我们向左走,极点多半是向右走,这是一个新的状态。因此,在每个时间步中,我们所做的任何动作都会导致不同的状态。
Figure 3: When we move the cart to the left, the pole tends to fall to the right side, and vice versa for the other direction.
q 学习
从上面的状态图可以看出,如果我们做了正确的决定,杆子不会倒,我们会得到奖励。换句话说,对于那些状态和动作对导致越来越进一步的状态也是期望得到一大笔奖励。因此,让我们称每个状态-动作对的期望回报为 Q 值,记为 Q(s,a) 。
在一个状态 (s) 期间,代理人采取了一个动作 (a) ,他们将立即获得该动作的奖励(如果游戏仍在进行,则为 1,否则为 0)。然而,早些时候我们提到我们想要考虑国家行动对的潜在未来回报。让我们用下面的等式来正式考虑这种情况。
Equation 1 : Idea behind Q-Learning
直觉上,我们想知道 Q(s,a) 如果我们处于 (s) 状态,做出 (a) 动作,我们能得到的预期回报是什么。通过做一个动作 (a) 得到一个奖励 ® 后,我们会到达另一个状态*(s)。然后,我们只需在 Q 表中查找,找到在状态(s’)*下采取的最佳行动。所以,这里的想法是我们不需要考虑整个未来的行动,而只需要考虑下一个时间步的行动。伽马符号 (γ) 表示我们应该把多少注意力放在国家 s’的未来回报上。
在训练开始时,我们不知道任何状态-动作对的 Q 值。基于上面的等式,我们可以朝着最佳值的方向一点一点地改变 Q 值。
Equation 2 : Updating Q(s,a)
这个等式可能看起来有点可怕。别担心。我们将通过下图对其进行分解,看看这里发生了什么。
Figure 4: Breaking down equation 2
这里, Q(s,a) 会根据我们认为我们对 Q(s,a) 的了解和当前剧集告诉我们的 Q(s,a) (应该是什么)之间的差异进行更新。如果我们的 Q(s,a) 被高估,红色虚线框中的值将为负,我们将稍微降低 Q(s,a) 的值。否则,我们将增加 Q(s,a) 的值。我们对 Q(s,a) 的改变量取决于差值(红框)和学习速率(α)。
目前的 Q-Learning 有一个问题。那就是状态空间是巨大的。杆子角度或小车速度的每一个微小变化都代表一种新的状态。我们需要一个非常大的内存来存储所有可能的状态。对于这种手推车来说,处理这么多状态也许是可能的,但对于更复杂的游戏,如星际争霸 2 或 Dota 2,Q-Learning 本身不足以完成任务。
深度 Q 学习
为了解决这个问题,我们需要一些东西来近似一个函数,该函数接受一个状态-动作对 (s,a) ,并返回该对的预期回报。这就是深度学习的用武之地。它以仅根据训练数据逼近函数而闻名。请记住,我们不会在这篇文章中详细讨论神经网络。这将只是一个关于我们如何将深度学习与强化学习相结合的简介。
Figure 5: Incorporating network network in Q-Learning
假设我们想知道 Q(s,a=right) ,我们将环境的状态 (s) 输入到模型中。让神经网络进行计算,它将返回 2 个值。一个是向左移动时的预期回报,另一个是向右移动时的预期回报。由于我们对 a=right 感兴趣,我们将只从该输出的较低节点获取值。现在我们通过使用网络得到了 Q(s,a) 。
为了充分训练网络,损失函数是必不可少的。直观地说,在网络输出一个近似值 Q(s,a) 之前,我们已经知道这个值应该是什么(基于等式 2)。因此,我们可以惩罚网络所犯的错误,并让它通过反向传播来学习这个错误。
把它放在一起
现在我们已经讨论了状态、奖励、行动、Q-learning 和 DQN,特别是在这个车杆环境中。让我们看看 DQN 在杆位环境下的结果。
Figure 6: Playing cart-pole with DQN after fully trained
结论
这就是了。我们刚刚在一个推车杆子游戏中经历了 DQN 的概念。DQN 成功地应用于更多的游戏,尤其是雅达利游戏。它非常通用和健壮。所以,下次你心中有了一个环境,你可以直接插入 DQN,让它自己学习玩游戏。请记住,最近有许多其他深度强化学习技术可以更好更快地学习更复杂的游戏,如围棋或 Dota 2,但这是另一个时间的主题。
参考
- https://arxiv.org/pdf/1312.5602.pdf
- https://www . analyticsvidhya . com/blog/2019/04/introduction-deep-q-learning-python/
- https://web . Stanford . edu/class/psych 209/Readings/suttonbartoiprlbook 2 nded . pdf
- https://gym.openai.com/envs/CartPole-v1/
新闻推荐强化学习介绍(DDPG 和 TD3)
推荐系统暴露的深度学习方法
Photo by Juliana Malta on Unsplash
TL;DR:强化学习是推荐系统的理想框架,因为它具有马尔可夫性。状态是由用户分级的电影。动作是下一部要看的电影,奖励是它的评级。我用 DDPG/TD3 实现了这个想法。本文的主要部分涵盖了实现细节,讨论了 RL 的参数选择,介绍了动作评估的新概念,提出了优化器的选择(生命的拉达姆),并分析了结果。
我还发布了一个 ml20m 数据集版本,专门用于马尔可夫决策过程和 RL。
强化学习是一个相当难的话题。当我开始深入调查时,我意识到需要一个好的解释。这篇文章,加上代码是我的学校项目。 我目前是一名高二学生,我以一种更“社会研究”的方式理解难懂的数学概念。我希望这篇文章能对我这样的新人有所帮助。
我创建了一个 GitHub 项目,您可以克隆并跟随它!一定要去看看。你可以在下载部分下载我在电脑上处理过的所有东西。以及常见问题解答、数据集描述、一些文档、操作指南等。它经常更新。因为在写这篇文章,一周没推了。希望你喜欢!https://github.com/awarebayes/RecNN
本文提供了最流行的推荐方法的比较,以及对各种强化学习算法的深入研究,概述了每个可调整的参数以及更改它的后果。我还提出了评估深度学习推荐器的替代方法,并讨论了该应用程序的不同优化器。这也是我的遗产,因为我高中的最后一年就要到了,所以我没有足够的时间来完成它。如果你有兴趣支持这个项目,欢迎你的贡献!
内容
介绍
一个伟大的优化故事
- 静态与动态时间序列数据集
- 为什么您应该选择 HDF5
- 编码时间序列
新闻推荐方法
- 相似性搜索
- 矩阵分解
- 受限玻尔兹曼机器
- 因式分解机器
- 强化学习
- 方法比较
嵌入概述
- 深度学习中的信息论
- 信息平面定理
- 为什么嵌入=“瓶颈特性”有意义
马尔可夫材料概述
- 马尔可夫性质、链、游戏和决策
- 回报与价值
- 连续状态马尔可夫过程
非政策方法:
DDPG:深度确定性政策梯度
- 简单的解释
- 高级解释
- 用代码实现
- 为什么它不起作用
- 优化器选择
- 结果
TD3:双延迟 DDPG
- 说明
- 履行
- 结果
结论
政策上的方法:(下一篇文章……)
- PPO:最接近的策略优化
- 盖尔:生成性对抗模仿学习
无探索的非策略深度强化学习。)
介绍
这篇文章花了这么长时间来写有几个原因。
首先,因为数据集是动态的令人沮丧。当我开始构建原型时,仅仅一次迭代就要花费 40 多个小时。随着基本熊猫和优化的完成,它缩小到 1.5。当我实现动态数据集时,需要 10 分钟。如果你用状态表示法对状态进行编码,结果是 3。此外,我不能让 DDPG 工作,它增加了相当多的影响。因此,我最终使用了一个静态时间序列数据集+ TD3。不过,以后再说吧。
然而,最重要的是,大多数关于 TDS 的文章都是付费的。因此,没有优质的文章,没有 Patreon,没有钱乞讨。你可以多次点击这篇文章(请点击左上角的按钮),然后进入 GitHub 页面开始回购。
这是我的学校项目,主演,对我来说是必不可少的。这也会给我赢得项目竞赛的更好机会,甚至可能减少大学的付款。
时间序列的提示和技巧
完全避开熊猫!
正如你所看到的,pandas 是可以优化的,但最终,它的运行成本仍然很高,因为即使是我最好的优化也不能很好地扩展。x 轴代表 10 的幂。y 轴是花费的时间(秒)。此外,深度学习的问题是,我们经常在同一个数据集上反复运行模型。因此,让我们的数据集完全静态,消除所有熊猫的互动是完全有意义的。让我们运行数据集生成器并保存结果。如果你已经找到了我的回购协议,并继续跟进,笔记本位于 notes/1 下。香草 RL/ 1。生成静态 dataset.ipynb 。注意:完全是强制的;你可以下载我生成的数据集。
Scaling for different approaches
以 HDF5 格式存储您的数据!
有时时间序列不能完全输入你的内存。此外,HDF5 格式也是专门为此开发的。尽可能使用它,因为它比 PyTorch 快得多,并且自带 numpy 支持。唯一的限制是你的固态硬盘,所以你可能想买一个 PCI Express 的快速读取。
编码尺寸!
如果您使用静态大小的时间序列(也称为“滚动”ts),请确保将数据编码到较低的维度中。对于经典的 ML 方法,我们有主成分分析或简称 PCA。如果这对你来说是一个新单词,这里有一段视频。
您也可以使用 LSTM 自动编码器动态长度时间序列。从我的实验中,我注意到线性 AEs 对于滚动 ts 表现不佳。然而,我使用国家代表作为论文的作者提出。DL 的规则#1337 指出,90%的实际学习发生在前 10 分钟。所以我运行 TD3 模型,并使用它的状态表示模块来编码 ts。
新闻推荐方法
当我第一次开始钻研这些东西时,我意识到甚至连基本的推荐技巧都没有全面的指南。我最近发现了受限玻尔兹曼机器。本节旨在解决这个问题。我试图概述一些最流行的,并做一个快速的比较。更多的分析结果,请看下面的迷因。
相似性搜索
SS 是最容易理解的概念。只需在用户中寻找喜欢或不喜欢的类似电影。状态(被分级的电影)通常被表示为度量空间。有几种方法可以从原始电影索引中对其进行编码。第一个是使用嵌入层,这是现代 DL 应用程序中的常见情况。然后使用余弦或欧几里德距离等相似性度量对它们进行良好的排序。然而,回头看看更经典的 ML 方法,我们有局部敏感散列法。LSH 是一种算法技术,它以很高的概率将相似的输入项散列到相同的“桶”中。无论哪种方式,我们最终都会得到一堆与我们预测的状态相似的排序状态。然后我们看用户喜欢/不喜欢的电影并推荐它们。如果你想用这个方法,建议你去看看脸书的 Faiss 库: GitHub 链接。
矩阵分解
分解矩阵的思想,即把一个大矩阵分解成多个小矩阵的乘积,进一步扩展了相似性搜索。这个大矩阵可以表示为一个表格,行是电影,列是用户,值是收视率。我们通过假设大矩阵可以表示为两个较小矩阵的点积来扩展这个想法。它们代表隐藏(嵌入)表示。使用 PyTorch 可以轻松实现该过程:
user_matrix = user_embedding(users)
film_matrix = film_embedding(films)
ratings = (user_matrix * film_matrix).sum(1)loss = MeanSquares(ratings, target_ratings)
loss.backward()
“Users”是 userId 的整数向量。“Films”是 film_id 的整数向量。用户和电影矩阵是相应索引的 2D 嵌入。我们计算点积,因为我们想知道评级。您可能已经注意到,由于使用了嵌入,这种方法非常有限。你不能添加新的电影/用户到现有的电影/用户中,除非你使用类似增量 SGN 或水库计算的东西。只是上面方法的一篇很好的综述文章:链接。另外,如果你想深入了解 MF,我强烈推荐这个由 Luis Serrano 制作的视频。
受限玻尔兹曼机器
RBS 是自动编码器的早期变体。它属于基于能量的方法。作为自动编码器,用于降维。命名的受限部分意味着没有层间传播。该架构看起来像一个普通的两层线性网络。正向传球看起来很像前馈网络。
关键的区别在于 RBM 是概率性的。他们用贝叶斯方法工作。每当你试图计算网络的状态,也就是说,从这些权重和偏差分布的样本,你会遇到玻尔兹曼方程。这是粒子物理学中的一个方程。该模型的学习包括两个主要步骤:Gibbs 抽样和对比发散。
我从吴恩达对杰佛瑞·辛顿的采访中发现了这些机器。当被问及他最大的成就时,后者承认了他对 RBMs 训练算法的贡献。提醒一下:G.H .是一个支持反向传播的人。事实上,RBM 在网飞竞赛中取得了最高水平的成绩。如果你想了解更多基于能源的模型:这里有 Yann LeCun 的笔记。
RBM structure
因式分解机(非个性化)
因数分解机器已经被证明对点击率预测非常有用。它们的速度允许它们高度可伸缩,但是它们只适用于具有分类特征的数据。然而,它们值得大声疾呼。我们需要以某种方式将特征数据合并到我们的因子分解过程中。当然,我们可以认为一个特性就足够了:
ratings = linear(features.size(1), 1)loss = MeanSquares(ratings, target_ratings)
loss.backward()
如您所见,它们不能用于个性化推荐!
然而,考虑特征的标签-标签互相关是很酷的。我们刚刚学习了订单的概念。阶数是计算互相关的要素数。假设阶数为 2,我们需要计算两个特性的 CC。然而,这个特征是一个分类变量,那么如何计算两只猫的点积呢?更多的潜变量给了潜变量之神!可以使用向量来描述特征标签,并且可以使用我们用于矩阵分解的相同嵌入思想来回归这些向量。
ratings = linear(features.size(1), 1)(features)# factorization machine
latent = latent_embeddings(features)
latent_gram = latent * latent.T
features_gram = features * features.T
ratings += (latent_gram * features_gram).sum(1)loss = MeanSquares(ratings, target_ratings)
loss.backward()
这里有一篇文章帮助我更好地理解了这个概念:链接。
强化学习
使用 RL 进行新闻推荐的关键优势是马尔可夫性质和状态表示。因为我们不依赖任何嵌入,所以我们可以向任何用户推荐任何电影。为此应用程序生成的电影嵌入不依赖于嵌入层。我使用了简单的统计数据,如平均评级、收入、文本的 TF-IDF、流派等。… + PCA。因此,您可以添加新电影进行推荐,而无需重新训练网络。或者,您可以使用这些新的嵌入来表示状态。马尔可夫性保证了我们可以使用静态长度的时间序列。稍后详细介绍。
比较
警告:讽刺
Reinforcement Learning
Restricted Boltzmann Machines
Matrix Factorization
综上所述:RL 允许在任何规模的迷你批次上学习,静态长度时间序列的输入,不依赖于静态嵌入,在客户端工作,可用于迁移学习,具有可调的对抗率(在 TD3 中),支持集成,工作速度比 MF 快,并保留马尔可夫属性。最重要的权衡是准确性:像网飞/亚马逊这样的大公司仍然依赖 MF/RBM。
解释嵌入
与 Q-Learning 不同,这个特殊的应用旨在解决连续控制问题。在 Q-Learning 状态下往往是连续的,但动作本身是离散的。然而在我们的例子中,动作(=电影)不是离散的,而是一个向量。
但是我们如何得到这个向量,我们以后会尝试回归这个向量?上次我检查 ML20M 数据集时,没有找到任何向量。答案很简单:我自己生成了这些数字索引电影的矢量表示。大多数东西都是琐碎的:我解析了 IMDB/TMDB 数据,并应用了基本的统计数据来制作收集到的数据的向量(通过对类别进行编码,使用 TF-IDF,应用 PCA ),但我使用的最重要的东西之一是用于文本数据嵌入的 Google 的 BERT。我知道,嵌入在技术上是一个不同的东西,这些被称为“瓶颈特性”,但我将坚持这个词。
然而,为什么神经网络的一些中间层有意义呢?为什么可以将这些数据用作上下文信息?这些问题都可以在信息论领域找到答案。这在数字图书馆的背景下并不普遍,但是 Naftali Tishby 关于“保留信息的最大化”和其他关于为什么网络学习的提示的讲座很有意思。我推荐你看看这些!
一些亮点:
- 00:19:00 信息平面定理——对于一个相当大的典型 X,DNN 的样本复杂度完全由最后一个隐层的互编码器信息 I(X,T)决定;解码器信息确定前一隐藏层的精度(泛化误差),I(T,Y)。这个现象就是我在这个 app 里用的东西。你可以在 00:23 看到这个现象的可视化。
- 【https://www.youtube.com/watch?v=pFWiauHOFpY
马尔可夫材料概述
既然我们已经让我们的数据集工作了,理解了我如何将电影 id 转换成上下文向量,现在是时候回顾一些关于强化学习和博弈论的事情了。如果你阅读关于 DL/RL 的 Arxiv 论文,很容易看到基础知识被整理出来。
新闻推荐可以被认为是一个我们正在努力赢得的游戏。我们基于状态采取行动,而状态就是我们对用户的了解:收视率和观看的电影。动作是基于状态产生的,并描述空间中的一个点。
马尔可夫性质
从现在开始一切都严格遵守马尔可夫性质。引用维基百科:“如果一个随机过程的未来状态的条件概率分布(取决于过去和现在的状态)只取决于现在的状态,而不取决于之前的事件序列,那么这个随机过程就具有马尔可夫性质。”你可能会问,我为什么要在乎?我们假设我们只能基于当前状态采取行动,而忽略之前发生的任何事情。记住这一点,问题就变得更容易解决,因为我们不必担心过去。马尔可夫方法提供了一个框架,让你可以专注于当下发生的事情。
马尔可夫链
你也听过这个名字,因为 DeepMind 的 AlphaGo 用的是马尔可夫链蒙特卡罗。蒙特卡洛部分仅用于国际象棋或围棋等有限状态游戏。但是,马尔可夫链无处不在!为了简单起见,让我们考虑一个离散状态。我们还假设推荐是一个随机过程,这意味着我们随机遍历数据集。像任何其他物理链一样,马尔可夫链由称为节点的“循环”组成。每个节点都有一个条件转移概率。想象一下,这是一个随机的图遍历,当前访问的每个节点都有概率决定下一个访问哪个相邻节点。这里有一篇短文,有 19k 个赞,详细介绍。酷的事情是,它保留了马尔可夫属性:转移只取决于当前状态,即被访问的节点。
马尔可夫决策过程
马尔可夫链的思想可以进一步应用到我们的‘游戏’中。我们希望在我们的应用程序中使用 Markov 框架,因为它非常方便。然而,你如何将一个抽象的链条应用到状态-行动-回报-状态-行动…过程中呢?还记得我介绍的图表示例吗?马尔可夫决策过程也可以解释为一个图。我们假设我们当前的状态是图中的某个节点。因为它保留了确切的属性,所以我们不需要知道在到达那个状态(节点)之前发生了什么。从那个节点开始,有大量的动作可以以指定的概率被采取。这些动作可以被解释为将我们带到新状态的相邻边。当我们到达新状态时,我们会立即收到一个**奖励。**数据集中还有一件事用于 TD — Done 因为我们不想在最后一步之外传播时间差异。虽然,稍后会详细介绍。
States are green, actions are red, and the rewards are yellow
我构建的数据集由 State-Action-Reward-Next _ State-Done 值组成。GitHub 上有一个例子
连续状态马尔可夫过程
要完全理解正在发生的事情,最后一件事是行动不是离散的。我已经提到过几次,这个动作是一个矢量。我可以理解如何基于一个离散的数字在图形中移动,但是你用一个向量去哪里呢?所以不要把 MDP 想象成图形,而是一个 N 维的平面。为了简单起见,我将使用 2D 飞机作为例子。让我们考虑一个蚂蚁代理在操场上移动。此刻他知道他可能需要带一些树叶到它的房子里。唯一的问题是它的大脑中没有这种离散的“硬编码”动作。因此,它需要在环境中采取连续的步骤:移动它的四肢,咬紧它的下巴,躲避邪恶的蚂蚁。每走一步,奖励就会增加。它可能会意识到树叶就在附近的某个地方,而且方向是正确的。另一个重要的区别是我们假设时间步长是离散的。只有当我们知道一定数量的电影和用户指定的分级时,推荐才是可能的。考虑到 5.6 的电影和 1.3 的收视率,试图提出一些建议是很奇怪的。
如果你看一下上面的“连续行动与离散行动”的例子,就会发现有一个多智能体。它将肢体位置和角速度作为输入来提供环境。事实上,还有很多有趣的代理可以摆弄,如猎豹和波士顿动力公司的机器人模型。
.
.
.
价值功能与奖励
这一部分对于理解时间差异损失是必不可少的,这将在稍后讨论。在马尔可夫博弈中,我们有价值函数这种东西。所以价值函数并不意味着是一个估计回报的函数。价值只能表示行动对当前状态有多好。尽管,正如你将会看到的,它并不一定意味着对那个行为和状态的“给我奖赏”。它是一种更抽象的‘好’的度量,可以表示为一个连续的实值函数。函数的范围可以是任何实数。因此,该值不是[-5,5]中的整数。
第 1 部分:深度学习
现在,让我们暂时忘记我们学过的所有马尔可夫理论,试着从一个基本的 DL 方法开始。所以你决定建立一个基于深度学习的推荐系统,已经了解马尔可夫决策过程和数据集结构,总体上非常渴望直接投入行动。让我们尝试一种更基本的方法,暂时不用强化学习。你所拥有的只是一个简单的线性感知器和数据集:一堆状态、相应的动作和对这些动作的奖励。翻译成更人性化的语言:观看的电影,用户选择的下一部电影及其评级。我希望你继续思考你会用这些工具做些什么。
我们想推荐好电影;因此,我们训练网络来生成像动作这样的电影:
generated_action = model(state)
if is_good(reward):
loss = MeanSquares(generated_action, action)
loss.backward()
这种方法被称为“政策学习”,因为我们学习的是政策,是行动。它有它的应用,但是在端点上,PL 是非常有限的。如果你像这样训练一个网络,它会工作得很好,而且有点用。不过,你注意到‘is _ good’功能了吗?我们只学习“好”的行为,而不考虑其他任何事情。
Rewards distribution
第二部分:行动和批评
到目前为止,我们一直把奖励作为我们“学习”的标准。然而,分析动作不是更明智吗?这是演员-评论家方法背后的主要思想。为了清楚起见,让我介绍一下网络的命名。我们已经考虑过的网络叫做 Actor,它基于状态来行动。试图根据状态和行动者的行动来预测报酬的网络称为 critical。我们都知道,从看鲍勃·罗斯:每个人都需要一个朋友。所以让我们给我们孤独的演员增加一个人来嘲笑他的行为。
#teach the critic
generated_reward = critic(state, action)
reward_loss = MeanSquares(generated_reward, reward)
reward_loss.backward()# teach the actor
generated_action = actor(state)
value = critic(state, generated_action)if value > 0:
# learn the action
action_loss = MeanSquares(generated_action, action) # learn action
action_loss.backward()
最终,行动者会采取更好的行动(也许是也许),损失会收敛到零。然而,从那以后,我们在乍得 Pytorch 工作;我们可以在亏损的情况下做一些奇怪的事情,而不用担心反向传播!如果我们想直接使用评论家对演员产生的行为的奖励作为损失度量呢?Pytorch 让一切变得前所未有的简单!
#teach the critic
generated_reward = critic(state, action)
reward_loss = MeanSquares(generated_reward, reward)
reward_loss.backward()# teach the actor
generated_action = actor(state)
action_loss = -critic(state, generated_action)
action_loss.backward()
我们在这里做的是,我们用批评家作为我们的损失函数!从一开始就是这么打算的。注意标准前的减号。我们希望回报最大化。尽管如此,在机器学习中没有“最大化”这样的东西。我们经常反其道而行之:将负面因素最小化。
这就是 DDPG 算法。不过,如果你看报纸,评论家培训的代码会有所不同。这就是我们接下来要讨论的内容。
第 3 部分:实现时间差异
我们的评论家有问题。我们不需要估计回报。让我们引导动作的值。你为什么会问?答案很简单:未来的回报可能取决于当前的行动。将动作视为单个马尔可夫链步骤,我们希望最大化价值。什么是价值?
Markov 游戏环境中的 Value 是一个实值函数:V(state,action ),它表示(不是用整数奖励来表示——5 到 5,可以是任何实数)特定的操作对于相应的状态有多合适。
这就是我们需要把马尔可夫链带回来的地方。在这个特定的应用中,我使用 TD(1)版本的算法,这意味着我提前 1 步引导值。可以实现 TD(n),但是值迭代的次数是线性增加的。
为了学习价值函数,我们引导奖励和下一个状态和文本动作的值。你可以在这里阅读更多关于 TD 的内容。
# train the actor
next_action = actor(state)
action_loss = -critic(state, next_action)
action_loss.backward()
reward_loss.backward()# train the critic
next_value= critic(next_state, next_action )
expected_value = reward + next_value
value = value_net(state, action)
value_loss = MeanSquares(value, expected_value))
第四部分:你是在抄袭我吗?
要完全理解 DDPG,你只需要做最后一件事。它使用了目标和学习网络的概念。目标网络比学习网络更稳定,因为它通过软更新使用学习参数来更新。它显示出较少的过度拟合趋势,总体表现更好。此外,TD 损失略有调整。我们不需要为残局动作引导值。伽马参数服务于稳定性,我把它设置为 0.9 左右。
# train the actor
action_loss = -critic(state, actor(state))
action_loss.backward()# train the critic
next_action = target_actor(state)
target_value= target_critic(next_state, next_action )
expected_value = reward + (1 — done) * gamma * next_value
value = value_net(state, action)
value_loss = MeanSquares(value, expected_value))
value_loss.backward()# soft update
def soft_update(*networks, soft_tau=1e-2):
for target, learning in networks.parameters():
target= target.data * (1.0 — soft_tau) + learning .data * soft_tausoft_update(actor, target_actor)
soft_update(critic, target critic)
这是我使用的更新功能的实际截图
这就是 DDPG 的基本情况。
解释结果
在下一节中,我们将尝试比较并主要评估不同的强化学习算法。但是我们如何判断结果是好是坏呢?批评家网络为我们的行为赋予价值;但是,你确定这个值是否有意义。嗯,他们是基于评论家的损失。如果批评者的损失很小,而政策损失是合理的,我们就教演员。但是这些指标还不够。我也考虑动作的欧几里德距离和余弦距离。矩阵通常代表这一点。你可以看到用不同颜色的单个网格描述的距离。天气越暖和,距离就越大。例如,下面是真实的动作(我用统计嵌入产生的那些动作)看起来是什么样子。
Pairwise distances example
稍后,您将看到类似的培训和测试行动矩阵。另一种评估动作“人为性”的方法是使用自动编码器重建误差。我训练自动编码器模型来重构嵌入动作。重建误差被用作人为度量。这种技术被广泛用于异常检测,因为它是无监督的。此外,我对误差分布进行了核密度估计,以便进行漂亮的绘图和视觉比较。也可以暗示 Wasserstein 距离或 KL 散度。
An example of reconstruction error KDE
目标是使生成的测试分布接近真实的分布。生成的列车(或刚刚生成的列车)可以是不同的形式。
DDPG:深入观察
DDPG Training
GENERATED Actions
REAL actions
在这一点上,我所做的只是复制粘贴 Higgsfield 的 RL 冒险代码,并做了一些小的调整,以适应 torch 1.1
看起来我们有发现了!矩阵看起来很酷?一些相关性正在显现…损失在下降…等等,说一下比例尺上是什么?为什么我几乎没有余弦距离?为什么保单亏损会落入幽冥境界?为什么我的宠物人工智能不能正常工作?
这才是 RL 真正的快乐!
无数事情都可能出错!也许我应该玩玩学习率?诚然,这是熟悉 DL 的人首先想到的。然而,为什么我的错误首先在增长呢?我在 DL 里没遇到过这些事… WTF 正在跟 v 网优化发生关系,PyTorch?当过程开始时,它似乎没有太大的影响,但随后梯度爆炸,一切都被遗忘了…所以,很可能,学习率是非常好的。也许那是因为时差自举?但 TDB 不仅使用通过**软 tau、**TD 软更新的目标值网络,它还利用一个称为 gamma 的参数对未来预期进行加权。
P_gamma = 0.9
P_min_value=-5
P_max_value=5
P_soft_tau=1e-2
P_policy_lr = 1e-5
P_value_lr = 1e-6
P_actor_init_w = 3e-4
P_critic_init_w = 3e-4
我该怎么做?也许我设置了错误的参数来剪裁值:
expected_value = torch.clamp(expected_value, min_value, max_value)
让 DDPG 明白
有一件事让我迷惑不解,那就是“重量限制”的工作原理与人们的预期略有不同。如果我们用较小的数字初始化网络的最后一层的权重,它将生成较小的向量。不对!它的作用正好相反。所以这是余弦距离与实际作用的分布相比如此之短的主要原因。但是,对于欧几里得来说,似乎没有太大的影响。
此外,您是否注意到值裁剪的最小和最大参数分别是最小和最大奖励?这也需要改变,正如我在马尔科夫财产中提到的。我设置为奖励* n_td_steps。这很好,最后,损失很少低于 6-7。
你可能没有意识到,但是一个较小的批评家学习率会导致演员过度适应。如果政策损失下降得非常快,改变 LR,因为参与者过度适应了。记住:不是最直观的东西!
始终调试并跟踪以下参数:value、target_value (mean,std)、expected_value (mean,std)、generated_action(余弦距离、Gramian、方差、std、means、samples KL 到原始分布的距离)。总是在测试结束时绘制这些指标。
P_critic_init_w=3e-5
P_actor_init_w=3e-1
P_min_value=-10 # or -100
P_max_value=10 # or 100
我们解决了一个不工作网络的 RL 部分,现在损耗增长的原因完全是 DL。这里有一些给你的建议:
- 和优化者一起玩。有这么多是有原因的。从 Adam 开始,试试 Hinton 的 RMS prop,纯 SGD,带温重启的 SGD 和 CosineAnnealingLR。虽然,如果你不在乎,有一个整洁的新算法供你尝试!它叫 RAdam: GitHub link 。我尽可能使用它,因为它减少了要优化的参数数量。后面会解释。
- 极其小心地使用 grad_clip。在价值网络上使用它会改变价值函数的符号。我不明白为什么会这样。但是政策似乎运作良好。我花了将近一周的时间才弄明白。不,是真的。
- 重量衰减对于避免过度拟合至关重要。此外,它很容易与 Pytorch 优化器一起使用。将其设置为较小的值,爆炸渐变会在几秒钟内消失。此外,使用它与 grad 剪辑的演员。
这应该会让您/我的数据中的 DDPG 重现生机。
DDPG 参数会改变什么:
- 价值网络学习率-影响生成的操作之间的欧氏距离。它还改进了余弦距离,但规模较小。仅适用于 SGD/Adam,对拉达姆无关紧要。
Value LR is too big: Euc is skyrocketing value LR is balanced
- 演员权重初始化-改变动作空间中余弦距离的多样性。如果您发现您的动作距离几乎没有变化,请从更改此参数开始。
Small Cosine distance as the result of lousy weight initialization
- 软 tau —负责目标网络更新。它影响应用于目标网络的损失函数的“过山车”的延迟。你可以看到这两种损失彼此相似。如果您运行代码,您将看到价值损失慢慢转化为策略损失。正如我所说,它影响了这种翻译的通顺性。如果某样东西对你不起作用,这是另一个需要考虑的关键参数,但是不要高估它。
- γ—是时间差异中预期动作的权重。Imho 不那么重要。较小的值可能会导致梯度爆炸。
- 最小/最大值—我将它们设置为± 10。你可以用另一个大数字做实验。或者,您可以使用 x*n_td_iterations,其中 x 是最小/最大可能回报。它使学习过程更加严格,但违背了价值函数的性质。或者,如果你根本不在乎过山车的损失,你可以使用 numpy infinity。该参数对值测试损失有积极影响。
总是看损失函数的尺度。该值应该在[0,10]之间,而策略在 TD 削波的最小/最大值范围内。如果涨到 10e7,你就是在浪费时间调试!
为什么优化器的选择很重要
我已经注意到了这一点,但我怎么强调都不为过。始终使用最先进的优化程序。每天查看 Arxiv,订阅 twitter bot 并保持警惕,因为机器学习社区现在正处于生产力的巅峰。
Adam 通常是优化的默认选择。此外,这种情况应该改变。亚当是你最糟糕的选择之一。为什么?它对学习速度非常敏感。回想一下学习率调度程序:仔细记住将里程碑放在哪个步骤,使用 CosineAnnealingLR 热重启 SGD,CyclicLR。以上所有的技术都已经成为过去——不要再摆弄学习速度了。就用 RAdam!自适应学习率的方差及超越!
RAdam 是 Adam 的意识形态扩展,它使用了一个叫做学习率热身的聪明绝招。不幸的是,拉达姆的作者没有受到足够的欢迎,所以没有详细的解释。你可以阅读他们的 Axriv 论文。
As in Figure 8, we assume gradients follow a normal distribution (mean: \mu, variance: 1). The variance of the adaptive learning rate is simulated and plotted in Figure 8 (blue curve). We can see that the adaptive learning rate has a significant variance in the early stage of training.
然而,我声称仅仅通过改变优化器,我就能够用 DDPG 算法达到 TD3 那样的性能。并且在两种情况下都有更少的过度拟合
让我们继续关注亚当,看看它的表现如何。
这是亚当损失的样子。人们不必是博士也能发现明显的值过度拟合。还有,你注意到保单损失了吗?它看起来出奇的小。最大奖励 5,最大 TD 削波 10。
火车动作似乎过拟合,没有太多的欧几里德距离显示出来,但好吧…
Adam train actions: looking good
损失在 7.5 似乎是合理的。是吗?好吧,让我们看看自动编码器重构误差。
and_that_was_the_moment_he_knew.png
只需查看 ae rec 误差分布和/或比较它们之间的各种指标,就可以发现问题所在。最愚蠢的选择是只计算 KL/w 距离。你也可以看看更有意义的统计指标,比如均值/标准差/峰度/偏斜度。
Adam test actions: oops! All overfit copies!
CosDist < 0.4,Euc < 3。无需言语。还有我的一个观察:余弦矩阵定义了向量方向的角度分布。你可以用基本的数学来形象化它。
哇,那是一些美好的回忆!我希望我能记住那么多。不幸的是,这不是倾斜。你可以直接跳到 inro TD3,这无疑会有助于过拟合,但让我们尝试使用 RAdam 代替。换 optim 就行了。当你定义优化器时,从 Adam 到 RAdam。
搬到拉达姆
所以我用 RAdam 运行了同样的代码,这就是事情的经过。
DDPG Radam Error
Radam train actions
首先,没有令人讨厌的价值过度拟合。而且,价值损失较少。与 Adam 相比,收敛要慢得多。在 400 左右,你可以看到一个明显的下降趋势。这里需要两倍的迭代次数才能注意到这个模式。还有,价值损失平滑多了。火车的动作在欧几里德距离上有更大的距离。余弦距离似乎在所有实验中都保持不变。好了,让我们看看测试动作:
RAdam test actions: As you can see, we gained three times as much Euclidian distance and 1.5x cosine
成绩不言自明!使用 RAdam 可以更好地近似测试分布,但是训练分布更加模糊。然而,我们只关心测试。
Radam results for the reconstruction error.
然而,RAdam 有一个缺点。很难用它来微调模型。如果让模型运行 RAdam,训练分布将很快收敛到真实分布。此外,测试发行版将在最右边像一个小松果。需要注意接近-5 的策略损失,或者手动停止学习。如果你不阻止它,就会发生这样的事:
RAdam overfitting
政策网络过度拟合:价值正在迅速下降。亚当的情况并非如此。
Value tends to deteriorate for some reason as we will find out in a moment that is due to overfitting.
结合两者
我的最终解决方案是结合这两个优化器。首先,我用 RAdam 学习,通过在过度拟合之前创建检查点,我确保我有一个出色的预热模型。然后我加载这些模型,用 Adam 训练它们,以获得更好的性能。不幸的是,没有自动化的空间:您找到最小的策略损失,并从最近的检查点开始。
它可以更好地表现训练版,但是测试版要差得多。但是这种微调方法对 TD3 算法更有用。我们正在切换到…现在!
附注:所有模型都可以在 github 页面上下载(包括原始的拉达姆和经过微调的亚当)
TD3
TD3 代表双延迟 DDPG。三是论文作者提出的改进数量。正如我已经说过的,它是深层确定性政策梯度的延伸。区别如下:
- 无剪辑双 Q 学习。在这个算法中,我们有两个价值网络。此外,我们没有裁剪期望值,而是取最小的目标值。这个简单的技巧大大减少了政策代理人利用和愚弄批评家的机会,因为现在它必须愚弄他们两个。
#ddpg
target_q_value = target_value_net(next_state, next_action)
expected_value = reward + (1.0 - done) * gamma * target_q_value
expected_value = torch.clamp(expected_value, min_value, max_value)#td3
target_q_value1 = target_value_net1(next_state, next_action)
target_q_value2 = target_value_net2(next_state, next_action)
target_q_value = torch.min(target_q_value1, target_q_value2)
expected_value = reward + (1.0 - done) * gamma * target_q_value
2.延迟的策略更新。与价值观相比,我们更新政策的频率较低。对于每三个值的更新,我们只更新 actor 一次。这允许更好的价值估计,也防止演员愚弄。附注:这不是一个很难的概念,而且非常容易实现。我对 DDPG 使用了延迟策略更新。
3.动作平滑。TD3 向目标动作添加了噪声,通过平滑 Q 以及动作中的变化,使得策略更难利用 Q 函数错误。在我的例子中,噪声是从~Normal(0,0.1)中提取的,并被剪裁以适合[-.3,… 3]。
next_action = target_policy_net(next_state)
noise = torch.normal(torch.zeros(next_action.size()), noise_std)
noise = torch.clamp(noise, -noise_clip, noise_clip)
next_action += noise
TD3 结果
该算法具有与 DDPG 几乎相同的参数(不包括最小/最大剪辑,添加噪声参数)。所有的代码/数据集/预训练模型都在 GitHub 上。TD3 位于 notes/1 下。香草 RL/2.ddpg
TD3: Value loss is growing if you do not stop it. I stop it at 1000
Final loss
Test distribution is way better approximated
TD3: Train action pairwise distances 3x cosine 4x euclidean (compared to ddpg Adam)
TD3: Test action pairwise distances 3x cosine 4x euclidean (compared to ddpg Adam)
Real Action Distances. Most of them are somewhat between 10–12
唷!我们成功了!你看到的是我对政策方法的最终结果。现在让我们讨论损失和其他东西。首先:价值损失正在增加。这种现象是合理的,因为如果我们看价值观,他们不是过度拟合。在 ddpg 中,它们先上升,然后又下降。
TD3: value over time
真实动作和生成动作中的距离余弦距离不同。它大约产生 0.6,而真实值是 1。可以通过将噪声 std 设置为更高的值来增加噪声。然而,我认为这是欺骗,因为我们增加了更多的噪音。或者,您可以结合策略损失使用另一个损失函数来增加更多余弦多样性
在我以前的一次提交中,我用新的 Pytorch JIT 编译器实现了余弦和欧几里德距离损失惩罚。它返回成对距离矩阵,如上所示。你可以对这个东西做任何你想做的事情(即比较方差、标准差、均值、KL),使它看起来像一个真实的动作。
@torch.jit.script
**def** torch_cdist_euc(x1, x2):
x1_norm = x1.pow(2).sum(dim=-1, keepdim=**True**)
x2_norm = x2.pow(2).sum(dim=-1, keepdim=**True**)
res = torch.addmm(x2_norm.transpose(-2, -1), x1,
x2.transpose(-2, -1), alpha=-2).add_(x1_norm)
res = res.clamp_min_(1e-30).sqrt_()
**return** res@torch.jit.script
**def** torch_cdist_cos(x1, x2):
x1_norm = x1 / x1.norm(dim=1, p=2).unsqueeze(1)
x2_norm = x2 / x2.norm(dim=1, p=2).unsqueeze(1)
res = 1 - torch.mm(x1_norm, x2_norm.transpose(0,1))
**return** res
对预测进行排序
是时候测试我们的算法了。你可以下载所有预先训练好的模型,自己测试。该文件在 notes/results/1 下。排名/ (可点击)。
下面你会看到距离排名的例子。它支持 scipy。空间距离还是你的空间距离。在笔记本里,我收录了以下内容:欧几里德、余弦、相关、堪培拉、闵可夫斯基、切比雪夫、布雷-柯蒂斯、城市街区(曼哈顿)。余弦排名允许更好的语言和流派多样性,看起来非常类似于相关性。
DDPG
DDPG euclidian ranking
DDPG cosine ranking
TD3
TD3 euclidian ranking
TD3 Cosine Ranking
就是这样!你可以在这里看到两种算法的所有排名示例。
结论
所以我们在这里。如果你最终成功了,祝贺你。这似乎是一个简单的项目:只是使用现有的 Higgsfield 算法实现新数据,但我在过去的一个月里每天工作 6 个小时,以使它工作,计算出 DDPG 的参数,并了解 PyTorch 的深度,尽管这篇文章是最难的部分。我已经在写这个结论了,但是我还没有写完比较部分的受限玻尔兹曼机。回购未推出。我想知道结果如何…你明白了吗?
TD3 的实施前景看好。此外,排名很好,尽管还有改进的空间。我用的是 O(n)算法。如果你想在生产中使用嵌入,强烈推荐你查看一下 Milvus 库。
我也还没有实现一个网络应用程序。已经得到了我的另一个反应和基本布局回购提交。希望它能很快出版。如果没有,你可以自己做:所有的型号都发布了。
老实说,我没什么可说的了。我已经通过 7131 个单词了。
无论如何,这是我的一些想法:
- 因为这是一个推荐项目,你可以使用前 k 排名来采取行动。这些排名结果可用于帮助学习过程:
- 您可以添加另一个损失来计算实际排名和生成的操作之间的距离。(评论家的又一次损失)
- 分级行动的价值函数有何不同?它能根据距离进一步调整吗?
2.向生成的动作添加另一个余弦/欧几里德损失。上面公布了脚本。
3.实现一个排名网络。这是政策的延伸。它将动作作为输入,并根据 top k 排名学习生成真实动作。
如果你碰巧实现了这些,请随意提交。
谢谢您:
中:郭平、/ 기계공학부 ]、杰基·诺亚、沙迪·哈萨布、亚历山大·马凯夫、希瓦姆·阿克豪里、迪克沙·加尔格、西达斯·普拉布、佐哈尔·科马罗夫斯基、哈里·普拉萨德、帕纳吉奥蒂斯·卡普罗斯、维沙尔·施里尼瓦斯、伊维特·李、Lxs Lxs、尼尔斯·施吕特、阿尤什·库马尔、迪安·索、科迪·布什内尔、马库斯·奥、、谢纳维、桑惠恩、西蒙·于、张玉洲、黄、兰杰德·本、阿克塞尔·施万科
GitHub: 海军-谢、骑士 ofK9 、托马托、利斯塔希、 jungi21cc 、 nutorbit 、大卫江特、金明、 hb1500 、耶林敏、萨利赫-哈桑 陈明霞,阿什图,丁达诺维塔萨里,kk-海恩克,巴兹图,尤尤安尤,维-斯里,桑杰门,伊维特里——在我的项目实施之前,你们就相信了。 由你开始的那些开端激励我继续工作。
如果没有你出色的课程和指导,我不会写这篇文章。希望明年我能去 MIPT。
对新来者:
请随意介绍你自己。上了高中就开始深度学习了。尽管那时,我创建了无数其他主题的 GitHub 项目,但这些项目并不逊色。唯一的问题是没有人知道这件事——除了几个朋友,没有一个人知道。如果你正在努力做某件事,一定要告诉你这件事。是别人的欣赏让你不断前进。附言:不要再为学龄前儿童写另一个 Keras 教程;)
下一篇文章
最近,我发表了一篇新文章,内容涉及强化推荐系统:
在我的强烈推荐下,OffKTopPolicy 现在可以开箱即用,没有任何先决条件…
towardsdatascience.com](/top-k-off-policy-correction-for-a-reinforce-recommender-system-e34381dceef8)
还会有什么
下一篇文章将解决一些我们没有探索的问题。这当然需要一些时间,但在我看来,BCQ 很容易融入 DDPG。如果您想了解更多关于使用静态数据集的 RL 应用程序的信息,请访问以下链接:
Arxiv 文章:【https://arxiv.org/abs/1812.02900
Pytorch 代码:【https://github.com/sfujim/BCQ
有问题吗?评论是开放的…
GitHub 回购:https://github.com/awarebayes/RecNN
别忘了鼓掌!
再见!