与神经科学保持同步:2021 年 7 月必读
DeepMind 🧠谈深度强化学习和神经科学;艾👍🏻重新提出了 SGD 动力学的数学基础;果蝇🪰启发神经网络优于经典 ones⚡⚡⚡
加固。图片由 Ricardo Gomez Angel 在 Unsplash 上拍摄
https://medium.com/@stefanobosisio1/membership
你为什么要关心神经科学?
神经科学是当今人工智能🧠的根源🤖。阅读并意识到神经科学中的进化和新见解不仅会让你成为一个更好的“人工智能”的家伙😎而且还是一个更好的神经网络体系结构的创造者👩💻!
今天这里有三篇来自 arxiv.org 的新论文。DeepMind 和 UCL 发表了一篇关于深度强化学习及其对神经科学的影响的精彩评论。毫无疑问,这是一个热门话题,将会有更多的论文发表,以及关于人类大脑的新发现!第二篇论文是脸书·艾写的。研究人员已经对扩散 SGD 动力学的起源及其与统计物理的关系进行了奇妙的数学工作。这些暗示揭示了神经网络最初应该如何在纸上创建,具有正确的设置和期望,而不是等待“随机”收敛。最后,KAIS 的研究人员发表了一项基于稀疏编码的模型的伟大工作,以模仿果蝇的嗅觉系统,这优于经典的香草模型。享受:)
深度强化学习及其神经科学含义
Matthew Botvinick,Jane X. Wang,Will Dagney,Kevin J. Miller,Zeb Kurth-Nelson, 论文
在这篇论文中,DeepMind 和 UCL 的作者撰写了第一篇关于深度强化学习(DRL)在神经科学中的应用的综述。尽管 DRL 的研究才刚刚开始,但对神经研究的潜在影响却非常大。事实上,DRL 反映了大脑组件(神经元)、连接(突触)和系统必须自行学习的环境情况。DRL 可能会导致对什么是记忆,以及动物和社会认知如何管理情境探索的更深入的见解。总结本次审查,我们可以定义这些部分:
- DRL 对神经科学的早期研究
在文献中,我们可以找到 DRL 的神经任务的早期方法:
Yamins & DiCarlo 创建了一个深度卷积网络来模拟猕猴腹部流各个部分的组成;
Niv 进行了寻找阶段性多巴胺释放与时差报偿预测误差信号(RPE)之间联系的研究;
【宋、杨和王设计了一个网络来解决实验研究中猴子的任务。由此产生的模式与神经生理学实验数据密切相关。
- 元和分布学习
王等 探索了元强化学习:对于特定的相互关联的任务,网络能够在不改变权值的情况下适应新的任务,突出了隐含网络结构中的动力学效应,即慢 RL 驱动学习和快 RL 学习;
达布尼等人。将 DRL 带入了一个新的场景,*分布 RL,*即 RL,其中 RPE 不仅是一个标量,还是一个向量,更类似于与大脑相关的结构,并为任务提供了更广泛的概率
图 1:分布 RL:图中显示了达布尼的实验。a)时差任务。经典 RL 算法返回相同的 RPE,而在分布式 RL 中,RPE 的值可能有很大不同,导致概率从悲观到乐观。b)在这种情况下,代理必须学会在平台之间跳跃,概率回报分布显示在右边。c)真实案例场景。用概率奖励训练老鼠是可能的(右边灰色阴影区域)。奖励可以清楚地解释为一个分布 RPE。(图片由作者提供)
- 米艾默里
DRL 可以帮助我们理解记忆是如何支持基于奖励的学习和决策的。
Mnih 展示了 DRL 模型如何依靠记忆/经验重放,存储过去的经验,并在雅达利游戏的新挑战中使用它们,模仿海马体进行记忆巩固;
Pfeiffer 和 Foster 研究了在线决策的记忆维护和提取。特别是,在 DRL,在线决策是两个记忆之间的相互作用:一个是“情节”记忆,它读取和写入长期记忆槽,另一个是“激活”记忆,即存储激活信息;
- 探险
对于 DRL 来说,探索是一个棘手的概念,因为 RL 算法通过测试新的可能性和组合来找到解决方案。
内在动机作为 RL 探索的替代方案出现,并由 Badia 和 Osband 进一步发展,在那里代理人被鼓励探索预测不那么有信心的新环境。
关于这个研究领域,元学习提供了有趣和有前途的解决方案。元强化学习系统中的探索可以被认为是假设驱动的实验,这使得该解决方案成为研究动物任务探索的最有吸引力的解决方案之一
- 社会认知
社会认知是神经科学中一个不断发展的领域。DRL 最近在这一领域有了新的发展,有了多智能体场景,比如竞技团队游戏或社交困境。有希望的未来研究致力于潜在的心智模型,被称为‘心智理论’
重新思考 SGD 的极限动力学:修正损失、相空间振荡和异常扩散
大卫·库宁、哈维尔·萨加斯图伊-布雷纳、劳伦·吉莱斯皮、埃希德·马尔加利特、田畑秀则·田中、苏亚甘古利、丹尼尔 L.K 亚明斯、 论文
这是斯坦福、NTT 和脸书人工智能研究人员的一项了不起的工作,他们研究了随机梯度下降(SGD)的动力学,将模型超参数探索与统计物理联系起来。作者从基本假设出发,认为现在的神经网络模型缺少理论驱动的设计。事实上,训练通常是通过启发式参数完成的,并且没有将超参数优化与神经网络体系结构和数据集的几何结构联系起来。这项研究试图量化所有这些元素如何在 SGD 动力学中发挥作用,理解为神经网络的学习动力学建立完整理论的关键步骤。
图 2:5 个卷积神经网络的局部(上图)和全局(下图)位移的平方欧几里德范数。尽管模型的性能已经收敛,但是在训练之后,模型仍然在探索相空间。对于局部位移,这以固定的恒定速度发生,而对于全局位移,存在扩散的准布朗行为
首先,作者挑选并训练预训练模型,并监控局部参数位移(逐步超参数之间的差异)和全局参数位移(当前步骤的超参数与预训练模型的参数之间的差异)的波动。如图 2 所示,局部位移(图 2 顶部)继续以恒定速度波动,而全局位移(图 2 底部)根据幂 c 以布朗方式演变为步数的函数。这就产生了下面的问题:为什么网络在训练结束时继续扩散地探索相空间?
为了回答这个问题,作者将 SGD 建模为欠阻尼的朗之万方程。朗之万方程描述了一个粒子在随机力作用下的运动。这种随机力是布朗运动的本质,由于周围分子的碰撞,朗之万计算返回了流体中粒子运动的统计数据。将 SGD 建模为朗之万过程,作者发现欠阻尼版本的朗之万方程正确地模拟了相空间中网络的波动轨迹。
在以下设置下,作者用 SGD 分解线性回归,发现由 SGD 驱动的相空间探索导致了奥恩斯坦-乌伦贝克过程(OU 过程)。OU 过程是一个嘈杂的松弛过程。例如,弹簧可以在长度上摆动。在过阻尼的情况下,会有一个摩擦系数阻碍波动。如果存在热波动,弹簧长度将围绕弹簧静止长度随机波动。由此,通过使用梯度噪声和 Hessian,可以计算超参数优化过程的统计矩的解析表达式。第一个矩描述了扩散过程的振荡行为。二阶矩可以洞察驱动随机成分。
为了进一步理解这第二个组成部分或 SGD 扩散行为的驱动力,可以将 OU 过程发展为 Fokker-Plank 方程(FP 方程)。FP 方程返回了朗之万动力学下粒子位置分布的时间演化。在这一点上,作者意识到,关于线性回归,数据分布中的各向异性导致梯度噪声和扩散中的各向异性。对于大多数数据集,SGD 轨迹不是由原始最小二乘损失驱动的,而是由修改的损失驱动的。
也可以为神经网络计算这种修改的损失。根据经验,作者可以确认超参数的优化受到扩散指数的强烈影响,扩散指数表现为学习速率、批量大小和动量的函数。所有这些元素独立地起作用,并引起异常扩散机制。此外,较大的学习速率会导致欠阻尼振荡,从而降低扩散指数。另一方面,批量大小不影响阻尼比,但导致对扩散指数的非单调影响
果蝇持续学习的算法洞察
杨慎,Sanjoy Dasgupta,Saket Navlakha, 论文
这是一篇精彩的灵感来自大脑的方法论文,旨在创建一个可能能够匹配神经网络性能的新模型。作者研究了果蝇如何不断学习将气味与行为联系起来,发现了一种新的人工神经网络,它可以超越经典网络,而无需反向传播。特别是,连续学习对于现代神经网络来说是一项复杂的任务,因为经常会出现灾难性的遗忘问题。受果蝇嗅觉系统的启发,作者创建了一个模型,该模型使用稀疏编码、突触冻结和感知器式学习来学习并返回任何气味的特定动作。
图 3 两层嗅觉系统网络:A)嗅觉系统表示。当一种气味被接收时,一个深层的两层网络被启动。投射神经元对输入信号进行预处理。然后,由凯尼恩细胞(KCs)执行随机投影。通过 APLs 反馈,只有 5%的细胞被激活,并能与 MBONs 相互作用,根据行为对气味进行分类。b)当第二种气味进入时的例子。在这个阶段,不同的 Kenyon 细胞被激活,产生与不同 MBONs 的相互作用
果蝇有两层嗅觉系统(图 3)。当闻到一种气味时,就被投射神经元(PNs)的放电频率编码。PNs 响应进入第一层。在第一层中,2000 个凯尼恩细胞(KC)通过从 PNs 中随机采样,将 PNs 输入表示转换成稀疏和高维的表示。然后,信号被发送到抑制性神经元(APL),反过来,抑制性神经元将抑制反馈到每个 KC。因此,95%的低点火 KC 被关闭,剩下的 5%用于赢家通吃(WTA)计算。第二层把气味和行为联系起来。这是通过 KCs 和蘑菇体输出神经元(MBONs)之间的相互作用来完成的。KCs 细胞以相同的重量向“接近”和“避开”MBON 细胞发出气味。如果气味与不良行为有关,就会释放一种多巴胺信号来减少 KCs 和“接近”MBONs 之间的联系。
计算对应物也在 2 层电路中实现(FlyModel)。第一层计算输入信号的高维稀疏表示。输入层通过稀疏的二进制随机矩阵连接到第一层。然后,应用赢家通吃过程,仅顶部最活跃的 KC 保持开启,而所有其余的被设置为零。第二层看到这个稀疏的输入。给定学习速率和背景记忆衰减,可以在输入和输出之间编纂权重更新规则(论文的等式 3)。
该电路已经在 MNIST-20 数据集上进行了测试,其中训练数据被排序并分成顺序任务,并与以下各项进行比较:
- EWC:弹性权重合并模型,其中费雪信息标准用于确定权重
- GEM:梯度情景记忆,存储以前学习任务的数据子集
- BI-R:大脑启发的重放,它用一个生成模型来重放活动模式,从而保护旧的记忆
- 标准全连接神经网络
- 离线,像香草,但学习任务随机,而不是顺序
结果,FlyModel 的表现超过了所有的模型。对于 MNIST-20,FlyModel 达到了 0.86 的精度,而 BI-R 为 0.77,GEM 为 0.69,EWC 为 0.58,Vanilla 为 0.19。此外,在训练步骤结束时,FlyModel 的记忆损失只有大约 7%。对于 CIFAR-100 数据集记录了类似的结果
为什么 FlyModel 取得了类似的成绩?FlyModel 的主要特点是稀疏编码和突触冻结。两者在神经科学界都很有名,研究人员发现这些方面对学习和大脑启发的模型有巨大的影响。然而,很难确定为什么这些特征也是顺序学习的关键因素。
请记住这篇文章是一篇开创性的工作,可以让你进入一个更受生物大脑启发的神经网络世界:)
我希望你喜欢 2021 年 7 月神经科学arxivg.org
论文的这篇综述。请随时给我发电子邮件询问问题或评论,地址:stefanobosisio1@gmail.com
与神经科学保持同步:2021 年 6 月必读
稀疏神经连接🖇️如何影响功能行为?一个更符合生物学原理的反向传播:误差向量广播📡,又是如何关注 work⚡⚡⚡的?
图片来自 Unsplash
https://medium.com/@stefanobosisio1/membership
你为什么要关心神经科学?
神经科学是当今人工智能🧠的根源🤖。阅读并意识到神经科学中的进化和新见解不仅会让你成为一个更好的“人工智能”的家伙😎而且还是一个更好的神经网络体系结构的创造者👩💻!
今天这里有三篇来自 arxiv.org 的新论文。第一个研究稀疏连接性及其对功能模块性的影响。第二篇文章提出了一种反向传播的新方法,这可能在生物学上更合理——毫无疑问,这里应该进行大量的研究。最后,第三篇论文研究深度学习神经网络中的注意力,试图捕捉注意力在大脑中是如何工作的。
极度的稀疏导致了功能的专门化
加布里埃尔·贝娜,丹 F.M 古德曼, 论文
神经网络是模块化,也就是说,它们可以分解成独立的子网。这些子网络呈现出结构模块化,其中神经元被划分为不同的模块,以及功能模块化,其中每个模块都可以执行独立的操作。给定这些概念,结构模块化和功能模块化之间有关系吗?我们能评估结构模块化在多大程度上影响功能模块化吗?作者对这些方面进行了研究,提出了一种可控的结构模块化神经网络,并监测功能模块化度量,了解这两种模块化在多大程度上相互影响,试图找到神经生物学对应物的答案。
具有高模块化的网络在模块内的节点之间具有密集的连接,但是在不同模块的节点之间具有稀疏的连接
所提出的架构由两个子网络组成。这些网络作者具有不同程度的互连,从不同子网络模块中的节点之间的稀疏连接,到实现全密集架构时的无模块性。作为输入任务,每个子网接收一个 MNIST 数字,并且该网络必须与所有其他子网通信,以返回跨网络的两个数字是否具有奇偶性。同时,每个子网能够专门识别它们自己的数字。为了测量功能模块性,作者监控了三个度量标准:
- 瓶颈度量:在读出以检查它们是否能够识别输入数字之后,窄的 5 个神经元层的平均准确度
- 权重屏蔽度量:这是一个专门化的度量,其中保留了来自一个子网络的参数的子集 q% ,以检查给定任务的性能
- 相关性度量:对隐藏层进行分析,计算相同数字示例的子网络 n 的隐藏状态之间的皮尔逊相关系数
图 1 显示了所研究的子网的三个度量中的每一个的最终结果。总的来说,所有这三个指标都随着网络的结构模块性而变化,用稀疏性(活跃连接的比例)和 Q 模块性来衡量。可以得出以下结论:
- 强加结构模块化(Q 模块化的高值)导致更多的功能模块化(活动连接比例的高值)
- 在稀疏性或结构模块化的极端水平上,我们在所有三个度量上都有高度的结构专门化
- 需要高水平的结构模块性(Q 模块性)来确保功能模块性——即功能模块性可以通过子网之间非常稀疏的连接来实现
图 1:左边是两个子网络之间的稀疏度,右边是 Q 模块度。线条表示该指标的平均值,而阴影区域表示同一实验的 10 次重复的 1 个标准偏差
这些结论对生物神经网络有显著的意义。连接组学的整个思想,即知道网络的结构属性就足以让我们理解功能属性,可能不再正确。正如作者所写的:
我们不应该仅仅通过观察适度的结构模块化来得出任何程度的功能模块化
通过广播全局误差向量的信用分配
大卫·g·克拉克,L.F 阿博特,钟素妍, 论文
神经回路不实现反向传播方法(BP),因为进化已经找到了另一种算法或路线,允许回路可塑性工作并训练所有的大脑网络。BP 的一个可能的生物学解决方案是学分分配——这里是我们讨论学分分配问题的回顾——一个神秘的全球学习信号在整个网络中传播。
从这里,作者提出了一种新的替代 BP 的方法,称为误差向量广播(GEVB) ,其中全局学习信号被广播到神经网络中的所有隐藏单元以更新权重。特别地,在网络上分发的信号是关于输出误差的信息,充当无单元特定反馈。实现 GEVB 的神经网络被称为矢量化非负网络(VNNs) 。此外,GEVB 回忆起生物神经网络,对第一层施加非负权重,因为它发生在皮质投射神经元的兴奋行为上。最后,通过由突触前激活和全局误差向量的内积给出的量来更新每个权重。图 2 显示了理解 BP 的各种替代方案的差异的图形方式。
图 2:关于反向传播(BP)算法的替代实例:a)BP 算法,其中通过逐步转置误差来逐层更新权重;b)反馈对准(FA ),其中误差被逐层向后发送;c)直接反馈对准(DFA ),其中误差被直接广播到每个隐藏层;d)提出的全局误差向量广播(GEVB ),其中全局误差向量被广播到所有隐藏单元,而没有单元特定的反馈。
我们有什么结果?首先,作者尝试使用矢量化非负网络(非负权重网络)和传统网络,针对不同的连接范围,针对 MNIST 和 CIFAR-10 数据集,比较 BP 和 GEVB。我们的注意力将集中在矢量非负网络上,如表 1 和表 2 所示。总的来说,误差比较在不同的连接性和权重更新算法上是兼容的,在 GEVB 和 BP 之间有显著的重叠
表 1 矢量网络的 MNIST 检验误差(%)比较,在不同连接范围(完全连接、卷积连接、局部连接)下,GEVB 和 BP 之间具有非负权重或混合符号 wegiths。
标签。2: CIFAR-10 测试误差(%)比较,术语根据表 1
当使用 t-SNE 对 CIFAR-10 图像进行聚类时,获得了进一步令人鼓舞的结果,其中 GEVB 聚类质量在统计上优于 BP 方法。
这些显著结果可能为使人工神经网络更类似于生物神经网络铺平新的道路。GEVB 算法提出了一个新的问题,关于矢量化的生物学实现,以及突触前和突触后神经元的响应如何相互干扰,在网络中传播“权重更新”信号。伙计们,请继续关注!
通过内部门控的基于对象的注意
乔丹·雷,阿里·本雅明,康拉德·保罗·柯丁, 论文
注意力是大脑用来选择给定刺激或特征的有意义子集的机制
大脑中的一个神秘机制是注意力。计算神经科学和机器学习已经成功地为我们提供了使用注意机制在简单任务中检测和识别对象的模型。使用深度神经网络已经取得了更彻底的结果,这些网络被证明能够理解更复杂的场景,但是,它们仍然远远不能达到人脑的水平。人类大脑的注意力可以被认为是这些给定元素的混合:
- *神经激活的调制:*当受试者识别一个物体时,视觉神经元表现出活动的变化,从大约 5%到 30%的调制,增加了视觉皮层中的注意力机制
- *注意力不变调谐:*虽然神经活动的调节是开启的,但是注意力保持神经元的调谐特性不变
- *内部门控:*注意力是过滤不相关的特征,返回更清晰的信号
- *分层处理:*在大脑中,存在着分层组织的细胞,这些细胞呈现出广泛的调谐特性。这使得大脑能够学习复杂的非线性特征。这些细胞的输出增加了注意力层收集的信息
- *自上而下的注意神经调节:*以视觉问题为例,信息是以前馈、反馈、横向流动的方式行进的。反馈和横向流动使自上而下的注意成为可能,而前馈路径则定义了早期层中的感受野。
- *返回抑制:*由视觉输入激活的区域被抑制,以允许受试者从一个检测到的物体移动到一个新的物体。
作者提供了一个新的神经网络模型,它可以包含所有这些特征,以便研究对视觉刺激的注意力的本质,试图复制生物学上正在发生的事情,以给出一个似乎合理的生物学答案。
图 1 显示了实现的神经网络,其被细分为 3 个主要区域,反映了大脑视觉路径。存在三条线,前馈(黑线),其可以生成特征图并返回预测;实现注意力屏蔽的反馈通路(橙色线)和将前馈通路投射到反馈通路上的水平连接(绿色线)。注意力屏蔽在 V2 中充当内部注意力门控,并且在最后阶段,创建像素空间可解释的图像。最后的结果对注意及其机制给出了一个可能的解释
图 3:左边是实现的基于注意力的神经网络,右边是视觉注意力路径,因为它可能在大脑中。所实现的神经网络的特点是保持前馈、横向和反馈连接。
图 4 显示了 MNIST 和可可数据集的结果。根据注意机制,原始输入在不同阶段被处理。门控输入显示了注意力如何作用于输入图像,黑白区域是受抑制的区域,黑色区域是不受抑制的区域。注意掩码驱动门控机制,集中在最重要的区域,最后,IOR 掩码(返回的抑制)指定哪些区域已经被检查,哪些区域将被抑制用于将来的迭代。
图 4 是 MNIST 数据集(左侧)和可可数据集(右侧)的关注层的结果。
这种学习方法促进了对大脑中注意力机制的理解,这种机制是前馈、反馈和与内部门控和返回抑制的横向联系的混合。从神经网络输出来看,似乎有一个处理对象的一般注意规则:
- 神经元的调谐曲线不会改变
- 在不同的神经层次都有抑制
- 在深层神经层有一个注意力的峰值调制
这项研究为更深入地理解注意力奠定了基础,但未来的工作必须继续。与前一篇文章相关的一个注意事项是:如果我们对网络实现一个更符合生物学原理的反向传播算法,比如 GEVB,会怎么样?
我希望你喜欢 2021 年 6 月神经科学arxivg.org
论文的这篇综述。请随时给我发电子邮件询问问题或评论,地址:stefanobosisio1@gmail.com
与神经科学保持同步:2021 年 3 月必读
本月:脸书人工智能 vs 大脑信号👍人工神经网络中的树突🚨理解视网膜动力学中的错觉👁️
深度递归编码器:模拟大脑信号的可扩展端到端网络
奥马尔·谢哈布,阿列安德烈·笛福塞,让-克里斯托夫·卢瓦索,亚历山大·格拉姆福特,让-雷米·金, 论文 , 代码
这篇论文直接来自脸书人工智能研究所、巴黎大学和巴黎高等师范学院的合作。这篇论文的主旨是设计一种新的方法来帮助神经科学界分析大脑对感觉输入的反应。特别是,作者将注意力集中在从阅读活动中获取大脑信号,定义单词长度和单词使用频率在大脑中的反映。
事实上,来自人类任务的大脑记录经常是非常嘈杂和高维的。只是给你一个想法,一个小的眨眼可以破坏信号记录,以及心脏跳动需要考虑在内,以避免太多的噪声存在。迄今为止,神经科学界试图用线性技术来破译这些记录,如时间感受野(TRF)或递归时间感受野(RTRF),然而,这些技术无法处理记录信号产生的如此多的非线性。
为了解决这一挑战,作者提出了一种特定的端到端深度学习架构,经过训练可以一次预测多个受试者的大脑反应(深度递归编码——DRE)。该架构基于两个相互堆叠的改进的长短期记忆(LSTM)模块。输入数据通过卷积层和 ReLU 函数进行编码,然后 LSTM 模型对隐藏状态进行排序,最后通过卷积转置 1D 层和 ReLU 激活函数转换回 MEG 活动估计。
该模型在 68 名受试者身上进行了测试,他们有一个小时的阅读任务,同时用 273 通道的 CTF 脑磁图扫描仪进行记录。这项任务包括快速阅读屏幕上闪现的大约 2700 个单词。4 个众所周知的特征在这项研究中受到关注:单词长度、自然语言中的词频、序列中第一个和最后一个单词的二元指示器。
结果证明,不仅 DRE 比经典的 TRF 方法更好地预测大脑反应,而且 DRE 的特征重要性突出了哪些特征是大脑反应中最突出的特征。图 1 示出了作为 MEG 扫描的空间位置的函数的单词长度和频率的排列重要性的结果。在后部脑磁图通道中,单词长度在 150 毫秒后达到峰值,而在额颞脑磁图通道中,单词使用频率在 400 毫秒左右达到峰值。此外,DRE 能够跟踪一个额外的现象,这是大脑中词汇处理的侧化。事实上,对于词频,峰值反应出现在两个半球,但在额叶区的左半球幅度很大。
图 1:经典线性方法(TRF)和 DRE 之间的比较,用于分析大脑区域的特征峰值。根据时间活动和大脑位置(颜色编码的大脑地形图),在两个模型中比较单词长度和单词(使用)频率。DRE 的字长在 150 毫秒左右出现峰值,这与后部脑磁图通道的活动有关。TRF 和 DRE 都在 400 左右出现词频峰值。DRE 女士强调这种反应来自大脑的 3 个区域,但活动集中在左半球。通过将单词长度(左侧)和单词频率(右侧)的排列重要性(δR)用作空间位置(由脑地形图中的通道位置进行颜色编码)和相对于单词开始的时间的函数
生物限制会损害树突计算吗?
伊莲娜·西蒙娜·琼斯,https://arxiv.org/abs/2103.03274论文
作者研究了人工神经网络(ANN)中树枝状非线性的影响。出发点是想知道将树枝状连接建模为线性积分器的主导思想是否有意义。事实上,由于其电压依赖离子通道,枝晶是高度非线性的。三点被确定为在人工神经网络中模拟更类似生物的树状结构的关键:
- 树突显示出非线性激活函数,其类似于泄漏整流线性单元(LReLU),但是可以用 NaCaK 函数(钠、钙和钾电压依赖性的总和)以更生物合理的方式建模;
- 通常树突输入是 0/1,但是它们可以被建模为基于电导的突触非线性;
- 由于类似于隔间之间的轴向阻力,树突的权重参数可以是正的和负的,或者建模为非负的值。
这三点可以看作是对 ANN(或约束)的一种生物学上的改进。这些约束在二叉树模型中实现,修改了不同论文中提出的经典 k 树算法结构,如图 2 所示,并且针对 7 个机器学习数据集的性能与对照 2 层全连接神经网络(FCNN)进行了比较。
图 2: (A):实现的 k 树模型,具有树状约束,以及“控制”完全连接的神经网络(FCNN)。蓝色节点是输入的突触非线性。白色节点应用可选的树枝状非线性。黑线是受约束的非负权重。“k”决定了有多少相同输入的子树在模型中重复,类似于不同树突树上重复的突触输入。“h”是 FCNN 隐藏层中的节点数。(LReLU 和树突的 NaCaK 激活功能之间的比较。©没有突触非线性和具有突触非线性的模型的比较(D)没有和具有非负权重约束的模型权重的比较。
通过将 MNIST、CIFAR-10、FMNIST、EMNIST、KMNIST、SVHN 和 USPS 数据集的 k 树结果与 FCNN 进行比较,作者得出了以下结论:
- 对于 MNIST、FMNIST、KMNIST 和 EMNIST,NaCaK 激活函数优于 ReLU、LReLU 和 sigmoid 激活函数,而对于 SVHN、USPS 和 CIFAR-10 数据集,达到类似的性能
- 突触非线性约束非线性地将树突的输入映射到实际的毫伏单位,影响 k 树的性能,对于 MNIST、FMNIST、KMNIST、EMNIST 实现了比 FCNN 更高的精度,并且对于 SVHN、USPS 和 CIFAR-10 实现了相同水平的精度
- 非负权重添加到 k 树非线性映射 synapse 在具有 synapse 的正 k 树和负 k 树的水平上执行或者比其更好。对于 MNIST、KMNIST 和 CIFAR-10,该模型优于 FCNN。
尽管有这些令人鼓舞的结果,目前的 k-tree 树突模型仍有一些局限性。首先,NaCaK 函数是一个近似值,因为在树突中有不止 3 个离子通道,尽管钠、钾和钙是最具代表性的离子通道。第二,非负权重是离子通道在整个树枝状形态中分布的结果。因此,比 k 树更现实的形态和每个节点的可学习的 NaCaK 函数的组合可以引入更多生物学相关的自由度,这可以影响模型计算性能。最后,k-tree 结构呈现对称性,这在真实的自然界中是不重复的。对多突触输入重复以及这些输入如何到达不同的树状子树的进一步研究是必要的,以允许架构被更好地训练。总的来说,这项研究显示了神经生物学的限制有多重要,以及如何在当前的人工神经网络文献中反映出来,以便找到更好的神经网络结构。
视网膜预期动力学中的信息协同
齐,周博宇,陈国华, 论文
我们的视觉很容易出现错误,这就是所谓的视错觉。例如,闪光滞后现象是一种保护机制,由我们的视网膜针对移动物体触发。同时,预期是一种时间错觉,它让动物从过去的经历中感知未来的事件。本文作者研究并证明了视网膜的预期可以描述为负群时延(NGD)现象。NGD 是一个物理模型,其中“预期”是由神经网络基于过去感知的延迟反馈创建的。
**为了研究这种效应,作者对青蛙的视网膜进行了实验和计算研究。从牛蛙身上切下一小块视网膜,固定在 60 通道多电极阵列 (MEA)上,灌注并充氧长达 10 小时。随机光刺激 x(t) 通过 LED 照明发送到视网膜,强度 I 与 x 成比例。视网膜的反应由 MEA 在不同频率 fc (1、2、3.5 和 5 Hz)和强度时间 0.5 s 的刺激下在 25°c 下记录。
图 3 显示了大约 20 个视网膜的预期效果的平均刺激结果。 x(t) 为随机信号, r(t) 为视网膜放电频率,即从受刺激的视网膜上提取的电锋电位。特别地, r(t) 可以包含由视网膜创建的预期信息,作为信号 x(t) 及其时间修改 ẋ(t).的结果对于刺激频率 fc =1Hz(或每秒 1 个周期)的实验,视网膜的响应被分析为跨神经网络的互信息,作为时滞δt 的函数,这对于视网膜来说足够小以产生预期的响应。人们可以清楚地看到I(r;x) 在原点的右边(0.0 s 处),表示来自视网膜的响应(尖峰)是 x(t) 的预期。此外,对于 I(r,ẋ,可以注意到额外的峰值,再次在原点的左侧,指示预期行为。图 3(b)显示了I(r;{x,ẋ})通过部分信息分解(PID),进一步证明了预期现象的存在。
图 3:来自强度 I(r,x)的刺激的视网膜检测信号。(a):随机光信号为 I(r,x),红色;δt 是时间延迟,蓝色、紫色和黑色表示视网膜对信号的预期反应。(b)部分信息分解贡献
接下来,作者用计算线性模型模拟了视网膜的反应。该模型结果依赖于参数 λ(t) ,该参数作为时间的函数而变化。 λ(t) 似乎取决于刺激频率 fc 以及神经节细胞的特性,神经节细胞负责视网膜中“预测”细胞的放电——即触发预期事件的细胞。
总之,这篇论文阐明了视网膜中发生的预期事件。这种现象来自一组细胞的原始刺激中不存在的信息的重组。特别是,似乎在输入信号 x(t) 和它的时间修正 ẋ(t) 之间存在协同作用,这引起了视网膜的预期。因此,视网膜电路能够以某种方式从 x(t) 中提取 ẋ(t) 的信息,然后将它们重组以形成棘波 r 。
我希望你喜欢这篇 2021 年 3 月神经科学 arxiv.org 论文的综述。请随时给我发电子邮件询问问题或评论,地址:stefanobosisio1@gmail.com
与神经科学保持同步:2021 年 11 月必读
我们能雇用甘斯吗💻在神经科学实验中🐁?几何流形是什么💎我们的记忆存在于?我们能进行生物启发的独立成分分析吗📈?
杰弗里·布鲁姆在 Unsplash 上拍摄的图片
https://medium.com/@stefanobosisio1/membership
你为什么应该关心神经科学?
神经科学是当今人工智能🧠的根源🤖。阅读并意识到神经科学中的进化和新见解不仅会让你成为一个更好的“人工智能”的家伙😎而且还是一个更好的神经网络体系结构的创造者👩💻!
本月 3 篇惊险论文!来自爱丁堡大学的科学家们第一次使用了生成对抗性神经网络,从而拓展了神经科学分析的边界。对小鼠进行了实验,以研究学习前和学习后阶段之间的神经元动力学变化。第二,斯坦福大学、普林斯顿大学、哥伦比亚大学和高级研究所合作,利用递归神经网络研究了记忆几何流形应该是什么样子。最后,罗格斯大学的研究人员展示了生物启发的神经网络独立成分分析的实现及其对神经形态计算的影响。
使用循环一致的对抗网络进行神经元学习分析 布莱恩·m·李、奥克利托斯·阿姆夫罗西迪斯、娜塔莉·l·罗什福尔、阿诺·翁肯、 论文
神经科学的核心研究领域旨在了解学习过程中发生的神经元重塑动力学。从神经实验中提取可解释的信号并进行有意义的分析现在已经成为进一步理解神经元动力学的优先要求。许多出版物显示了使用标准技术(如 TCA 的五氯苯甲醚)得出的显著结果,但是,这些标准技术具有线性响应和映射的基本假设。在这篇论文中,爱丁堡大学的研究人员将分析扩展到生成对抗性神经网络,特别是,他们采用朱的 CycleGAN 来学习神经元活动的学习前和学习后之间的映射。
CycleGAN 可以学习两种概率分布,在这种情况下是学习前和学习后的神经元动力学,并将一种转换为另一种。这一过程使我们能够更好地理解哪些可能是学习过程中出现的关键特征,以及从神经元获得即时反应模式。
在这个实验中,我们用一只头部固定的老鼠研究了学习前后的动力学,这只老鼠被放在一个可以前后移动的线性跑步机上。在鼠标前面,有一个带有明确光栅图案的监视器。如果鼠标能够在跑步机上前进 120-140 厘米,显示器将切换为黑色模式。在这里,如果老鼠在虚拟奖励区内舔了一下,就会得到奖励(水滴)。这项活动迫使老鼠学会利用屏幕上的视觉信息和自身运动来获得最大的回报。初级视觉皮层神经元用钙指示剂标记,并监测 4 天,随时间测量相对荧光。
第一天是学习前,第四天是学习后,所以从这几天开始,我们会分别得到学习前和学习后的概率分布。GAN 的生成器和鉴别器必须以数据驱动的方式识别与动物实验相关的模式。图 1 显示了 GAN 鉴别器和生成器的主要结果。前两个顶部图显示了分别计算为平均注意力掩模的学习前和学习后鉴别器注意力图。学习前鉴别器专注于虚拟动物位置上 100-130 厘米之间的特定神经元组,这与奖励区一致。学习后鉴别器突出了两组神经元,总是在 100-130 厘米左右。同样,对于发电机来说——两个底部的图。特别是,预学习生成器(左下方)专注于流程开始和结束时的活动(奖励区)。后学习生成器在奖励区之前给予更多的关注。这些结果表明,要了解从学习后到学习前反应的转变,最重要的特征是在老鼠到达奖励区时获得的。
图 1:来自 CycleGAN 模型的注意力地图,是老鼠在跑步机上每跑一段距离的平均值。上图:学习前(左)和学习后(右)辨别者的注意力地图。下图:学习前(左)和学习后(右)生成者的注意力地图。虚线表示奖励区。
总之,本文首次将 GAN 的方法应用于活体神经元实验。作者能够通过 GAN 生成的潜在特征来可视化学习过程,强调奖励区周围的活动在整个动力学中具有高度影响力。未来的研究必须加强记录过程,利用垂直和水平空间信息来丰富模型的特征。
连续变量工作记忆的递归神经网络模型:活动流形、连接模式、动态代码 克里斯托夫·j·库埃瓦、阿德尔·阿达兰、米沙·佐戴克斯、钱宁、 论文
我们的记忆能够以适当维度的连续结构存储信息。例如,考虑两个视觉刺激,它们在我们视觉区域的相同位置依次出现。刺激是一样的,唯一不同的是方向,比如一个刺激指向左边,另一个指向右边。我们的大脑如何将两个刺激识别为两个不同的刺激,并避免第二个刺激在记忆中覆盖第一个刺激?从数学和计算的角度来看,这是一个奇妙的问题。为了模拟大脑动力学,我们需要找到一种在模型中存储记忆的方法,利用一些几何特性。在这篇论文中,麻省理工学院、普林斯顿大学、哥伦比亚大学和 IAS 的研究人员通过递归神经网络(RNNs)研究了这个问题。rnn 用于存储两个不同方向的连续闪光,并研究网络的连接模式。RNN 之所以被选中,是因为他们能把刺激保持在记忆中。
图 2 显示了实验装置。延时后,两个输入信号按顺序给出。除了方向之外,信号是相同的。用于网络模式研究的 RNN 由 100 个全连接单元组成。
图 2:实验设置。(a)训练 RNN 记住两条线的方向,给定两条线之间的延迟时间。(b)RNN 建筑:100 个循环连接的单元。输入是 32 个方向调谐的信号线。输出由方向角的余弦和正弦表示
主要结果如图 3 所示。首先,作者将主成分分析应用于一段时间内循环单位的活动,以了解低维结构。当两种刺激都作为输入出现时,主成分图显示 Clifford torus 流形的出现。一个标准的环面流形——就像一个甜甜圈形状的物体——当它有两个不同方向的两个信号的两个宿主时就会变形。相反,Clifford 环面可以同等地表示这两种信号。在正交性检查中给出了进一步的证明(如图 3 所示)。如果我们在两个环面上运行正交性和平行性测试,我们可以看到标准环面如何不对称地处理角度,而 Clifford 环面可以对所有角度保持对称。在早期训练阶段的 RNNs 显示出与标准圆环相似的结果。在后学习中,RNN 单元可以识别不同的方向,给出关于 Clifford 环面的正交性和平行性测试输出。
图 3:标准环面和 Clifford 环面的区别。RNN 在早期训练阶段展示了标准环面几何的典型行为。学习之后,由于克利福德流形,记忆得以保留。
此外,作者研究了所有 100 个单位的连接模式。出现了在第一延迟周期期间存储关于特定线路的信息的单元在第二延迟周期期间不总是继续存储关于同一线路的信息。特别是,有一个权重的调整和平衡,这可以防止内存被覆盖。
结论是:
- 记忆可能存在于类似 Clifford 环面的几何流形上。这个环面可以保持信号的连续表示,其中任何信号都可以被区分,它是一个正交基。
- 在学习时,存储第一方位记忆的单元随时间改变它们的调谐,防止覆盖第一个存在的方位。
- 这可能是拥有更多类脑网络和记忆系统的通用解决方案
- 这是对 RNN 如何存储多个连续变量的解释
一种用于独立成分分析的规范且生物学上可行的算法 Yanis Bahroun,Dmitri B. Chkolvskii,Anirvan M. Sengupta, 论文
大脑是一个奇妙的机器,它可以很容易地将系统信号(如听觉、视觉和嗅觉系统)分开,从系统混合物中识别潜在的来源。这项任务被称为盲源分离(BSS)。在计算机科学中,通常用独立分量分析(ICA)来解决盲分离问题。ICA 假设潜在的刺激是独立源的线性组合。尽管在文献中有成千上万种 ICA 风味,但是很少有 ICA 具有生物学启发的实现。对作者来说,生物启发意味着该算法可以 1)以流的形式运行,而无需将数据集保留在内存中 2)如果 ICA 是神经网络的一部分,则应该使用局部学习规则来更新突触权重。作者从四阶盲识别(FOBI)过程中获得灵感,探索了一种可能的生物启发 ICA 算法。
ICA 算法是以这样一种方式构造的,使得它可以在生物似然神经网络(NN-ICA)中实现。首先,神经网络输入有 d 个神经元,是要分离成独立分量的输入数据。网络呈现输入和输出的树突之间的前馈突触,以及横向突触(图 4)。实际上,输入信号首先乘以神经元的权重矩阵。输出投影然后在输出层的树枝状部分被白化。最后,躯体区域通过用局部学习规则平衡权重来计算最终输出。
图 4:生物启发 ICA 的神经网络实现。输入信号由 d 个神经网络单元混合和接收。这里前馈突触分解输入信号。输出层由两个神经元组成,其权重遵循局部学习规则。输出的树枝状部分白化数据。身体空间重建了源头。蓝色阴影意味着输出活动被调节,以模仿大脑的可塑性。
图 5 显示了来自不同输入源的结果。图 5A 报告了合成数据,其中周期信号和随机噪声作为 NN-ICA 的输入给出。图 5B 报告了在 16kHz 下记录的真实世界语音信号的结果。图 5C 的结果来自自然场景图像,其中算法从混合图像中恢复所有元素。很明显,对于大范围的输入数据集,所提出的规则可靠地收敛到正确的解。此外,整个 NN-ICA 算法易于实现,除了扩展我们关于大脑如何能够执行 BSS 任务的知识之外,还可以进一步促进神经形态计算。
图 5:神经网络独立分量分析结果。a)来自周期信号混合的结果 B)真实语音数据分解 C)自然场景图像。
我希望你喜欢 2021 年 11 月神经科学arxivg.org
论文的这篇综述。请随时给我发电子邮件询问问题或评论,地址:stefanobosisio1@gmail.com
与神经科学保持同步:2021 年 10 月必读
脸书艾和因里亚👍🏻调查语言🗣️和 brain🧠;罗格斯·uni🇺🇸用生物反向传播算法推进了神经形态计算;🇩🇪 🇺🇸用信息论研究大脑状态👩💻揭示了社会任务的高信息含量!
https://medium.com/@stefanobosisio1/membership
你为什么应该关心神经科学?
神经科学是当今人工智能🧠的根源🤖。阅读并意识到神经科学中的进化和新见解不仅会让你成为一个更好的“人工智能”的家伙😎而且还是一个更好的神经网络体系结构的创造者👩💻!
这个月有很多激动人心的出版物!首先,FacebookAI 和 Inria 以及 CNRS 提出了一种新的基于模型的方法来研究大脑中的语言基础,带来了一种新的研究方法,可以与经典的和需要大量数据的实验相媲美。第二,Rutgers 大学对神经形态计算的一个了不起的改进,它定义了一个满足神经形态原则的生物启发的反向投影。最后,宾夕法尼亚大学、圣达菲大学、朱利希研究中心和亚琛工业大学合作,确定连接体如何节能和优化,以处理高信息量状态。
基于模型的大脑活动分析揭示了 305 名受试者的语言等级
夏洛特·柯谢特,亚历山大·格拉姆福特,让-雷米·金, 论文
正如我们在这个系列中多次看到的,语言的基础,语言在大脑区域中的结构,我们如何学习语言是神经科学研究中的热门话题。为了更深入地了解大脑内部的语言过程,神经科学家通常会运行一个标准的实验程序,该程序由 Lerner 等先驱成功应用,采用功能性磁共振成像(fMRI)。功能磁共振成像记录刺激后的大脑反应信号(例如,听一个故事,一个特定的段落,或杂乱的声音)。然后,对于单个受试者脑体素,利用来自其余受试者的平均脑体素活动,计算称为受试者间相关性(ISC)的相关性。最终的大脑地图定义了语言刺激特别激活的区域。虽然勒纳的技术已经被证明是成功的,但 fMRI-ISC 需要大量的数据来获得有意义的结果,随着受试者的数量乘以刺激的数量而扩大。在本文中,来自脸书 AI、Inria 和 CNRS 的研究人员提出了一个基于模型的 Lerner 实验,该实验使用更少的数据,可以达到与 ISC 研究相同的性能。
图 1 比较了这两种方法。如果一方面,Lerner 的方法“脑-脑关联”需要来自不同对象的大量记录来实现对大脑时间感受域(TRFs)的解释,那么“模型-脑关联”利用深度学习模型(如 GPT-2)的能力来实现相同的性能。GPT 模型已经得到了广泛的研究,它们在构造常规语音和修改的刺激响应的映射方面与人脑有许多相似之处。通过分析和提取第八 GPT-2 层的潜在特征,语言处理的层次被恢复和足够准确地预测。选择第八层是因为它是证明编码相关语言特征的转换器的中间层。
图 1:传统脑-脑关联和模型-脑关联的比较。a)在开创性的神经科学研究(Lerner 等人)中,每个受试者都有一个故事、故事中的一个段落、一个句子、特定的单词和声学加扰信号(条件)。b)对于每种情况,ISC 计算为平均脑反应和单个 y 脑反应之间的相关性。c)本研究试图复制传统方法,仅使用由常规故事诱发的录音。GPT-2 层用于提取加扰的激活信号。然后将该信号与线性变换后的受试者大脑活动进行比较。
图 2 报告了实验结果,其中每种颜色代表一种特定的刺激。基于模型的方法复制了相同的勒纳的实验表现,只使用 7 名受试者听 7 分钟的故事和混乱的叙述。作为收敛性的进一步证明,作者将该模型扩展到 305 名受试者,让他们听一个 4 小时的故事,展示了该模型是如何有效的。
这篇论文是一个很好的例子,它强调了自然刺激和深层神经网络对语言基础研究形成了一个强有力的结合。如果一方面我们需要了解一些深度学习模型的限制,另一方面我们可以为这些模型想出新的解决方案,将它们常规地用于体内研究。
图 2:传统神经科学研究之间的结果比较(Lerner 等人)。这种颜色描绘了大脑区域对一个段落(蓝色)、一个句子(绿色)、一个单词(黄色)和一个声音加扰信号(红色)的反应。a)在标准的无模型实验中,受试者听 7 分钟的故事或声音信号 B)基于模型的能够复制 Lerner 的研究,数据来自 75 个受试者听 7 分钟的相同故事。c)此外,基于模型能够将研究扩展到 305 个受试者,听 4 小时的 15 个音频故事。
BioGrad:用于脉冲神经网络的基于生物似然梯度的学习
唐,尼莱什库马尔,约安尼斯波利克雷蒂斯,论文
神经形态计算是一种新兴的计算范式。这种硬件是受大脑启发的,允许轻松旋转神经网络架构。最有前途的神经网络架构之一是脉冲神经网络(SNN),它已经显示出在神经形态硬件上解决人工智能问题的高能效、大规模并行和低延迟的解决方案。尽管他们取得了成功,SNN 还有一个障碍需要解决,那就是反向传播的使用。反向传播在传统的神经网络应用中已经被广泛使用,然而,它不是由人脑启发的。这导致研究寻找 backprop 的替代品,它可以满足三个神经形态原则:
- 基于尖峰的计算:每种计算都是基于尖峰的,应该提供节能的解决方案(backprop 没有)
- 局部信息处理:神经形态网络应该能够实现异步计算和大规模并行处理——这是 backprop 很难实现的
- 快速在线计算:网络不应需要来自未来时间步骤的信息(低延迟解决方案)
出于这些原因,罗格斯大学的研究人员在这篇论文中提出了生物学上看似合理的基于梯度的学习被称为 SNN 的生物梯度。图 1 显示了该算法的构建模块,它满足神经形态计算原理。该算法的核心是使用一个多隔室神经元模型,该模型由一个锋电位的躯体部分和一个非锋电位的心尖区组成。特别是,体细胞区域将前馈突触前输入整合到其膜电压中,每当电压高于阈值时就会出现尖峰。顶室接收来自错误神经元的自上而下的反馈,整合其膜电压。引入周期性睡眠阶段,使得权重以无监督的方式用局部 Hebbian 规则和随机输入更新。
图 3: A)使用 BioGra 实现的建议 SNN。SNN 从输入尖峰开始,由隐藏层进行处理。每个隐藏层作为 BioGrad 实现,由顶端(红色圆圈)和体细胞(蓝色圆圈)隔间组成。顶端隔室具有从错误神经元接收的自上而下的反馈(红色箭头),而体细胞隔室整合前馈输入(蓝色箭头)。b)调查 BioGrad。我们可以识别学习和睡眠阶段。睡眠阶段基于资格轨迹更新神经元的权重 C)突触前和反馈尖峰对隔室电压和资格轨迹的影响的例子。
该实验装置在 MNIST 数据集上进行了测试,并与生物启发的方法进行了比较(表 1)。BioGrad 在 MNIST 数据集上实现了 98.13%的准确率,这优于或相当于其他方法,但是这些方法不满足神经形态学原则。BioGrad 还经过了标准反向投影算法的测试,采用随机梯度下降或 Adam 优化器,达到了相同的精度水平。
最后,为了表明 BioGrad 算法可以直接在片上使用,作者在英特尔的 Loihi 处理器上部署了该模型。由于硬件限制,训练是在单个隐藏层上进行的,MNIST 上有 100 个隐藏单元。最终测试准确率为 93.32%,每个训练样本消耗的能量比在 GPU 上少 400 倍。
表 1:MNIST 数据集的 BioGrad 与文献中生物学启发的 backprop 的比较。BioGrad 是唯一一个满足所有三个神经形态学计算要求的方法,达到 98.13%的准确率,与其他方法相当或更好。
大脑状态的信息内容由状态能量学的结构约束来解释
莱昂·韦宁格、普拉加·斯里瓦斯塔瓦、戴尔·周、杰森·z·金、伊莱·j·康布拉斯、麦克斯韦·a·贝尔托莱罗、乌特·哈贝尔、多里特·梅尔霍夫、达尼·s·巴萨特、T3【论文】
大脑在处理一条信息时会发生什么?我们认为这一信息触发了信号传播,信号沿着大脑的结构连接体传播并引发变化。然而,我们对这些变化了解多少呢?不同状态之间的过渡如何?在宾夕法尼亚大学、亚琛工业大学、Julich 研究中心和圣达菲研究所的合作中,作者研究了 fMRI 数据集的信息内容,并证明了以下假设:
- 基于特定的认知功能,大脑会显示不同层次的信息内容
- 结构连接体被组织起来以支持观察大脑状态的转换,具有高效的能量消耗
- 达到高信息含量状态所需的能量大于达到低信息含量状态所需的能量。
图 4:信息内容状态研究。a)fMRI 可以基于特定活动 x(t)跟踪大脑区域的激活强度 B)从 fMRI 中,可以从激活的直方图中检索信息内容及其大小 C)从一个区域的激活强度,作者通过该区域的信息理论确定信息内容(Iparcel)。也可以检索整个大脑的信息内容,对大脑的所有区域求和。d)给定一个控制信号,大脑的状态从初始状态(E)移动到最终状态。f)这种运动是由能源景观决定的。
图 5a 示出了对 596 名受试者的所有观察任务的平均信息量的分析。有趣的是,社会活动任务显示出比所有其他任务显著更高的信息含量。另一方面,赌博和情绪任务显示出较低的信息含量。此外,如图 5b 所示,作者已经研究了信息内容在大脑区域的分布。工作记忆、情绪和关系任务显示出正偏斜,表明大脑中各向异性的区域分布,一些区域比其他区域贡献更大。总的来说,剩下的任务显示了高斯分布。
图 5:对 596 个亚受试者进行功能磁共振成像扫描,得到不同活动的信息内容。a)为不同活动计算的平均信息量。平均而言,社交任务的信息量较高,而情感和赌博任务的信息量最低。b)信息内容的地区差异。总体而言,大多数任务呈高斯分布,而工作记忆、情绪和关系任务呈正偏态分布。
偏斜分析导致作者调查高信息状态的能量需求,高信息状态应该远离平均状态,并且应该比低信息内容的状态需要更高的能量。事实上,根据统计分析,高信息状态(如社交任务)需要更高的能量来驱动大脑进入这些状态。特别是,结构连接体看起来结构膨胀,达到高信息含量状态,满足最终论文的假设。
综上所述,作者对 fMRI 进行了全面的统计分析,以检测大脑信息内容。社交任务显示的信息含量最高,而情感和赌博任务的权重较低。将大脑作为一个整体来分析,信息内容对大脑区域之间的任务差异很敏感,这可以用作理解大脑动力学改变、功能障碍和精神病理学的关键假设。最后,本文证明了信息论可以如何容易地应用于神经科学,以及我们可以有多少关于大脑能量约束和连接体的发现,以在不久的将来进一步扩展人工神经网络。
我希望你喜欢 2021 年 10 月神经科学arxivg.org
论文的这篇综述。请随时给我发电子邮件询问问题或评论,地址:stefanobosisio1@gmail.com
与神经科学保持同步:2021 年 9 月必读
星形胶质细胞在记忆处理中的作用✨:SISSA 的研究人员致力于生物学启发的强化学习🧬;普林斯顿大学🎓和数学神经网络记忆流形👩🔬
图片由博斯科在 Unsplash 上拍摄。一张夜间高速公路照片完美地再现了在黑暗中寻找大脑连接答案的过程。
https://medium.com/@stefanobosisio1/membership
你为什么应该关心神经科学?
神经科学是当今人工智能🧠的根源🤖。阅读并意识到神经科学中的进化和新见解不仅会让你成为一个更好的“人工智能”的家伙😎而且还是一个更好的神经网络体系结构的创造者👩💻!
这个月 3 篇惊人的论文!第一个向我们展示了人脑和人工神经网络中星形胶质细胞的重要性。星形胶质细胞对于人类的记忆存储和处理至关重要,本文为所有数据社区敲响了警钟,让他们更密切地关注生物启发的神经网络。第二篇论文来自 SISSA 神经研究人员,他们将行为克隆规则转化为强化学习,使这种方法更受大脑启发。最后一篇论文是普林斯顿大学的一项艰巨工作,在那里,作者创建了一个新的门控递归神经网络(gRNN),它可以存储记忆而无需微调参数,只是从 gRNN 的基础知识中发展了进一步的数学见解。尽情享受吧!😃
星形胶质细胞在多层神经元-星形胶质细胞网络中介导模拟记忆
尤利娅·齐比纳、因诺肯蒂·卡斯塔尔斯基、米哈伊尔·克里沃诺索夫、阿列克谢·扎伊金、维克托·卡赞采夫、亚历山大·戈尔班、苏珊娜·戈尔德列娃
我们能在人工神经网络中模拟星形胶质细胞吗?人脑中星形胶质细胞的作用是什么?在这篇论文中,作者将他们的注意力集中在一个长期未知的问题上:大脑如何处理信息并将其作为记忆储存,在星形胶质细胞层中找到了一个可能的解决方案。星形胶质细胞是神经胶质细胞家族的一部分。它们通常呈星形,主要职责是处理神经元的突触。例如,一个人的星形胶质细胞可以同时与多达 200 万个突触相互作用😱特别是,星形胶质细胞通过钙离子调节突触神经元传递,导致放电频率的调节。这些调节已被证明与工作记忆有关,揭示了星形胶质细胞记忆处理的关键作用。
在这项工作中,作者进一步发展了以前的生物启发神经网络模型(SNN ),增加了星形胶质细胞介导的反应作为突触权重的变化,以存储输入图像的记忆。SNN 模型是由稀疏连接的伊兹克维奇神经元组成的。这里,通过微分方程描述神经元,该微分方程考虑了神经元跨膜电位,取决于输入信号、来自所有突触前神经元的总突触电流和星形胶质细胞通过钙离子诱导的电位调制。两层神经元与星形胶质细胞层相互连接,由 Ullah 的模型模拟。星形胶质细胞可以与神经元群进行双向交流,一方面提供生物相似性,另一方面提供信息的加载、存储和检索。
该模型被训练以记忆灰度图像(图 1)。这些图像被转换成输入电流,供给神经元层。神经元以不同的速率放电,这取决于输入电流的幅度。这种反应的差异引发了星形胶质细胞的钙反应,形成了每一个输入的特定模式。这种钙浓度分布持续几秒钟,并参与记忆储存过程。
图 1:A)SNN-星形胶质细胞模型。输入 BW 图像馈入神经元网络。每个神经元都有自己的放电频率,组成一个整体反应(神经元层中的蓝色阴影)。放电频率由星形胶质细胞调节。双向连接有助于分类过程,在神经元层解码为输出模式。b)生物学相似性:神经元集合触发星形胶质细胞中的钙浓度水平。结果,谷氨酸被释放,因此突触强度可以被调节。
图 2 显示了伴随星形胶质细胞双向调节的 SNN 的输入-输出响应的实际例子。一方面,输入灰度图像用于刺激神经元活动。神经元反应由星形胶质细胞调节,星形胶质细胞最终能够存储来自钙浓度信号的图像。这个信号持续几秒钟,这允许系统保持原始信息并检索它。
图 2:输入图像信号 A)的例子,该图像被转换为输入电流 B),来自神经元层放电速率 C)的结果和来自钙浓度的星形胶质细胞记忆。
这是一个了不起的结果,一如既往地提醒了数据科学界。事实上,这篇论文是向大脑启发的人工智能迈出的一小步。可以在神经形态计算中找到应用,其中可以通过简单地考虑星形胶质细胞介导的反应来增强神经元和突触计算。此外,星形胶质细胞层提供一次性学习,这是对通常的通用神经网络架构的巨大改进。这种方法可以帮助实现比深度学习本身更好的结果,在训练过程中使用更少的数据!
循环尖峰网络中的行为克隆:一个综合框架
克里斯蒂亚诺·卡彭,保罗·穆拉托雷,皮尔·斯坦尼斯劳·保鲁奇,https://arxiv.org/abs/2109.01039
正如我们在前一篇论文中看到的,学习方法是神经科学中的一个热门话题。特别是,有两种互补的学习方法:基于错误策略的学习和基于目标策略的学习。在前一种方法中,误差信息被注入到神经网络中,并用于改善未来的性能,而在基于目标的方法中,选择并学习目标。在本文中,作者设计了一个新的更通用的框架,它可以被视为基于错误和基于目标的方法的来源,为神经网络学习动力学提供了新的见解。这种普遍观点可以看作是模仿学习和行为克隆的自然进化。特别地,基于文献,该模型假设了基于尖峰定时的神经网络的形式,该神经网络在实验上被认为在大脑中是关键的。
作者提出了一个循环尖峰模型,其中每个神经元可以暴露一个可观察的状态,该状态代表一个神经元在某一时间出现一个尖峰。这个模型必须与环境互动,以解决特定的任务。该模型从模仿学习最优策略中学习,而不是使用强化学习。模仿学习允许代理在给定一组状态的情况下复制一组专家行为。对于学习步骤,模型通过目标而不是从错误中学习。内部权重受反馈矩阵的影响,反馈矩阵的等级用作基于其等级值检查学习的度量。
这里调查了两种情况:按钮和食物任务,其中代理必须按下按钮解锁食物并够到它,以及来自 OpenAI 数据集的 2D 两足步行器,其中代理必须学习走路并尽可能远地旅行。我们将把注意力集中在第一个实验上,其结果如图 3 所示。在这个实验中,针对反馈矩阵的不同秩值来训练代理。所有的训练条件都显示出结果的趋同性。当给出高等级的反馈结构时,奖励是最大的。在第二个实验中,2D 两足步行器,尖峰脉冲时间被调整,而不是反馈矩阵秩,这证明了学习也是特定尖峰脉冲模式的结果。
图 3:按钮和食物任务 A)任务,代理必须点击红色按钮来解锁目标食物。一旦食物被解锁,代理必须找到到达食物的轨迹,不要忘记按钮已经被按下。b)由受过训练的代理为不同目标位置产生的轨迹的例子。箭头(紫色)是专家行为。c)作为目标位置的函数的最终奖励(通过角度测量),重复 10 次。d)作为反馈矩阵秩 d 的函数的平均奖励
以下是结论:
- 反馈矩阵秩修改导致代理的更高的解决方案空间,这可以阐明错误如何在大脑的不同区域传播的实验发现
- 另一方面,典型的运动任务确实需要并受益于精确的定时编码。这对于获得更精细的移动控制以实现更好的性能可能是必要的。在这种情况下,高等级是不相关的,而尖峰调制是相关的。
记忆流形的出现
Tankut Can,Kamesh Krishnamurthy, 论文
这不是一篇容易阅读的论文,因为它的根源是在一个新的机器学习数学领域。我将很快就此发表一些东西,特别是关于 Martin-Siggia-Rose-De Dominic is-Jansen(ms rdj)形式主义,它为神经网络带来了新的见解。这篇论文背后有一个简单的想法。
人脑可以储存记忆,并根据输入的任务在合适的时间提取记忆。这意味着生物系统可以在比神经元反应的内在时间尺度更长的时间内保持记忆。对于计算神经网络来说,这是一个难以解决的问题,即使有了最新的进展,在正确的时间利用记忆仍然是一个巨大的障碍。
从数学的角度来看,记忆/大脑系统不断产生变量,这就产生了一个对象:记忆流形。流形是一种几何结构,存在于多维空间中,其中每个点都可以被视为给定输入问题的固定点(解决方案)。从这里进一步的数学问题出现了:流形是稳定的吗?什么时候不稳定?有分叉点吗?歧管有需要调整的参数吗?
为了在计算上解决这个记忆流形问题,作者为神经网络定义了一个新的数学视角。换句话说,论文的关键问题是:如何在不改变数量或使用特殊对称性或微调参数的情况下,在神经网络中实现内存?最终目标是扩展网络的内存,而不要过多地使用它的参数,在正确的时间使用内存,所以很长一段时间没有看到这些。
作者将记忆流形定义为处于边际稳定点的系统。然后,他们用“冻结稳定”(FS)定义了一个可能的场景。FS 是一个过程,其中神经网络家族可以自组织到一个临界状态,表现出记忆流形而无需进一步调整。因此,递归神经网络(RNN)框架是从其数学根源发展而来的,定义了一个二元变量,该变量可以根据当前系统状态减慢系统的一部分。
图 4: a)香草 RNN (vRNN ),其中每个节点都有随机偏差,动态通常流向定点 b)门控 RNN (gRNN ),其中一半的种群被冻结,另一半在任何给定的时间内自由进化。冻结的那一半给进化的那一半提供了随机偏差。gRNN 的相图(黑线),稳定 vRNN 动态所需的临界方差(红色虚线)。
早期的结果非常令人鼓舞。FS 允许神经网络自组织到展示记忆流形和长时间尺度的状态。神经元的内部动力学是冻结的,而它的一部分仍在进化,并偏向另一半。
我希望你喜欢 2021 年 9 月神经科学arxivg.org
论文上的这篇综述。请随时给我发电子邮件询问问题或评论,地址:stefanobosisio1@gmail.com
通过线性模型保持竞争力
可交代的 AI
有了正确的特征,线性模型可以变成野兽
作为一名数据科学家,你有许多不同类型的闪亮的机器学习模型可供选择。有神经网络模型、梯度增强模型、bagging 模型,仅举几个主要类别。
在这些家伙的阴影下,也存在着像线性和逻辑回归这样的模型。线性模型通常在最好的情况下仅仅被用作基线,在最坏的情况下被取笑。然而,我认为这是不合理的。简而言之,我的请求如下:
作者在 imgflip.com 创作的。
让我通过考虑回归任务来解释我的意思,但是记住这同样适用于分类任务。
首先,我将向您展示带有坏特征的线性回归会导致什么,这样您就不会上当。然后,我将向您展示线性回归是非常通用的,如果给予良好的特性,它可以用于模拟复杂的模型。最后,我们将使用线性回归进行简单有效的时间序列预测。
添加多项式特征(不好!)
我们可能已经全部完成了。创建新要素的一种最常见、最简单但也最可怕的方法是添加基础要素的多项式幂。除了只使用特征 x 之外,您还可以添加 x ,x ,… 作为特征,然后进行多元线性回归。让我们在 x 中创建一个非线性的小型一维数据集来说明这一点,这样每个人都在同一页上。
import numpy as np
np.random.seed(123)
x = np.random.uniform(0, 10, 10)
y = 3*np.sin(x) + x + np.random.randn(10)
以 x 为唯一特征的简单线性回归产生一条不太符合数据的直线。
图片由作者提供。
现在让我们添加一些四次幂的多项式项。
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
lr = make_pipeline(
PolynomialFeatures(degree=4),
LinearRegression()
)
lr.fit(x.reshape(-1, 1), y)
我们得到了这种契合:
图片由作者提供。
好多了,对吧?我们可以通过设置degree=9
变得更疯狂,得到如下结果:
很难看出,但这是一个完美的拟合,它通过所有的点。不幸的是,曲线围绕摆动很大。训练集中的所有标签 y 都在 0 到 12 之间,但是该模型以某种方式预测大约x1 的值大于 10.000。为什么?因为多项式特性不好。可悲的是,这通常是线性回归旅程的终点。
“线性模型是给孩子们看的,让我们继续看好的东西。涉及树或者前馈连接的模型,你懂的!”—也许是你?
然而,让我告诉你为什么这样想是错误的。可以创建行为完全类似于神经网络的线性模型或基于决策树的模型。你只需要好的特性,而不是多项式特性。
模拟高级模型
神经网络
快速提醒一下,这是一个简单的前馈神经网络的例子,它有一个大小为 3 的隐藏层,将一个数字 x 作为输入,输出一个值 y (没有偏差):
图片由作者提供。
可以看到 x 进入神经网络。然后使用三种不同的变换对其进行变换 T ₁、 T ₂和 T ₃,留给我们三个新值x₁=t₁(x)、x₂=t₂(x和 x ₃ = 【T36 这些变换通常涉及乘法、求和以及某种非线性激活函数,如 ReLU 或 Sigmoid 。
然后,这三个导出值被用作神经网络最后一步的输入:将它们乘以一些值 α ,然后将所有值相加。因此,最终的输出是y=α₁x₁+α₂x₂+α₃x₃=α₁t₁(x+α【t67
观察最后一个等式是如何在三个新特性 x ₁、 x ₂和 x ₃中只是一个线性模型!
这就是神经网络的神奇之处:特征是自动组装的。我们不必像处理多项式特征那样手工制作它们,而是由网络来学习它们。但是一旦我们得到了这些新的特征,最后一步就是运行一个简单的线性回归。
让我们看一个使用小玩具数据集的具体例子。
from sklearn.neural_network import MLPRegressor
mlpr = MLPRegressor(
hidden_layer_sizes=(3,),
random_state=142,
max_iter=10000
)
mlpr.fit(x.reshape(-1, 1), y)
这会产生以下输出:
图片由作者提供。
这一切都很好,但现在我声称,当使用正确的特性时,我们可以通过简单的线性回归来重新创建这个输出。而我们可以从训练好的神经网络中得到这些特征。下面的代码模拟了神经网络在中间部分所做的事情:它将我们的 10 个一维输入样本转换为 10 个三维智能输入样本。
transformation_coefs = mlpr.coefs_[0]
transformation_biases = mlpr.intercepts_[0]
x_linear_transformation = x.reshape(-1, 1) @ transformation_coefs + transformation_biases # linear transformation
x_clever = np.maximum(x_linear_transformation, 0) # ReLU
从图形上看,这种情况会发生:
图片由作者提供。
我们现在可以用x_clever
代替x
来训练一个线性回归模型。结果如下:
图片由作者提供。
请注意,线性回归拟合略有不同。事实证明,它对训练数据的跟踪甚至比神经网络的输出更好!这是因为神经网络必须一次优化许多参数——它必须专注于特征创建和最终的实际线性回归。特别是第一步要对麻烦负责,因为它使拟合过程优化非凸函数,这是困难的。另一方面,找到线性回归的最佳参数很容易。
因此,在这种情况下,我们甚至可以提高一点点性能,至少在训练集上。我们仍然要小心过度拟合,但这不是我们在这里的主题。关键是:有了正确的特征,我们能够建立一个像神经网络一样好的模型。
我已经听你说过了:
“好吧,那么我们先训练一个神经网络。然后,我们从中提取特征来训练一个线性模型,它和原始的神经网络一样好。为什么不直接用神经网络?”
你是对的。我们投入了更多的工作来创建一个与原始神经网络一样好的线性模型。但是我从来没有说过找到好的特性是容易的。这实际上是建模最难的部分。
艺术是想出好的特征,而不必窥视一些神经网络正在做什么。这些特征也可能看起来与神经网络创建的完全不同。我们不需要使用 ReLU 函数或者类似的函数。例如,在我们的例子中,sin( x )将成为一个很好的特性,因为我们甚至在数据生成过程中使用了它。
总之,我们已经看到了如何使用线性回归来模拟神经网络的输出。现在让我们转向树木,因为我们可以在那里做同样的事情!
决策树
我不会介绍决策树是如何工作的,因为有很多很好的资源可以让你重温这方面的知识。你只需要知道决策树输出分段常数函数。让我们训练一个深度为 2 的决策树。
from sklearn.tree import DecisionTreeRegressor
dt = DecisionTreeRegressor(max_depth=2)
dt.fit(x.reshape(-1, 1), y)
结果是具有(最多)个 2^max_depth 不同值的分段常数函数。
图片由作者提供。
为了提取允许我们模拟这个函数的特征,函数值变化的点——分裂点*—*—是很重要的。我们可以这样得到它们:
from sklearn.tree import plot_tree
plot_tree(dt)
图片由作者提供。
此外,让我们在-∞和∞处再增加两点。总的来说,我们在(-∞,4.08,6.18,6.91,∞)处有分裂点,我们创建的特征将如下所示:
图片由作者提供。
其中( a ₁=-∞ ,a ₂ ,a ₃,…,∞)为拆分点,升序排列。
注: 这基本上意味着我们 bin 了样本,见下图。
对于熊猫,你可以这样做:
import pandas as pd
split_points = [-np.inf, 4.076, 6.181, 6.906, np.inf]
x_clever = pd.get_dummies(
pd.cut(
x,
bins=split_points),
prefix='x'
)
使用这些新特性进行线性回归,我们可以得到:
图片由作者提供。
在这种情况下,您无法区分原始模型和线性模型,它们完全相同。这是因为决策树不像神经网络那样有数字上的困难。于是,我们学会了如何用线性回归模拟单个决策树!
再次强调:想出这些特性并不容易,但是一旦你拥有了它们,一切都变得简单了。
我们甚至可以从这里继续:随机森林、AdaBoost、梯度增强、额外的树……都只是具有特殊权重的决策树的总和。分段常数函数的和也是分段常数函数,只是可能有更多的分裂点。这意味着,只要有合适的特性,我们也可以用线性模型模拟这些更高级的树模型!
时间数列预测法
到目前为止,我们已经处理了很多抽象的东西。理论上,线性模型和更复杂的模型一样好,只要有正确的特征。但是,如果我们不想使用预先训练好的神经网络或基于树的模型,这些正确的特征会是什么样子呢?
我认为一个简单但非常有用的领域是时间序列预测,这是一项在你的日常数据科学工作中经常出现的练习。
数据
现在让我们用一些真实的数据。首先,通过!pip install sktime
安装 sktime,这是一个很棒的时间序列预测库。我们可以得到如下的航空乘客数据集:
from sktime.datasets import load_airline
y = load_airline()
数据看起来像这样:
图片由作者提供。
有两件事应该引起你的注意:
- 有上升趋势,而且
- 每年都有季节性。
如果人们想做一个预测,通常他们会选择统计方法,比如 ARIMA T2、萨里玛、萨里玛……但是我不太喜欢这些方法,因为它们太复杂了。让我们做一些简单的事情,用可解释的特性和一个简单的线性模型。
简单的线性模型
为了捕捉上升趋势,我们可以创建一个向上计数的特征。最早的观察值—在我们的例子中是 1949 年 1 月—得到值 0,1949 年 2 月得到值 1,1949 年 3 月得到值 3,…在代码中:
import numpy as np
from sklearn.linear_model import LinearRegression
x = np.arange(len(y)).reshape(-1, 1)
lr = LinearRegression().fit(x, y)
y_forecast = pd.Series(lr.predict(x), index=y.index)
结果看起来像这样:
图片由作者提供。
它看起来并不可怕,尤其是考虑到我们到目前为止只添加了一个单一的功能。要模拟每年的季节性,最简单的方法是为每个月创建一个热编码变量,一个例子是特征“month_5 ”,它在第 5 个月(5 月)的值为 1,在其他月份的值为 0。你可以这样做:
X = pd.get_dummies(y.index.month, prefix='month')
X['trend'] = range(len(y))
X.index = y.index
图片由作者提供。
这些都是非常便宜的特征,但是看看基于它们训练的线性模型给我们带来了什么:
图片由作者提供。
这相当不错。模型捕捉到了趋势和季节性,很容易将这条曲线延续到未来。然而,只有最后一个挑战:季节性的强度随着时间的推移而增加。我们的模型尽了最大努力,但在开始时,我们的模型在附近摆动得更强,最后比原始时间序列更弱。这是我们无法用更多的功能来解决的。但是处理这个问题的一个简单方法是
- 用对数变换原始标签
y
, - 对这个新数据集使用线性回归,然后
- 使用求幂运算将预测值转换回来。
在 scikit 中有一个简洁的方法——学习实现这三个步骤,而不需要太多的开销并跟踪转换:
from sklearn.compose import TransformedTargetRegressor
from sklearn.linear_model import LinearRegression
lr = TransformedTargetRegressor(
regressor=LinearRegression(),
func=np.log, # use logarithm on the no. of passengers
inverse_func=np.exp # transform the data back with exp
)
lr.fit(X, y)
然而,结果是惊人的,在训练集上 r 为 0.98,。
图片由作者提供。
我希望你能享受这有多棒!该模型仍然是一个简单的线性模型,即使进行了变换。此外,构建特征是琐碎的,然而结果是极其精确的。像这样的模型是黄金。
完整的模型,简化的符号。图片由作者提供。
你甚至可以创建一个更长的时间范围,并获得预测。
future = pd.date_range(
start='1949-01-01',
end='2021-12-31',
freq='M'
)
X_future = pd.get_dummies(future.month, prefix='month')
X_future['trend'] = range(len(future))
X_future.index = future
如果我们把这个输入模型,我们会得到 1949 年 1 月到 2021 年 12 月之间的预测。
图片由作者提供。
根据该模型,我们今年的航班乘客人数将接近 100 万。然而,这个模型被输入了非常旧的训练数据,而且它也不了解新冠肺炎,所以对这个预测有很大的怀疑。根据我找到的数字,在 Covid 之前,2019 年每月约有 40 万名航空乘客。我们的模型说的是 60 万左右的东西,至少和真相差不多一个量级。但这说明过去的增长比现在高,是有道理的。这就是为什么该模型高估了真实的航空乘客数量。
结论
我们已经看到,就性能而言,说线性模型不好而复杂模型好通常是错误的。通过正确的功能,线性模型可以像神经网络或梯度推进一样执行。不幸的是,找到这样的优点很难,但这也是这份工作有趣的地方。如果对原始数据进行简单的拟合/预测就足够了,许多数据科学家可能明天就会失业。
虽然有时候想出好的特性很容易。当处理时间序列数据时,一个很好的起点是添加月份、星期几、星期几。或者像圣诞节、复活节、黑色星期五这样的特殊日子。包含一个趋势特征也是很好的。这可以是一个从零到观测值减一的数,正如我们在飞机乘客的例子中所看到的。但这只能让我们模拟一个线性趋势。我们还可以添加一个二次或根趋势,我们所要做的就是应用一些简单的函数,例如,0,1,4,9,…,,(#observations-1)。找到正确的指数,让它成为 1、2、0.5 或其他值是超参数调整的典型用例,您不必手动尝试所有东西。
因此,精心制作一些有意义的特性,尝试一下线性模型。这样做的好处是,该模型易于解释,快速且健壮,并且您可以确保线性回归适用于每种编程语言。这是而不是像 CatBoost 等高级模型的情况。
我希望你今天学到了新的、有趣的、有用的东西。感谢阅读!
作为最后一点,如果你
- 想支持我多写点机器学习和
- 无论如何都要计划获得中等订阅量,
为什么不做 通过这个环节 ?这将对我帮助很大!😊
透明地说,给你的价格不变,但大约一半的订阅费直接归我。
非常感谢,如果你考虑支持我的话!
如有问题,请在 LinkedIn 上写我!
正确使用熊猫类别是很棘手的,原因如下…
了解常见的陷阱和意想不到的行为,如何避免让猫抓你
在 pandas 中,分类数据类型经常被吹捧为减少数据帧内存使用的简单方法,它们确实是一个有用的工具。然而,如果你想象你可以在代码的开头加上一个.astype("category")
,其他的都一样(但是更有效),你可能会失望。
本文主要关注在 pandas 中使用分类数据类型时可能会遇到的一些现实问题;要么调整您现有的思维模式,使用类别编写新代码,要么尝试使用类别列将现有管道迁移到流中。
本文中描述的行为是截止到*pandas==1.2.3*
(2021 年 3 月发布)的当前行为,但是如果您在更晚的日期阅读本文,请不要担心,所描述的行为不太可能在未来的版本中有重大改变——但是如果有,请留下评论!
为什么在 pandas 中使用分类数据类型?
如果分类数据是一种痛苦,那么为什么不干脆完全避免它呢?嗯,使用类别可以带来一些显著的好处:
- 内存使用 —对于有许多重复值的字符串列,类别可以大大减少在内存中存储数据所需的内存量
- 运行时性能 —有一些优化可以提高某些操作的执行速度
- 库集成 —在某些情况下,库对分类列有特殊的功能,例如
lightgbm
在构建模型时以不同的方式处理分类列
快乐之路
让我们做一个强制性的“快乐之路”的例子。这是在一个简单的世界里,每个人都互相微笑的样子:
df_size = 100_000
df1 = pd.DataFrame(
{
"float_1": np.random.rand(df_size),
"species": np.random.choice(["cat", "dog", "ape", "gorilla"], size=df_size),
}
)
df1_cat = df1.astype({"species": "category"})
这里我们创建了两个数据帧,df1
包含作为对象列的species
和df1_cat
,后者是相同数据帧的副本,但是使用species
作为分类数据类型。
>> df1.memory_usage(deep=True)Index 128
float_1 800000
species 6100448
dtype: int64
我们可以在这里看到,根据我们的内存使用情况,保存一个包含字符串的列是多么昂贵——这里的字符串列占用大约 6MB,如果这些字符串更长,它会占用更多;与之相比,float 列占用了 0.8MB。我们可以用一个字符串列的价格购买近 8 个float64
列……很贵。
>> df1_cat.memory_usage(deep=True)Index 128
float_1 800000
species 100416
dtype: int64
在转换到一个类别后,查看内存使用情况,我们看到了一个相当大的改进,内存使用量减少了 60 倍,非常好。现在,我们可以用一个float64
列的价格购买 8 个这样的字符串列,哦,形势发生了多么大的变化。
这很酷,但是,只有我们能保持这种状态才是真正的酷…
分类列是脆弱的东西
听起来很奇怪吗?嗯……处理类别很像玩那些摇摇晃晃的洋娃娃,当你把它们推过来时,它们又会弹回来;如果您不密切关注使用分类列的每个操作,它们将很容易返回到object
中。
在最好的情况下,这是令人讨厌的,在最坏的情况下,它会降低您的性能(因为转换类型很昂贵),和/或耗尽您的内存(因为您只能将这些数据作为一个类别存储到您的内存中)。
对分类列进行操作
这是我对猫手术的描述。我知道通常情况下,人类会给猫做手术,但是现实比小说更奇怪:我们有熊猫给猫做手术!
很可能在某个时候,你会想对你的分类列做些什么,其中之一可能是一个转换。这是第一个我们必须表现出勤奋的地方…
由于分类列通常是基于文本的列,让我们来看一个使用字符串操作的例子,我们可以像通常对基于文本的object
列那样对分类列进行操作;通过使用.str
访问器。
非分类字符串系列:
>> %timeit df1["species"].str.upper()25.6 ms ± 2.07 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
关于分类字符串系列:
>> %timeit df1_cat["species"].str.upper()1.85 ms ± 41.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
分类版本在性能上是明显的赢家,在这种情况下大约快了 14 倍(这是因为内部优化意味着.str.upper()
只对唯一的类别值调用一次,然后从结果中构造一个序列,而不是对序列中的每个值调用一次)。然而,这是我们遇到的第一个主要问题…
>> df1_cat["species"].str.upper().memory_usage(deep=True)6100576
我们已经丢失了我们的分类类型,结果是一个object
类型的列,数据压缩也消失了;结果现在又是 6MB 大小。在此之后,我们可以重铸回一个类别,但这需要在类型之间来回转换,这会使我们的代码更加混乱,并且不会降低我们的内存使用峰值。
有效的替代方案
通常,一种有效的替代方法是重写操作分类列的代码,直接对类别本身进行操作,而不是对它们的值序列进行操作。这需要在思维模式(和实现)上做一点改变,你可以认为它只是对列中的每个唯一的值做一次操作,而不是对列中的每个实例。如果在 100,000 行的类别中只有 2 个唯一值的列,那么只需执行 2 次操作,而不是 100,000 次。
例如,在上述情况下,我们可以执行以下操作:
%timeit df1_cat["species"].cat.rename_categories(str.upper)239 µs ± 13.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
这比前面的任何一个选项都快 10 倍,主要的好处是我们从不将分类系列转换成昂贵的中间object
列状态,所以我们保持了很好的内存效率。
这是一个玩具示例,但原则适用于更复杂的示例,如果没有特定的.cat
访问器方法来帮助您的特定情况,请考虑对包含唯一分类值的df1_cat[“species”].dtype.categories
进行操作,而不是对整个系列进行操作。
与分类列合并
描绘一些合并的猫确实是一个巨大的尝试。
在除了最简单的用例之外的所有用例中,我们可能不只有一个数据帧,而是有多个数据帧,我们可能希望在某个时候将它们粘在一起。例如,我们将收集一个小型“参考”数据集,其中包含第一个数据集的物种栖息地:
df2 = pd.DataFrame(
{
"species": ["cat", "dog", "ape", "gorilla", "snake"],
"habitat": ["house", "house", "jungle", "jungle", "jungle"],
}
)
df2_cat = df2.astype({"species": "category", "habitat": "category"})
和以前一样,我们已经创建了这个数据集的一个分类版本,以及一个带有object
字符串的版本。这里需要注意的一点是,我们有一个额外的物种(snake
),这是我们将与之合并的数据帧df1
中没有的,这在以后会很重要(但不要担心不会有测试)。
我不会展示将两个object
列合并在一起的例子,因为你们都知道会发生什么,object
+ object
= object
,没有魔法,这只是一个合并。
在分类列上合并对象列
在这个小测试中,我们将选取一个分类数据帧,并将其与另一个数据帧上的对象类型列合并。
>> df1.merge(df2_cat, on="species").dtypesfloat_1 float64
species object
habitat category
dtype: object
所以这里我们有左边的物种object
和右边的物种category
。我们可以看到,当我们进行合并时,我们得到了结果数据帧中合并列的category
+ object
= object
。如此等等等等,当我们回到object
s 时,这又一次在记忆中击中了我们。这并不令人惊讶,但同样,这是在处理类别时需要注意的事情。
合并两个分类列
希望我已经让你认为我正在走向category
+ category
= category
。让我们来看看:
>> df1_cat.merge(df2_cat, on="species").dtypesfloat_1 float64
species object
habitat category
dtype: object
报警,我被骗了… category
+ category
= object
。
那么尾巴上的刺是什么?在合并中,为了保留分类类型,两个分类类型必须完全相同。与 pandas 中的其他数据类型不同(例如,所有的float64
列都具有相同的数据类型),当我们谈论分类数据类型时,数据类型实际上是由特定类别中存在的一组值来描述的,因此您可以想象包含["cat", "dog", "mouse"]
的类别与包含[“cheese”, “milk”, “eggs”]
的类别是不同的类型。虽然在我们的例子中,它们看起来非常相似(一个是另一个的子集),但在df2
中,我们有一个物种在df1
中不存在(狡猾的snake
)。
我们可以这样看待合并列的行为:
category1
+ category2
= object
category1
+ category1
= category1
因此,采用前面的例子,我们可以得到我们想要的和预期的结果:
>> df1_cat.astype({"species": df2_cat["species"].dtype}).merge(
df2_cat, on="species"
).dtypes float_1 float64
species category
habitat category
dtype: object
从上面可以看出,设置分类类型进行匹配,然后进行合并,得到了我们想要的结果……最后。
使用分类列分组
我不是一个爱猫的人,我不清楚如何最好地对猫进行分类(我想它们中的很多会下地狱)
在修改代码以处理分类数据类型时,用类别分组曾经让我自己伤透了脑筋。一次导致行为意外改变,给出一个充满空值的数据帧,另一次导致操作无限期挂起(尽管以前使用object
数据类型只需要几秒钟)。
当您对分类数据类型进行分组时,默认情况下,您会对该数据类型中的每个值进行分组,即使它不在数据本身中。
那是什么意思?最好用一个例子来说明。
habitat_df = (
df1_cat.astype({"species": df2_cat["species"].dtype})
.merge(df2_cat, on="species")
)house_animals_df = habitat_df.loc[habitat_df["habitat"] == "house"]
所以这里的habitat_df
是上一节的合并示例(其中species
和habitat
最终都是分类的),而house_animals_df
只包含住在房子里的动物,在我们的例子中是cat
和dog
。让我们试着找出这些species
的平均值float_1
。
>> house_animals_df.groupby("species")["float_1"].mean()species
ape NaN
cat 0.501507
dog 0.501023
gorilla NaN
snake NaN
Name: float_1, dtype: float64
有些事情看起来有点不对劲,我们现在在 groupby 中得到一堆空值。默认情况下,当对分类列进行分组时,pandas 会为类别中的每个值返回一个结果,即使这些值不在数据中。这可能很烦人(因为这是行为上的意外变化),如果数据类型包含许多相关数据帧中不存在的组,尤其是在多个不同的分类列上分组时,这可能会影响性能。
为了得到我们想要的结果,我们可以将observed=True
传递给 groupby 调用,这样可以确保我们只得到数据中值的分组。
>> house_animals_df.groupby("species", observed=True)["float_1"].mean()species
cat 0.501507
dog 0.501023
Name: float_1, dtype: float64
是的,但这又是一个让我们保持警觉的陷阱。
分类列索引
这是一个猫专栏,你明白吗?
这个例子稍微有点小众,但它为你有时会遇到的意外问题增加了一点色彩,如果你在使用范畴时没有保持头脑的话。有些情况下,您可能会将行值移动到列中,例如,groupby-unstack
组合有点像职业玩家的移动。
>> species_df = habitat_df.groupby(["habitat", "species"], observed=True)["float_1"].mean().unstack()
>> species_df species cat ape dog gorilla
habitat
house 0.501507 NaN 0.501023 NaN
jungle NaN 0.501284 NaN 0.501108
现在我们有了一个数据框架,列中有物种,到目前为止一切正常,让我们添加另一列,看看会发生什么。
>> species_df["new_col"] = 1 TypeError: 'fill_value=new_col' is not present in this Categorical's categories
通常这段代码完全没问题,我们只是试图添加一个名为new_col
的新列,它的值总是 1。只是看了一眼数据帧,看起来没有任何错误,错误似乎有点令人困惑,它在谈论哪个Categorical
,我们只是试图添加一个新列?
所发生的是.unstack()
(对于外行来说,它将索引翻转到列中,就像一个支点)将分类索引移动到列索引中。不可能将条目添加到不属于分类数据类型的分类索引中,因此会出现错误。虽然这并不是立即显而易见的,但如果你最终来到这里,挠头也是情有可原的。
可能不存在拥有分类列索引的强有力的例子,但是如果意外地拥有了一个分类列索引和/或您开始看到类似这样的奇怪错误,那么检查您正在处理的所有事物的数据类型并确保没有任何奇怪和分类的事情发生可能是值得的。
结论
Pandas categorical dtypes 很酷,并且有一些好的性能优势。当采用分类数据类型时,了解数据类型在不同的常见情况下如何表现是很重要的,尤其是对来说,确保分类在整个程序流程中保持分类,而不是返回到object
。
以下是一些需要注意的事项的高度概括:
- **对分类列进行操作时,**选择对数据类型中的类别进行操作的选项,而不是对包含该数据类型的系列中的值进行操作的选项。这应该允许您保留分类的性质,同时提高性能。
- **在分类列上进行合并时,**请注意,为了保持分类性质,每个数据帧的合并列中的分类类型必须完全匹配。
- **当对分类列进行分组时,**默认情况下,您将获得数据类型中每个值的结果,即使它不在数据中,您也可以使用
.groupby
中的observed=True
来更改它。 - **当你期望工作的事情出乎意料地停止工作时,**考虑是否有一种与范畴的奇怪互动在起作用
祝你好运,并祝你快乐!
用 NLTK 对文本进行词干分析
词干分析是文本规范化中使用最广泛的技术之一。在这篇文章中,我们将探索 nltk 的三个最著名的词干分析器
马库斯·斯皮斯克的照片
T 处理文本数据的能力是一项巨大的技术成就,使公司和组织能够处理非结构化信息,并根据过去极难收集和存储的信息支持决策。
自然,由于计算机不像人类那样真正理解字符和单词,这带来了许多新的挑战,这些挑战可以通过使用专门处理文本数据的特定技术来解决,如词干化或词汇化。
在这篇文章中,我们将探讨词干的概念,以及词干如何帮助你挖掘文本管道。
词干定义
词干提取,也称为后缀剥离,是一种用于减少文本维数的技术。词干化也是一种文本标准化类型,使您能够将一些单词标准化为特定的表达式,也称为词干。
让我们从一个句子的例子开始:
这绝对是一个争议,因为律师称该案件“极具争议”
如果我们想将这个文本表示为一个数组(查看本系列的另一篇文章 )单词争议和争议**会被认为是不同的标记,并在您可能构建的任何数组中有不同的位置。
词干有助于我们标准化有相同后缀的单词,这些单词通常是语法相似单词的派生词。
但是,像往常一样,在几个文本挖掘管道中,有许多可能导致信息丢失的选择。请记住,考虑到我们今天能够在 NLP 管道中应用的计算能力和更高级的模型(例如深度神经网络),在 NLP 领域中词干提取是否真的是一个好主意,这是一个正在进行的讨论。
词干提取对于处理大量维度的算法来说可能是个好主意。回想一下,词干分析是一种标准化技术,但是像大多数标准化问题(例如主成分分析)一样,它会导致你丢失文本中的一些原始信息。对于 NLP 管道来说,这是一个好的还是坏的应用程序,这实际上取决于您使用的模型、您保存数据所需的空间量(尽管现在空间应该不是问题)以及您想要使用的算法的特征。
*鉴于此,让我们探索一下 *NLTK(自然语言工具包)库中最常见的词干分析器。
波特的斯特梅尔
波特的斯特梅尔实际上是计算机科学中最古老的词干分析器应用程序之一。它第一次被提及是在 1980 年 Martin Porter 的论文 中的一种后缀剥离 算法,它是**【nltk】**中广泛使用的词干分析器之一。
***波特的斯特梅尔应用一套五个连续的规则(也称为阶段)来确定句子中常见的后缀。*举例来说,第一阶段首先从句子中移除复数和过去分词,例如单词 cats 被转换成 cat :
猫->猫
从第二阶段到第五阶段,波特的算法根据前面辅音和元音的不同组合来阻止常见的词尾。
每个阶段的详细描述见此处。
porter stemmer 最重要的概念之一是以下公式中的 m 的概念:
波特的斯特梅尔算法辅音和元音公式
每个 C 都被认为是一个包含一个或多个辅音的字符串。每个 V 都被认为是一个包含一个或多个元音的字符串。元音字母被认为是字母 a,e,I,o,u 和 y 有一定的限制。**
m 是波特词干分析器中最重要的概念之一,因为它定义了对特定单词应用特定规则的阈值。让我们来看一些单词的例子:
- 树->这个词可以用表示法 CV 来表示,因为 TR 被认为是 C 表示法而 ee 被认为是 V 表示法。在这种情况下, m 是零,因为这个单词只适合格式[C][V]
- 创作->这个词可以用 CVCVC 来表示。为了符合波特公式,可以用[C][VC]来表示,因此m等于 2。
- 燕麦->这个词可以用符合波特公式的 VC 来表示为[VC]。在这种情况下 m 等于 1。
请记住这个“T2”的概念,因为它对下面的一些解释很重要。
我们在 nltk 图书馆有波特的《斯特梅尔》:
*from nltk.stem import PorterStemmer*
要使用它,必须在导入后声明 PorterStemmer 的实例:
*porter = PorterStemmer()*
定义了 PorterStemmer 的实例后,我们可以根据算法中定义的规则对单词进行词干处理:
*porter.stem('cats')*
这个命令产生单词:‘cat’—单词 cats 的词干版本。我们来看看更常见的例子:
*porter.stem('amazing') returns ‘amaz’*
*出现这个词干是因为 ing 在英语单词中是一个如此常见的词尾,以至于单词 amazing 被词干化为单词 *amaz。这个 amaz 词干也是由下面这些词产生的,惊叹、拍案叫绝、惊叹:
*porter.stem('amazement') returns ‘amaz’
porter.stem('amaze') returns ‘amaz’
porter.stem('amazed') returns ‘amaz’*
惊异、惊异、惊异和惊异这四个单词在经过词干处理后,在我们的文本中被认为是同一个单词——这就是为什么我们称之为文本规范化!**
作为一个反例,单词 amazon 并不是源于 amaz :
*porter.stem('amazon') returns ‘amazon‘*
为什么亚马逊中上的没有被移除?这是因为某些词尾,比如上的**,在波特的算法中是不被考虑的——只有当它们前面有 i 的时候,比如民族、预感、等等。让我们测试这两个例子的词干:**
*porter.stem('nation') returns ‘nation‘
porter.stem('premonition') returns 'premonit'*
现在一个新的问题出现了——为什么预感被阻止了,而国家却没有?
某些词尾只考虑某个类似字长的阈值(我们的 m !).如果你查看波特规则,你会看到后缀 ION 或 TION 仅在基于 m 的特定条件下应用于第二和第四阶段。
让我们一步一步地了解每个阶段,真正理解波特的斯特梅尔背后的规则。当词干分析器被顺序应用时,可以应用不止一个规则,例如,单词 条件 (m 等于 4) 在斯特梅尔阶段中遵循以下流程:
- 阶段 1:它不匹配该步骤认为的任何模式,例如以 IES 或 SSES 结尾,以及阶段 1b 和 1c 中存在的其他规则。
- 阶段 2:当 m 大于 0 并且单词以国家结尾时,词干分析器应用后缀 al 的裁剪,并且我们的单词成为 条件。
- 阶段 3:我们的单词条件*(注意,现在我们将我们的单词视为条件,而不是原始的条件,因为我们已经在阶段 2 中应用了一些东西)。*
- 阶段 4:这个单词以第个第个第个第个第>个第 1,所以后缀第个第个第个第个第个第个第个第个第个第个第个第个第个第个】个第个】个第个第【20】个第【18】个第【19】个】个第【18】个第【19】个】个第【**
- 阶段 5:我们的单词 condit 与阶段 5 中可以剥离的任何模式都不匹配,因此我们的最终词干是 condit 。
正如您在上面的过程中看到的,在词干提取过程的各个阶段,我们的单词可能会被词干提取多次。
如果您需要检查每个阶段应用的规则列表,请返回此链接。
波特的斯特梅尔是自然语言处理中最常用的词干技术之一,但自从它首次实现和开发以来已经过去了近 30 年,马丁·波特开发了一个名为 Porter2 的更新版本,由于它的 nltk 实现,它也被称为雪球斯特梅尔。
雪球斯特梅尔
Snowball stemmer(正式名称为 Porter2)是波特的斯特梅尔的更新版本,引入了新规则,修改了波特的斯特梅尔中已经存在的一些现有规则。
雪球/搬运工 2 的详细规则在这里找到。
其逻辑和过程与波特的斯特梅尔完全相同,单词在词干分析器的五个阶段中被依次词干化。
Snowball 和 Porter 之间的另一个相关区别是,Snowball 还详细说明了其他语言的规则——例如,您可以在这里访问葡萄牙语的规则。
你可以很容易地在 nltk 中访问 Snowball,就像我们访问波特的斯特梅尔一样——这里我们也同时定义了实例,但是我们必须将语言定义为一个参数:
*from nltk.stem import SnowballStemmer
snowball = SnowballStemmer(language='english')*
除了广泛回顾雪球的规则,让我们用一些例子来检查波特和雪球之间的一些重要区别:
*porter.stem('fairly') -> returns fairli
snowball.stem('fairly') -> returns fair*
在下面的例子中,斯诺鲍在规范副词方面做得更好,让它产生词干 fair,,而波特产生词干 fairli。这样做使得单词的词干相当与形容词尚可,相同,从规范化的角度来看似乎是有意义的。
这个规则也适用于其他副词:
*porter.stem('loudly') -> returns loudli
snowball.stem('loudly') -> returns loud*
Snowball 的另一个改进是它的规则防止了一些越界(从单词中去掉太多后缀)。让我们看看一般的和慷慨的这两个词的例子——从波特的第一个开始:**
*porter.stem('generically') -> returns gener
porter.stem('generous') -> returns gener*
根据波特的斯特梅尔,这些表达完全不同意思的词将被归结为同一个表达 gener。
对于 Snowball,这种情况不会发生,因为两个单词的词干不同:
*snowball.stem('generically') -> returns generical
snowball.stem('generous') -> returns generous*
总之, SnowballStemmer 被广泛认为是波特的《斯特梅尔》的改进版本。
nltk 的实现基于 Porter2,是对马丁·波特开发的原始算法的改进。
兰卡斯特斯特梅尔
兰开斯特·斯特梅尔是兰开斯特大学的克里斯·佩斯在论文 中提出的另一个斯特梅尔 中开发的词干分析器。
它的规则比波特和雪球更具侵略性,它是最具侵略性的词干分析器之一,因为它倾向于超越许多单词。
作为一般的经验法则,认为兰开斯特的斯特梅尔的规则试图减少单词到尽可能短的词干。你可以在这里查看兰卡斯特的一些规则。
下面是 nltk 的 实现兰卡斯特的斯特梅尔:
*from nltk.stem import LancasterStemmer
lanc = LancasterStemmer()*
让我们来看一些例子,看看兰开斯特的斯特梅尔是如何词干化的,并将结果与斯诺鲍·斯特梅尔的方法进行比较——从单词salt开始:
*snowball.stem('salty') returns 'salti'
lanc.stem('salty') returns 'sal'*
现在对比一下销售这个词:
*snowball.stem('sales') returns 'sale'
lanc.stem('sales') returns 'sal'*
正如你所看到的,Lancaster 把单词 salty 和 sales 放在同一个词干中,这对于两个单词的意思来说没有多大意义。发生这种情况是因为 Lancaster 倾向于过度词干,这是我们说 Lancaster 词干是最积极的词干分析器之一的主要原因。
评估词干分析器的影响
既然我们已经理解了词干是如何通过裁剪后缀来规范化文本的,那么我们如何理解这种规范化在我们的语料库中的影响呢?
由于词干化是一种导致信息丢失的标准化技术,最直接的方法之一是了解词干化前后文本长度之间的比率。这将给出一个近似值,即词干化后保留的信息的百分比。
对于这个例子,让我们使用维基百科中欧盟定义文章的第一段和第二段来评估我们的词干分析器:
*eu_definition = 'The European Union (EU) is a political and economic union of 27 member states that are located primarily in Europe. Its members have a combined area of 4,233,255.3 km2 (1,634,469.0 sq mi) and an estimated total population of about 447 million. The EU has developed an internal single market through a standardised system of laws that apply in all member states in those matters, and only those matters, where members have agreed to act as one. EU policies aim to ensure the free movement of people, goods, services and capital within the internal market; enact legislation in justice and home affairs; and maintain common policies on trade, agriculture, fisheries and regional development. Passport controls have been abolished for travel within the Schengen Area. A monetary union was established in 1999, coming into full force in 2002, and is composed of 19 EU member states which use the euro currency. The EU has often been described as a *sui generis* political entity (without precedent or comparison).The EU and European citizenship were established when the Maastricht Treaty came into force in 1993\. The EU traces its origins to the European Coal and Steel Community (ECSC) and the European Economic Community (EEC), established, respectively, by the 1951 Treaty of Paris and 1957 Treaty of Rome. The original members of what came to be known as the European Communities were the Inner Six: Belgium, France, Italy, Luxembourg, the Netherlands, and West Germany. The Communities and their successors have grown in size by the accession of new member states and in power by the addition of policy areas to their remit. The United Kingdom became the first member state to leave the EU on 31 January 2020\. Before this, three territories of member states had left the EU or its forerunners. The latest major amendment to the constitutional basis of the EU, the Treaty of Lisbon, came into force in 2009.'*
让我们通过我们的搬运工的斯特梅尔,看看结果。为了在 nltk 的实现上传递整个文本,我们必须使用 word_tokenize 函数来标记我们的文本:
*from nltk.stem import PorterStemmer
from nltk.tokenize import word_tokenizetokenized_eu = word_tokenize(eu_definition)porter_eu = [porter.stem(word) for word in tokenized_eu]*
让我们检查最终的词干版本:
*'the european union ( EU ) is a polit and econom union of 27 member state that are locat primarili in europ . it member have a combin area of 4,233,255.3 km2 ( 1,634,469.0 sq mi ) and an estim total popul of about 447 million . the EU ha develop an intern singl market through a standardis system of law that appli in all member state in those matter , and onli those matter , where member have agre to act as one . EU polici aim to ensur the free movement of peopl , good , servic and capit within the intern market ; enact legisl in justic and home affair ; and maintain common polici on trade , agricultur , fisheri and region develop . passport control have been abolish for travel within the schengen area . A monetari union wa establish in 1999 , come into full forc in 2002 , and is compos of 19 EU member state which use the euro currenc . the EU ha often been describ as a sui generi polit entiti ( without preced or comparison ) .the EU and european citizenship were establish when the maastricht treati came into forc in 1993 . the EU trace it origin to the european coal and steel commun ( ecsc ) and the european econom commun ( eec ) , establish , respect , by the 1951 treati of pari and 1957 treati of rome . the origin member of what came to be known as the european commun were the inner six : belgium , franc , itali , luxembourg , the netherland , and west germani . the commun and their successor have grown in size by the access of new member state and in power by the addit of polici area to their remit . the unit kingdom becam the first member state to leav the EU on 31 januari 2020 . befor thi , three territori of member state had left the EU or it forerunn . the latest major amend to the constitut basi of the EU , the treati of lisbon , came into forc in 2009 .'*
这是使用波特词干分析器对 eu_definition 文本进行词干分析的版本。这对于人类来说是不可能的,但是请记住,词干提取的主要目的是规范化文本,以提高机器学习算法的泛化能力。我们的词干版本包含 1430 个字符,不包括空格。我们可以通过以下方式获得:
*len(''.join(porter_eu))*
***我们的原始句子包含 1591 个字符,*我们可以使用:
*len(''.join(word_tokenize(eu_definition)))*
信息保留的百分比是这些数字之间的比值(1430/1591),约为 89.88%。
如果我们对 Snowball 和 Lancaster 的相同文本应用相同的逻辑,我们会得到以下值:
- 雪球:90.88%
- 兰卡斯特:78.44%
不出所料,保留较少信息的词干分析器是兰卡斯特·斯特梅尔。
如果您想在项目中使用词干,这里有一个小要点和代码:
就是这样!词干是最常用的文本规范化技术之一,当您想要减少将在代码中使用的词汇(独特的单词)时,它可能适合您的自然语言管道。但是请记住,与任何规范化一样,每次应用词干都会丢失语料库中的一些原始信息。
尽管如此,词干分析对于数据科学家来说是一个很好的工具,因为它仍然广泛应用于整个 NLP 应用程序,并且可能对监督和非监督方法都有好处。
感谢您花时间阅读这篇文章!随意在 LinkedIn 上加我(【https://www.linkedin.com/in/ivobernardo/】)查看我公司网站(https://daredata.engineering/home)。
如果你有兴趣获得分析方面的培训,你也可以访问我在 Udemy(https://www.udemy.com/user/ivo-bernardo/)上的页面
这个例子摘自我在 Udemy 平台 上为绝对初学者开设的 NLP 课程——该课程适合初学者和希望学习自然语言处理基础知识的人。该课程还包含 50 多个编码练习,使您能够在学习新概念的同时进行练习。
*https://ivopbernardo.medium.com/membership *
逐步在关系数据库中创建 SQL 表
初学者教程,学习创建带有主键和外键的关系表的艺术
大量 SQL 教程向您展示了如何查询和连接数据库中的表,以提取有用的信息。这些教程基于假设已经创建了表,并且表之间的关系已经建立… 对于从零开始的人来说,情况并非如此!本文将展示如何从空白脚本开始。我们将建立一个非常简单的数据库,其中有三个相互关联的表:病人-医生-医院。
您将在本文中发现:
- 如何在 SQL 中创建表
- 如何在表中添加唯一标识符
- 如何使用主键和外键关联表
- 如何用真实数据填充表格
如果您还不是会员,请在此获得您的中级会员资格!
需要了解的几个有用的首字母缩写词:
什么是 RDBs: 关系数据库( RDB )是由表、记录和列组成的多个数据集的集合。
什么是 SQL: SQL 是一种用于编程的特定领域语言,旨在管理关系数据库管理系统中的数据
**什么是表:**在关系数据库中保存数据的数据库对象
用户故事
一个人走进医院,马上就会被联系到一个医生。当发现一种疾病或状况时,病人会得到一种药物并被送回家。至少这是我们今天要讨论的最好的情况。同样,每个医生在医院的特定部门工作。显然,一个医生可以为多家医院甚至多个部门工作,但是对于这个用例,我们将假设只有一个可能的值。
因此,我们可以说病人表链接到医生表,医生表链接到医院表。间接地,病人通过分配给他们的医生与医院有联系。
在开始创建表的代码和语法之前,让我们看一下最终结果。
存储在关系数据库中的表及其
第一步:创建表格
在 SQL 语言中,我们使用以下语法创建一个表:
create table patient
(
name varchar,
lastname varchar,
hospital int,
id serial,
primary_doctor int
);
create unique index patient_id_uindex
on patient (id);
alter table patient
add constraint patient_pk
primary key (id);
让我们将代码分解成小的逻辑步骤:
该查询有三个主要部分:
- 创建表格
这将创建一个表,其中包含我们希望该表包含的所有列和存储的信息类型。首先给列一个名称,然后给它们存储一个数据类型。 Integer , serial (顺序整数),varchar(一串字/秒)。
- 创建唯一索引
这表明在第一步中刚刚创建的列 id 只能取唯一值。这是什么意思?任何两个患者都不能有相同的标识符。将这个约束添加到病人的 id 中是有意义的,否则同名的人可能会混淆。
- 涂改表
最后,我们取同一个 id 列,我们给它分配主键的角色。当一列中的值是唯一的并且是整数形式时,我们只能将该列指定为主键。在我们的例子中,“patient_pk”代表患者主键。
SQL 表不需要主键,但它是保持数据整洁和跟踪每个条目的有用功能。
对医院和医生表重复相同的过程。
create table doctor
(
name varchar,
hospital varchar,
id serial
);
create unique index doctor_id_uindex
on doctor (id);
alter table doctor
add constraint doctor_pk
primary key (id);
创建存储医院信息的表:
create table hospital
(
name varchar,
id serial
);
create unique index hospital_id_uindex
on hospital (id);
alter table hospital
add constraint hospital_pk
primary key (id);
第二步:通过外键和主键关联表
目前,我们只有三个相互独立的表,不知道其他表的存在。让我们通过添加 外键 来设置表之间的关系。
这方面的代码如下:
alter table patient
add constraint patient_doctor_id_fk
foreign key (primary_doctor) references doctor (id);
让我们把它分成三个步骤:
- Alter table :由于表已经被创建,我们需要改变它的当前状态来添加一个外键。
2.添加约束:用于指定表格中数据的规则。这就是我们给将要做的事情命名的地方。在这种情况下,添加一个外键。
3.外键:这里我们指定我们取列" primary_doctor “并将其与 doctor 表中的” id "列相关联。这样,当我们向某个医生添加一个患者时,这两个表会立即链接起来,我们可以在输入患者时搜索医生信息,反之亦然。
类似地,要链接医生表和医院表:
alter table doctor
add constraint doctor_hospital_id_fk
foreign key (hospital) references hospital (id);
用真实的医院、患者和医生信息填充表格
当开始填充数据时,我们需要非常注意填充的顺序。至少对于这个初级教程来说,我建议您从填充医院表开始,然后是医生,最后是病人。
这样做的原因是因为在查看表之间的关系时,医院可以自己袖手旁观。当我们添加新医院时,不需要其他患者或医生的信息。而医生和病人之间存在依赖关系。
向表中添加新医院
在本例中,我们需要提供的唯一值是医院名称/位置。 id 列由 SQL 在后台自动填充。第一个条目将具有 id =1,并且每个新条目增加 1。
INSERT INTO hospital (location) VALUES ('Johns Hopkins')
现在我们有了一家医院,我们可以在医生表中添加一名医生。在这里,我们提供医生的姓名、工作部门和医院的 id。这是直接引用医院的表。在本例中,id = 1,因此我们引用上面创建的约翰霍普金斯医院。
INSERT INTO doctor (full_name, department, hospital) VALUES ('alex','dermatology', 1)
最后我们可以插入到患者表中。就像我们对于医生一样,第一列表示每个患者的特征值,最后我们添加与该患者相关联的医生的 id。
INSERT INTO patient (name, age, gender, entry_date, primary_doctor) VALUES ('james','85', 'M', '01/01/1982', 1 )
**就是这样!**确保在添加新患者和新医生时,只插入表中已经存在的外键值。当表中只注册了 3 名医生时,不要创建主医生 id = 7 的患者…
一些陷阱:
- 一个病人有多个医生会怎么样?
- 一个医生在多家医院工作会怎么样?
- 病人定期去医院会怎么样?
我们是否将它们注册到一个新行中,并因此分配一个新的惟一 id?我们是否将多个条目与同一个患者/医生相关联?但是,这如何与唯一主键约束保持一致呢?
对于更高级的 SQL 用户来说,这些都是非常好的问题。现在,我鼓励您用一些简单的例子创建自己的小表结构。
让你开始的想法
使用上面提供的代码尝试这些关系。这是真正测试您对 SQL 和关系数据库的理解的最佳方式。祝你好运!
- 学生—教师—教室
- 足球运动员—球队—进球
- 产品—商店—购买
非常感谢你的阅读!
更多类似的文章,请点击在媒体上找到我。
如果您有任何关于如何改进的问题、建议或想法,请在下面留下评论或通过 LinkedIn 这里取得联系。
Sci-kit 学习管道的分步教程
实践教程
立即使用管道来简化您的数据科学项目!
大多数数据科学项目(像我一样热衷于说所有项目)都需要一定程度的数据清理和预处理,以充分利用机器学习模型。一些常见的预处理或转换包括:
a.输入缺失值
b.移除异常值
c.标准化或规范化数字特征
d.编码分类特征
Sci-kit learn 在预处理包下有一堆支持这种转换的函数,比如 StandardScaler,simple imputr…等等。
典型且简化的数据科学工作流需要
- 获取训练数据
- 清理/预处理/转换数据
- 训练一个机器学习模型
- 评估和优化模型
- 清理/预处理/转换新数据
- 根据新数据拟合模型以进行预测。
您可能会注意到,在工作流中,数据预处理至少要进行两次。尽管这一步既繁琐又耗时,但如果我们能自动化这一过程并将其应用于所有未来的新数据集,那该多好啊。
好消息是:是的,我们绝对可以!有了 scikit learn pipeline,我们可以轻松地将流程系统化,从而使其极具可重复性。接下来,我将带您了解使用 scikit learn pipeline 的过程,让您的生活更加轻松。
** 免责声明:这篇文章的目的是了解 scikit learn pipeline 的用法,而不是训练一个完美的机器学习模型。
读入数据
我们将使用来自微软神奇的机器学习学习材料的“每日自行车共享”数据。
**import** pandas **as** pd
**import** numpy **as** npdata = pd.read_csv(‘[https://raw.githubusercontent.com/MicrosoftDocs/ml-basics/master/data/daily-bike-share.csv'](https://raw.githubusercontent.com/MicrosoftDocs/ml-basics/master/data/daily-bike-share.csv'))
data.dtypes
data.isnull().sum()
幸运的是,该数据集没有缺失值。虽然看起来所有的特征都是数字,但实际上我们需要识别一些分类特征。那些是 [‘季节’,‘月份’,‘假日’,‘工作日’,‘天气’] 。为了便于说明,我仍然将它视为缺少值。我们先过滤掉一些明显没用的功能。
data = data[['season'
, 'mnth'
, 'holiday'
, 'weekday'
, 'workingday'
, 'weathersit'
, 'temp'
, 'atemp'
, 'hum'
, 'windspeed'
, 'rentals']]
拆分数据
在创建管道之前,我们需要首先将数据分成训练集和测试集。
**from** sklearn.model_selection **import** train_test_split
X = data.drop('rentals',axis=1)
y = data['rentals']X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=123)
创建管道
我们将要处理的管道的主要参数是’ steps 。从文档来看,它是一个链接的(名称,转换)元组(实现 fit/transform)的“列表,按照它们被链接的顺序,最后一个对象是一个估计器。”
简单地看一下管道应该是什么样子更容易:
Pipeline(steps=[('name_of_preprocessor', preprocessor),
('name_of_ml_model', ml_model())])
“预处理器”是复杂的部分,我们必须自己创建。让我们继续吧!
预处理器
我们需要的包如下:
**from** sklearn.preprocessing **import** StandardScaler, OrdinalEncoder
**from** sklearn.impute **import** SimpleImputer
**from** sklearn.compose **import** ColumnTransformer
**from** sklearn.pipeline **import** Pipeline
首先,我们需要为数字和分类特征定义转换器。变换步骤由元组表示。在这个元组中,首先定义转换器的名称,然后定义想要应用的函数。元组的顺序将是管道应用转换的顺序。这里,我们首先处理缺失值,然后标准化数字特征和编码分类特征。
numeric_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='mean'))
,('scaler', StandardScaler())
])categorical_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='constant'))
,('encoder', OrdinalEncoder())
])
我们需要做的下一件事是指定哪些列是数字的,哪些是分类的,这样我们就可以相应地应用转换器。我们通过使用 ColumnTransformer 将转换器应用于特征。将转换器应用于特征是我们的预处理器。与 pipeline 类似,我们将由*(‘name’,‘transformer’,‘features’)*组成的元组列表传递给参数“ transformers ”。
numeric_features = ['temp', 'atemp', 'hum', 'windspeed']categorical_features = ['season', 'mnth', 'holiday', 'weekday', 'workingday', 'weathersit']preprocessor = ColumnTransformer(
transformers=[
('numeric', numeric_transformer, numeric_features)
,('categorical', categorical_transformer, categorical_features)
])
有些人会根据数据类型创建数字/分类特征列表,如下所示:
numeric_features = data.select_dtypes(include=['int64', 'float64']).columnscategorical_features = data.select_dtypes(include=['object']).drop(['Loan_Status'], axis=1).columns
我个人不建议这样做,因为如果你有伪装成数值数据类型的分类特征,比如这个数据集,你将无法识别它们。仅当您 100%确定只有数字要素是数字数据类型时,才使用此方法。
估计器
在组装我们的预处理器之后,我们可以添加估计器,这是您想要应用的机器学习算法,以完成我们的预处理和训练管道。因为在这种情况下,目标变量是连续的,所以我将在这里应用随机森林回归模型。
**from** sklearn.ensemble **import** RandomForestRegressorpipeline = Pipeline(steps = [
('preprocessor', preprocessor)
,('regressor',RandomForestRegressor())
])
为了创建模型,类似于我们过去用机器学习算法所做的,我们使用 pipeline 的‘fit’功能。
rf_model = pipeline.fit(X_train, y_train)
print (rf_model)
使用常规方法评估模型。
**from** sklearn.metrics **import** r2_scorepredictions = rf_model.predict(X_test)print (r2_score(y_test, predictions))
>> 0.7355156699663605
使用模型
为了最大限度地提高再现性,我们希望对新的输入数据重复使用该模型。让我们使用“joblib”包将模型保存为 pickle 文件。
**import** joblibjoblib.dump(rf_model, './rf_model.pkl')
现在我们可以调用这个管道,它包括我们需要的各种数据预处理和训练模型,只要我们需要它。
# In other notebooks
rf_model = joblib.load('PATH/TO/rf_model.pkl')new_prediction = rf_model.predict(new_data)
结论
在了解 scikit learn pipeline 之前,每当我想将同一个模型应用于不同的数据集时,我总是不得不重做整个数据预处理和转换工作。这真是一个乏味的过程。我试图编写一个函数来完成所有这些任务,但是结果并不令人满意,也没有为我节省很多工作量。
Scikit learn pipeline 确实让我的工作流程更加顺畅和灵活。例如,您可以轻松比较许多算法的性能,例如:
regressors = [
regressor_1()
,regressor_2()
,regressor_3()
....]for regressor in regressors:
pipeline = Pipeline(steps = [
('preprocessor', preprocessor)
,('regressor',regressor)
])
model = pipeline.fit(X_train, y_train)
predictions = model.predict(X_test)
print (regressor)
print (f('Model r2 score:{r2_score(predictions, y_test)}')
,或者调整预处理/转换方法。例如,使用“中值”来填充缺失值,对数字特征使用不同的定标器,改变为一次性编码而不是顺序编码来处理分类特征、超参数调整等。
numeric_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='median'))
,('scaler', MinMaxScaler())
])categorical_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='constant'))
,('encoder', OneHotEncoder())
])pipeline = Pipeline(steps = [
('preprocessor', preprocessor)
,('regressor',RandomForestRegressor(n_estimators=300
,max_depth=10))
])
所有上述调整现在都可以简单地通过改变函数中的一个参数来完成。
我希望这能对你有所帮助,欢迎任何评论或建议!
斯蒂芬金文本生成与人工智能(RNN),使用 Python
J. Kelly Brito 在 Unsplash 上的照片
以下是我如何训练一个深度学习架构来编写一个类似斯蒂芬·金的文本。
**我喜欢阅读,我是斯蒂芬·金的超级粉丝。**另外,我是一名物理学家和数据科学家,目前在获得硕士学位后正在休假。在这段时间里,我决定读另一本斯蒂芬·金的书,我真的很喜欢它。
我永远不会让电脑写一本斯蒂芬·金的书,原因很简单。
我们还没有掌握这种技术。
如果你看一些 NLP 实验(例如 AI 写笑话这里)你可以有把握地说我们在写作方面不如人类。
所以你可能会问“为什么在一篇解释如何用人工智能生成文本的博客文章中,你告诉我我们不能让人工智能生成文本**?**”。答案是这样的:
虽然我们确实不能让计算机写一整本书(就目前而言),但人工智能仍然能够提出情节建议,获得见解,并帮助人类写作。
实际上,它在这些方面做得非常好!
因此,我决定拿一堆斯蒂芬·金的文本,用一个人工智能(深度学习)算法写一个小的新的。这是游戏计划:
- 理论
- 代码
- 结果
我知道你们中的一些人可能只对结果感兴趣,或者只对理论部分感兴趣,或者只对代码感兴趣。每个部分都是前后一致的,所以请随意跳到你最喜欢的部分。
我们潜进去吧!
1。 理论
注意:这是人工智能结构背后所需理论的简要概述。如果你觉得你需要更扎实的理论背景,你应该参考不同的资料或书籍。
当我们说 AI 时,我们会说很多东西。另一方面,当谈到“文本生成”时,我们可能希望参考深度学习。深度学习是一种特殊的人工智能,能够通过执行分层学习来完成任务。让我们简单点。如果你想识别你面前的动物是不是猫,你可能会从看颜色开始,然后是形状,然后是眼睛,等等。所以你基本上从简单的概念开始,然后从简单的概念中建立更复杂的概念。出于这个原因,我们说学习是分层的(即输入由不同的层处理)。
假设输入是由 N = N×N 个像素组成的图像。 这个输入被不同的层处理,然后如果动物是猫,结果是 1,如果不是猫,结果是 0。很简单,对吧?
需要知道的重要一点是,这个结构需要训练。这意味着你必须使用大量的猫和非猫的标签图片(idk,dogs?)并建立一个学习过程,让机器学习如何执行任务。
现在,让我们谈谈生意。当我们谈论文本生成时,我们必须记住两个重要的概念:
a)将字嵌入
b)递归神经网络
单词嵌入是机器把一个文本(一个字符串)转换成一个向量(一个数字序列)的部分。
递归神经网络是一种特殊的深度学习结构。这种结构能够收集一个序列顺序(如一个句子)的所有先前输入,以预测获得某个输出的概率。特别是有一个词汇包含了文本的所有单词(假设有 V 单词)和一个 **Logit 输出。**这是一个在[0,1]范围内的 V 数序列,其和为 1。序列的每个数字(假设是 j)告诉你输入序列后获得 j 字的概率。
到目前为止所解释的一切都总结在下面的方案中:
来源:https://www.tensorflow.org/text/tutorials/text_generation
2。代码代码
注:本部分灵感来自本来源
这可能会让你吃惊,但是代码部分非常简单。
这些是您将需要的库:
我用过的所有斯蒂芬·金的文本都可以在这里找到。
在你得到它们之后,很容易用一些非常简单的 Python 普通代码行来使用它们:
这些是为了使文本适应 TensorFlow 并创建字典而运行的代码行:
建立模型:
训练模型:
获取训练好的模型:
这里是生成文本功能:
可用于实际生成以下简单行的文本(假设给定了输入字符串):
如"后"已作为输入序列给出。
3结果
到目前为止描述的人工智能结构原则上可以从单个输入生成无限的文本。当然,这会导致糟糕的表现,因为它最终只会一遍又一遍地重复同样的话。因此,从输入中生成一个句子是安全的。需要注意的是,有一个参数叫做 t(温度),它允许你设置算法的创造性。t= 0 意味着重复数据集的相同单词,t=1 意味着发明非英语句子或单词。这两者之间的良好平衡是关键。
给你看看一些结果吧!
第一个例子(t = 0.1,中等输入):
Input: "After the"
Output: "After the sun was warm on our faces we were both wearing sweater (.) You know how confused dreams are logic like"
第二个例子(t=0.1,长输入):
Input: "So I decided"
Output: "So I decided the ordinary was going on. I think this was because in my heart I believed that such conditions only"
第三个例子(t=0.7,短输入):
Input: "I"
Output: "I fell in love to the sound of breaking glass edged it liked jagged lace. The two ved her be a fluke I r"
第四个例子(t=0.2,短输入):
Input: "He"
Output: "He who spotted her. He recognized her by her red handbag spread out in front of me and it was like takin"
一些乐趣(wordcloud):
单词越大,使用频率越高。
我用 Python 制作的图片
结论:
正如可能看到的,我们无法用这种技术实现一个完全一致的斯蒂芬·金文本生成器。尽管如此,斯蒂芬·金的粉丝可能会意识到,在生成的文本中有一些东西让他们想起了斯蒂芬·金。这并不令人惊讶,因为人工智能算法已经“看到”了由斯蒂芬·金文本组成的数据集。另一方面,令人惊讶的是,该算法已经发明了一种新的斯蒂芬·金式(非常短)文本!
如果你喜欢这篇文章,你想知道更多关于机器学习的知识,或者你只是想问我一些你可以问的问题:
A.在 Linkedin 上关注我,在那里我发布我所有的故事
B .订阅我的 简讯 。这会让你了解新的故事,并给你机会发短信给我,让我收到你所有的更正或疑问。
C .成为 推荐会员 ,这样你就不会有任何“本月最大数量的故事”,你可以阅读我(以及成千上万其他机器学习和数据科学顶级作家)写的任何关于最新可用技术的文章。
任何人都快乐斯蒂芬·金!
走进甘斯的神奇世界
甘的一步一步教程
https://unsplash.com/photos/6dN9l-gopyo
一个生成模型有潜在的魔力,如果训练得当,它可以像专家一样写诗、创作音乐、绘制图像。GAN 的目标是生成非常逼真的合成样本。甘模型在对抗环境中学习技巧。有两个多层神经网络,一个作为发生器,另一个作为其对手,称为鉴别器。两者都使用常规反向传播方法训练,尽管具有不同的和冲突的损失函数(对抗性设置)。一旦训练完成,鉴频器被移除,生成器被用于产生样本。
下图对此进行了说明。这里的任务是能够创建像 MNIST 手写数字。
图 1a:GAN 的训练阶段(图片来源:作者)
该图有两个神经网络,第一个是生成器,第二个是鉴别器。
生成器将随机噪声向量作为输入,并生成与真实数据维数相同的图像。为什么用噪声作为输入?这确保了生成器不会产生真实数据中已有数据的副本。
鉴别器是一个进行二元分类的简单分类器。来自生成器的类“0”或假类,以及来自真实图像的类“1”,在本例中为 MNIST。
鉴别器使用交叉熵的常规损失函数,而生成器训练通过鉴别器,保持其权重恒定(否则收敛将像移动目标一样),并且这里损失函数测量具有 1 类概率的伪图像。这就是冲突的来源。鉴别器希望真实类被分类为真实类,假类被分类为假类,生成器希望假类被分类为真实类。
一旦训练完成,鉴别器可以丢弃,生成器可以用来产生真实的样本,如下图所示。
图 1b:氮化镓的生成阶段
现在是实现部分,编码是根据 Jason Brownlee 的博客完成的。
步骤 1:定义生成器
def define_generator(latent_dim):
model = Sequential()
*# foundation for 7x7 image*
n_nodes = 128 * 7 * 7
model.add(Dense(n_nodes, input_dim=latent_dim))
model.add(LeakyReLU(alpha=0.2))
model.add(Reshape((7, 7, 128)))
*# upsample to 14x14*
model.add(Conv2DTranspose(128, (4,4), strides=(2,2), padding='same'))
model.add(LeakyReLU(alpha=0.2))
*# upsample to 28x28*
model.add(Conv2DTranspose(128, (4,4), strides=(2,2), padding='same'))
model.add(LeakyReLU(alpha=0.2))
model.add(Conv2D(1, (7,7), activation='sigmoid', padding='same'))
return model
生成器将噪声向量作为输入,并生成 28 X 28 的图像。下面是测试生成器的代码
noise = tf.random.normal([1, 100])
generator = define_generator(100)
generated_image = generator(noise, training=False)
plt.imshow(generated_image[0, :, :, 0], cmap='gray')
生成的图像如下
图 2:产生的随机噪声(图片来源:作者)
步骤 2:定义鉴别器模型
这是一个简单的二元分类网络。
def define_discriminator(in_shape=(28,28,1)):
model = Sequential()
model.add(Conv2D(64, (3,3), strides=(2, 2), padding='same', input_shape=in_shape))
model.add(LeakyReLU(alpha=0.2))
model.add(Dropout(0.4))
model.add(Conv2D(64, (3,3), strides=(2, 2), padding='same'))
model.add(LeakyReLU(alpha=0.2))
model.add(Dropout(0.4))
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))
*# compile model*
opt = Adam(lr=0.0002, beta_1=0.5)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy'])
return model
步骤 3:创建组合模型
这里的目的是训练发生器模型,鉴别器权重不会改变或者不可训练。
def define_gan(g_model, d_model):
*# make weights in the discriminator not trainable*
**d_model.trainable = False**
*# connect them*
model = Sequential()
*# add generator*
model.add(g_model)
*# add the discriminator*
model.add(d_model)
*# compile model*
opt = Adam(lr=0.0002, beta_1=0.5)
model.compile(loss='binary_crossentropy', optimizer=opt)
return model
第四步:搭建舞台。
- 加载真实数据: —从 MNIST 获取数据
- 生成真实数据: —从真实数据集中获取一个样本,并附加类标签‘1’
- 生成噪声数据:- 生成随机噪声作为发生器的输入
- 生成假日期:- 从生成器获取一个样本,并附加类标签‘0’
def load_real_samples():
*# load mnist dataset*
(trainX, _), (_, _) = mnist.load_data()
*# expand to 3d, e.g. add channels dimension*
X = expand_dims(trainX, axis=-1)
*# convert from unsigned ints to floats*
X = X.astype('float32')
*# scale from [0,255] to [0,1]*
X = X / 255.0
return Xdef generate_real_samples(dataset, n_samples):
*# choose random instances*
ix = randint(0, dataset.shape[0], n_samples)
*# retrieve selected images*
X = dataset[ix]
*# generate 'real' class labels (1)*
y = ones((n_samples, 1))
return X, ydef generate_latent_points(latent_dim, n_samples):
*# generate points in the latent space*
x_input = randn(latent_dim * n_samples)
*# reshape into a batch of inputs for the network*
x_input = x_input.reshape(n_samples, latent_dim)
return x_input def generate_fake_samples(g_model, latent_dim, n_samples):
*# generate points in latent space*
x_input = generate_latent_points(latent_dim, n_samples)
*# predict outputs*
X = g_model.predict(x_input)
*# create 'fake' class labels (0)*
y = zeros((n_samples, 1))
return X, y
第五步:训练方法甘
下面的代码是重要的一部分,有两个循环,外部的一个用于 Epochs,内部的一个用于 batches。正在训练两个模型,一个是鉴别器模型,另一个是具有鉴别器权重常数的组合模型。Epoch 的数量被设置为 5,这不会给出一个好的结果,但会让你知道它是否工作。
def train(g_model, d_model, gan_model, dataset, latent_dim, n_epochs=5, n_batch=256):
bat_per_epo = int(dataset.shape[0] / n_batch)
half_batch = int(n_batch / 2)
*# manually enumerate epochs*
for i **in** range(n_epochs):
*# enumerate batches over the training set*
for j **in** range(bat_per_epo):
*# get randomly selected 'real' samples*
X_real, y_real = generate_real_samples(dataset, half_batch)
*# generate 'fake' examples*
X_fake, y_fake = generate_fake_samples(g_model, latent_dim, half_batch)
*# create training set for the discriminator*
X, y = vstack((X_real, X_fake)), vstack((y_real, y_fake))
*# update discriminator model weights*
d_loss, _ = d_model.train_on_batch(X, y)
*# prepare points in latent space as input for the generator*
X_gan = generate_latent_points(latent_dim, n_batch)
*# create inverted labels for the fake samples*
y_gan = ones((n_batch, 1))
*# update the generator via the discriminator's error*
g_loss = gan_model.train_on_batch(X_gan, y_gan)
*# summarize loss on this batch*
print('>**%d**, **%d**/**%d**, d=**%.3f**, g=**%.3f**' % (i+1, j+1, bat_per_epo, d_loss, g_loss))
步骤 6:使用参数运行训练方法
*# size of the latent space*
latent_dim = 100
*# create the discriminator*
d_model = define_discriminator()
*# create the generator*
g_model = define_generator(latent_dim)
*# create the gan*
gan_model = define_gan(g_model, d_model)
*# load image data*
dataset = load_real_samples()
*# train model*
train(g_model, d_model, gan_model, dataset, latent_dim)
生成阶段:
seed = tf.random.normal([num_examples_to_generate, noise_dim])
predictions = g_model(seed, training=False)
fig = plt.figure(figsize=(4, 4))
for i **in** range(predictions.shape[0]):
plt.subplot(4, 4, i+1)
plt.imshow(predictions[i, :, :, 0] , cmap='gray')
plt.axis('off')
下面是 5 个时期后生成的图像,当然,如果我们训练更多的时期,这将给出一些有意义的东西。
图 3:生成器生成的图像(图像来源:作者)
结论:
GAN 是最酷的一个,具有很大的潜力和积极的发展,这个入门只是让你开始。关于鉴别器的收敛性和严格性还存在一些问题,有兴趣的读者可以进一步深入了解。
你也可以从我们的视频讲座开始。
为了每个人的利益踩在每个人的脚趾上
数据科学部门在 21 世纪组织中的角色
介绍
(作者创作)
数据科学部门是传统公司结构的新成员。以下是如何有效地创造一个有益于你的组织,而不是一个创造不必要的内耗。
早在《哈佛商业评论》宣布数据科学是 21 世纪最性感的工作之前,数学家约翰·w·图基(John W. Tukey)就在他的论文“数据分析的未来”(1962)中对电子计算的到来将如何影响统计学做出了同样性感的预测。他将高度理论化和学术化的数理统计领域的不可或缺的概括应用到更实用的“数据分析”领域,其特点是在从数据中确定真理的实践中增加了一些程序,如“计划数据的收集以使其分析更容易、更精确或更准确,以及统计学的所有机制”。毕竟,这是科学最基本的准则:如何区分真理和谬误,阐明其完整的背景和适用性,以理解我们所居住和构成的宇宙?无论在哪个领域,都是通过获取数据来指导旅程。数据也可能被滥用——就像经常发生的那样——通过明确的意图、无意的偏见或简单的粗心来推动错误的叙述。图基写道,当时电子计算在数据分析方面的新生应用刚刚进入讨论,他指出,“携带计算尺比台式电脑更容易”,“计算机使完全不可行的事情变得可行”。随着计算能力的增长,数据揭示真相和谎言的能力也在增长。适用性的广度也在增长,数据科学现在几乎渗透到了研究或工业实践的每个领域。因此,出现了一个科学和工业相结合的新领域:“数据科学”,其特征是几个领域的交叉,如数学、统计学、数据分析、计算、数据库,以及大量以主题专业知识和科学探究为统一核心的艺术故事。鉴于这些组织现在面临的数据的复杂性、丰富性和重要性,数据科学填补了传统企业组织结构中出现的功能缺口。忽视这一差距的代价是根据与现实不符的叙述行事的后果。
“数据科学”在 2008 年首次被称为“数据科学”,它已经成为一个新的角色,出现在从许多其他组织合并而来并涉足许多领域的组织中。过去难以解决的问题现在可以通过这一新角色来解决,前提是它在组织中的职能得到明确定义,以补充现有的部门角色,而不是激发领土反弹。然而,要充分履行这一新角色,需要其他传统部门所具备的独特技能组合。数据科学在操作上用代码来表达,但是软件工程师通常不具备必要的数学或统计背景。此外,工程师的目标是建造为特定目的而工作的东西,而不是通过经验主义来寻求真理。受过传统训练的统计学家在数据分析的基本原则和经验主义方面有很强的基础,但通常没有受过软件和数据库设计或管理方面的训练。数据库管理员和数据工程师可以有效地管理大量数据,但不一定从事过科学研究。人工智能本身是一个子领域,位于数据科学的中心,除了编码、数据库和统计建模技能之外,还需要自己的专业知识。鉴于这一研究领域在 2020 年大约只有 10 年的历史,在其现代化身中,其领导者几乎总是在某个相关领域接受过正规教育,并在必要时移居到该领域。早期领导者的个人经历以及他们所服务的组织的需求为数据科学所扮演的角色提供了信息,随着行业普遍努力理解这一新职能角色的效用,这一角色可能会因组织而异。
作为一名实验性高能物理学家,我在学术界从事了多年的工作,研究宇宙如何利用粒子对撞机生成的数据集构成的最深刻的已知原理,并在一家飞行 wifi 提供商的数据团队中担任了几年的全栈软件工程师,在过去的几年里,我花了几年时间为 rMark Bio 建立数据科学项目,在那里我们致力于数据驱动的方法,以提高生命科学中的运营效率和可操作的洞察力收集。作为一家不受传统部门、产品或思想束缚的年轻公司,我们有机会定义数据科学在一个新组织中的作用,这个新组织受制于 21 世纪第二个十年的技术和经济力量。我想分享我们学到的东西。
数据科学部门的首要原则
我经常向数据科学家强调通过理解正在研究的问题背后的首要原则来解决问题的重要性,所以让我们以同样的方式来解决定义和建立数据科学部门的问题:数据科学部门的首要、最基本的目标是什么?我提议:
“数据科学计划的目标是战略性地识别数据事实,理解这些事实的全部复杂性,识别由此产生的相关事实陈述,然后将这些知识应用于与数据科学计划所在组织的使命相一致的一些实际目的。数据科学表现为经验主义,专门研究用于实现这一目标的方法和技术。”
最根本的目标不是构建有用的东西,即使这样做对于可靠地处理数据是必要的;不是有效地营销叙事,即使一旦发现数据的真实叙事,这样做是数据科学的责任;而不是销售产品,即使数据驱动的洞察力可能是该产品设计的组成部分。数据科学的首要原则是通过经验主义进行科学探究;其他一切都是追求的结果。通过经验主义寻求真理是数据科学部门区别于其他部门的角色,数据科学部门必须与其他部门协同工作。正如在任何科学领域一样,表达挑战传统智慧的创造性自由,无论努力的最终结果是加强现有智慧,更好地理解它,还是完全推翻它,都是这一角色的关键,也是数据科学追求其使命所必须尊重的。
数据科学包括软件工程、数据架构和统计学,但不是它们
数据科学最相似的一个角色是软件,因为在编写管理和研究数据的代码的同时,组织、清理和管理数据是一种实际需要。然而,对数据进行操作的软件的目标和输出不仅仅是转换、重组或显示数据,即使所有这些都可能是过程的一部分。识别数据中的真理和见解的目标导致数据科学软件的结果更不可预测和更不明确。机器学习模型的特定输入的正确输出不能像定义良好的数据转换那样预先预测,因此显式测试脚本不能总是以软件工程师习惯的方式编写。模型从来没有明确的“正确”或“不正确”,而是占据了一个模糊的领域,在某些适用的上下文中足够好(或不够好),而在其他上下文中不够好,通过准确性分数和其他度量来衡量,这些度量永远不可能是 100%(如果它们曾经是,这将否定建模的需要)。尽管如此,数据科学家的永恒任务是按照这些指标来改进模型。数据科学不是以数据的自动计算和转换为特征,而是对数据的自动研究,数据科学家的心态必须相应地不同于软件工程师,同时仍然掌握类似的技术技能。
如果软件工程是数据科学家实现其目标的工具集,那么统计学的经验主义就是产生创造愿景的创造性灵魂。除了一些新颖的边缘案例,“机器学习”可以被理解为用代码执行的统计建模的应用,而不是前电子计算时代统计学家所从事的笔到纸(或滑尺)的计算。如果您在由标准“x”(水平)和“y”(垂直)轴表示的二维平面中有一些数据,并且您想要找到穿过该数据的最佳拟合直线,您正在进行线性回归,这是统计建模的最简单形式之一。如果你用运行在计算机上的代码执行线性回归,你现在正在做“机器学习”。大多数传统的统计回归建模是以最能代表数据的方式将一些数学函数拟合到现有数据的实践。无论哪种数学函数适合数据集,确定最佳拟合函数的过程都遵循一个标准的高级流程:
- 定义要解决的问题并设计研究
- 收集、清理和组织数据集
- 大部分数据集将用于训练模型。数据集的小的、独立的和随机的子样本被保留用于被训练的模型的“测试”和“验证”。
- 在训练数据集上训练模型,使用测试数据集在训练过程中监视模型的质量,使用验证数据集查看模型在未明确训练的代表性数据上的表现。
- 修改并注意模型是训练过度还是训练不足(即偏差-方差权衡)。
- 将该模型应用于最初启动其构建的任何实际目的。
关于如何有效地执行这些公认的非常高层次的步骤,整本书都可以写,而且已经写了,但是这些概述了回归问题是如何执行的。
图示了多层感知器的计算图形表示,以及它的复杂性如何取代经典回归的单一数学函数(图片摘自作者关于在寻找希格斯玻色子中使用神经网络的论文,发表于 2010 年夏天。)
假设我们现在有一个数据集,我们想在数据中的一个形状上训练一个模型,这个形状不能用任何一个特定的数学函数来表示。可以通过用数学函数网络替换拟合数据的数学函数,对刚才描述的回归过程进行调整。这是经典统计建模与我们现在所说的“人工智能”(AI)相吻合的转折点。使用数学函数网络而不是单个数学函数网络已被证明在对比单个数学函数更复杂的数据要素进行建模时非常有效。虽然现在有各种各样的机器学习和人工智能方法,但最标准的形式在很大程度上遵循上述相同的基本过程(即“监督训练”过程)。如果说经典的统计建模方法论是“统计学 1.0”,那么 AI 就是“统计学 2.0”。然而,理解和执行人工智能模型需要数学和计算方面的专业知识,这往往超出了统计学领域的严格范围。此外,在实践中,现代人工智能建模还需要一定程度的数据架构和云计算专业知识来开发企业人工智能解决方案。
一个人对数据最关键的理解之一是如何表示它的形状。在考虑任何类型的建模之前,我们需要管理和理解数据本身。有多种方法来表示数据的形状,如何针对特定数据集做出明智的决策对数据仓库架构有着至关重要的影响。例如,客户、支票账户、储蓄账户、抵押贷款等的银行模型。传统上使用“关系数据库管理系统”,该系统将各种形式的数据表示为相互关联的表格。一个表包含所有的客户数据。另一种方法是将所有带有引用号的支票帐户返回到 customer 表中拥有该支票帐户的客户。塑造数据的另一种方式是“图,其特征是特定数据点具有潜在的复杂关系网。社交网络的用户以及每个用户与谁联系(即,与谁是“朋友”)非常适合表示为图形数据。当然,可以在图形数据库中表示银行数据,也可以在关系数据库管理系统中表示社交网络数据,但是这样做是否明智、有效和划算,需要对数据架构有良好的判断。在数据的进一步研究开始之前,数据科学的许多领域都需要做出并执行这样的判断。数据科学部门必须了解如何构建数据,并经常管理至少部分架构本身。
最后,如果我们不能将数据科学部门的发现传达给其他利益相关者,那么这些发现就毫无用处。组织中的其他领导者依靠事实来做出明智的决定。数据科学部门负责了解他们的工作如何被使用的后果,这需要所使用的数据领域中某种程度的主题专业知识。该专业知识可能与生产、营销、产品、设计或任何其他需要基于对数据的准确理解做出业务决策的职能相关。将数据和得出的结果联系起来同样重要。主题专业知识和对正在解决的业务问题的定性理解是“数据分析师”的任务,也应该在数据科学领域内考虑。
数据科学部门需要与软件应用、数据工程、IT、产品/设计、业务开发和其他部门密切合作,以确保组织作为一个整体在正确理解可用数据的基础上做出明智的决策。虽然数据科学领导者通常来自软件工程、应用统计、IT 或物理、数学和社会科学等学术领域,但为了实现数据科学部门与传统组织角色不同的愿景和功能,扩展个人原始培训之外的技能组合是必要的。
数据科学部门的职责
如果数据科学部门的角色需要融合各种现有的专业领域,以及一些新的特定于数据科学的领域,以完成与其他部门不同的任务,那么下一个自然问题是:数据科学部门的职责和期望是什么?
让我们从不要做什么开始。
在解决问题的过程中,有一个我经常遇到的错误,我不得不在这次对话的开始提到它——一个新手数据科学家和经验丰富的企业高管经常犯的错误:以“我们需要使用人工智能”的结论开始,然后试图构建一个这样做的理由。对于刚刚进入该领域的新数据科学家来说,能够说一些先进的机器学习或人工智能方法已经付诸实践,既有兴奋感,也有职业压力。在实验设置、繁琐的数据清理、数据库设计和管理方面做得非常出色,选择一种简单而经典的建模方法并不能像大型 Word2Vec 或其他人工智能模型那样,传递自我并恢复建立街头信誉。同样,在许多拥有大量数据但不擅长数据管理的传统公司中,人们有被视为“投资于人工智能”未来的压力,因为这是过去十年中最大的价值驱动型流行语之一。如果不小心接近,大量的资金会很快被浪费在无效的应用上。使用数据有效解决问题需要从要解决的业务问题开始,确定可用的相关数据(或者如果不可用,可以收集哪些数据),然后返回到最适合该问题的解决方案,而不要过早地偏向特定的方法。这听起来很抽象,但使用基于人工智能的解决方案的压力,即使是在脱离上下文的情况下,也是普遍和强烈的,因为它们是短视的。一个负责任的数据科学部门建议不要做这种蠢事。
假设这些担忧已经消除。
数据科学部门的任务是确定数据驱动的决策战略,推动其所在的大型组织的使命。首先应该确定要解决的业务问题,并获得足够的专业知识。数据科学家不能有效地执行他们的功能,他们盲目地收集数据,而没有对环境的直观理解,并启动一些建模或分析方法,这是另一个太常见的陷阱。我们需要愿意与拥有与问题相关的主题专业知识的涉众坐在一起,并理解他们流程中的痛点。我们不是来取代他们的;我们在这里帮助他们更有效地执行他们的职能。这也应该有技巧地沟通。即使在这样一门硬科学中,人际交往能力和情商也是绝对必要的。
然后需要确定相关数据,包括已经存在的数据和需要获取的数据。必须理解并记录数据的性质、上下文和形式。需要明智地设计大大小小的数据集。应该解决的无数问题中的几个是:
- 数据将如何收集,需要经过多少步转换?也就是说,设计 ETL(“提取、转换、加载”)过程。
- 数据应该如何存储?它需要在 CSV 文件、关系(SQL)数据库、JSON (NoSQL)、图形数据库、时间序列数据库等中吗??数据的各个部分是否需要以各种形状存储?
- 如果数据本质上是表格形式的,那么它是否需要在 SQL 数据库中,或者 CSV 文件是否足够?维护云托管的 SQL 数据库比维护 blob 存储中的 CSV 文件要昂贵得多。在许多情况下,处理 CSV 文件对于建模来说也要高效得多。成本问题不容忽视。
- 数据是否包含受欧盟《一般数据保护条例》(GDPR)或《加州消费者隐私法》(CCPA)保护的“个人身份信息”(PII)?在这种情况下,必须解决管理这些数据的数据科学部门的法律责任。不这样做可能会导致足以拖垮中小型公司的巨额罚款。
- 当需要唯一标识符时,是否有数据类型没有适当的唯一标识符?(这个在 rMark Bio 很常见)
- 所有的值都被转换成正确的类型了吗?例如,如果预期为整数的值实际上是字母数字字符,则会出现意外问题。如果数据科学家不挑剔,可能会出现“1 + 2 = 12”这样的问题。
- 确定常见的数据清理问题,例如:丢失的数据、不完整的数据、以无法处理的格式到达的数据,以及某段数据是否只是被输入了错误的列?(也很常见)
- 设计数据时应该考虑候选的方法或建模解决方案。
如果输入了垃圾数据,世界上最复杂的建模或分析方法也只会产生垃圾结果。出于所有这些原因以及更多原因,数据科学部门需要拥有根据自身需求设计数据的自由。这并不意味着数据科学部门不能或不应该与外部数据工程组织协同工作;这确实意味着数据科学部门需要具备技能和资源来构建执行任务所需的数据。
有了可供使用的架构数据集,就可以开始研究数据了。数据科学家可用的分析工具集非常庞大,并且在快速增长。创造过程的混乱无人能幸免,发现数据的真相就是这样。在找到可行的解决方案之前,需要培养和尊重创造性的过程。一些解决方案可能以一次性的、孤立的研究报告的形式提交。其他时候,解决方案需要以服务的形式来维护,创造性努力的结果需要清理、记录并重组为可维护的软件。创作混乱需要纪律;技术掌握是艺术价值创造的必要伙伴。在浏览器窗口中执行脚本的 Python 笔记本是数据科学家中非常流行的工具,非常适合教学。适当的和可维护的软件,它们绝对不是。除了孤立的研究,我强烈认为数据科学的成果应该是组织良好的、可维护的、可部署的软件。数据科学部门为我们职责范围内的主题开发软件。因此,像所有软件一样,我们的软件需要用健壮的软件开发生命周期来管理。
最后,如果不能有效沟通,任何解决方案都不值得花费时间、精力和人力成本。无法交流的数据科学是无法利用的。如果数据科学家的中心任务是找到关于数据集的真实叙述,那么有效的沟通技巧,无论是书面还是口头的,都是至关重要的,没有商量的余地。
当然,数据科学部门不仅仅生产软件,数据科学部门的每个成员都没有必要掌握上面讨论的每一项技能。数据科学部门需要数据工程师和架构师、机器学习和人工智能专家的功能,这些专家可以作为强大的软件、统计学家和数学家、数据分析师、可视化专家和有效的沟通者来完成他们的工作。数据科学部门应该有这些领域的专家。
哪些数据科学可以实现,而其他重叠部门/角色不能实现
只是在 21 世纪,在信息时代的黎明,数据变得无处不在,以至于组织内的新职能角色变得必不可少。然而,鉴于此,这种需要挤入现有组织结构的新角色的出现是不可避免的。需要高效地管理和理解数据的数量、种类和速度(大数据的“3v”)。要做到这一点,不仅需要独特的技术组合,还需要过去许多组织可能不存在的科学心态。直觉和本能,从个人经历和对它们的主观感知中表现出来,是有缺陷的;常识没有那么普遍,也没有那么普遍错误。数据科学可以实施和执行对组织正在处理的现实的客观评估,以确保决策是正确的。这种情境化的、基于数据的对现实的感知也将随着情境及其产生的数据的变化而不断变化。在充斥着大量数据的商业和经济环境中,训练有素的科学头脑和执行这一任务的专业技术变得越来越不可或缺。
机器学习过程的步骤
机器学习过程由本质上循环的几个步骤组成。组织通过 MLOps 实现自动化的步骤越多,机器学习过程就越成熟。
约书亚·索蒂诺在 Unsplash 上拍摄的照片
MLOps 是关于 DevOps 哲学在机器学习系统中的应用(要阅读更多关于这两种实践的内容,请查看我的文章:【https://towardsdatascience.com/mlops-vs-devops-5c9a4d5a60ba】)。将机器学习模型投入生产的机器学习过程包括几个步骤。组成机器学习过程的步骤的自动化水平决定了机器学习过程的成熟度。通常,过程越自动化,给定新的输入/模型实现,训练新模型的速度就越高。
机器学习过程的步骤
- **数据提取:**该步骤涉及从各种数据源整合用于机器学习任务的数据。这一步的目的是选择在机器学习任务中使用哪些数据。
- **数据分析:**在此步骤中,执行探索性数据分析(EDA)以更好地理解提取的数据。这一步的目的有两个:
1:理解数据、模式和要用作模型输入/标签的数据分布。
2:确定执行机器学习任务所需的任何数据准备步骤和特征工程。 - **数据准备:**该步骤涉及数据清理(处理缺失数据、删除无意义数据等)、数据拆分为训练/验证/测试,以及通过创建新特征进行特征工程,以有望提高模型的预测能力。这一步的输出是训练、验证和测试数据,所有的数据都被清理,新的特征以正确的格式被添加,可以被传递到模型中。
- **模型训练:**使用数据准备步骤的输出来实现不同的算法,以训练各种机器学习模型。通常,我在这一步骤中进行超参数调整,以探索超参数空间,从而确定最佳模型。这个模型的输出是在这个步骤中找到的最佳模型的模型工件(模型架构和模型权重)。
- **模型评估:**根据数据准备步骤中收集的测试数据,对上一步中找到的最佳模型进行评估。在此步骤之前,必须决定一个评估度量或一组评估度量,以确定如何评估模型。
- **模型验证:**选择的模型必须足够令人满意,才能被认为足以部署到生产中。为了确定这一点,通常模型必须比基线表现得更好。这可能是测试模型预测是否比它试图改进的当前过程更好。
- **模型服务:**选择的模型被部署到适当的环境中,以使应用程序/流程能够使用模型的预测。要阅读关于各种模型部署选项的更多细节,请参考我的文章:https://towardsdatascience . com/machine-learning-model-deployment-options-47 C1 F3 d 77626。根据业务需求,该模型可以部署到以下位置之一:
1 .使用 REST API 的在线预测,其中应用程序/流程通过端点向模型提供输入数据,并接收回模型的预测。
2。模型嵌入到边缘设备中,并在边缘设备上计算模型的预测。
3。利用批量预测过程,其中周期性地或在某些事件上创建计算资源,并且在计算资源上部署模型以处理对输入数据的预测。 - **模型监控:**监控部署的模型的性能,以确定机器学习过程是否需要经历另一次迭代。通常有一个评估度量阈值集,如果部署的模型的评估度量恶化超过这个阈值,那么可能是时候进行另一次迭代了。
一旦确定机器学习过程需要经历另一次迭代,所有的步骤被再次重复,最有可能的是对各个步骤进行调整或增强,以针对数据的变化进行调整。通过这种重复和循环的过程,很明显,自动化这些步骤将提高效率、一致性和可扩展性。
一般来说,一个组织能够自动化的这些步骤越多,机器学习过程就越成熟。能够自动化大部分或所有这些步骤的好处是,组织可以有效地进行许多实验,并更快地将经验证的模型部署到生产中。此外,通过消除手动流程,它降低了由人为错误导致的潜在故障的几率。
有 3 个级别的 MLOps,组成机器学习过程的步骤具有不同的自动化级别。这些级别因其特点和挑战而有所不同。我将在以后的文章中更详细地介绍这三个层次的特点和挑战。
Python 中的逐步回归教程
使用逐步回归发现数据中的意义
弗兰基·查马基在 Unsplash 上拍摄的照片
你如何在数据中找到意义?在我们的迷你项目中,我和我的朋友 @ErikaSM 试图预测新加坡的最低工资(如果我们有最低工资的话),并在一篇文章中记录了这个过程。如果你还没有读过,一定要看一看。
从那以后,我们收到了对我们的流程的评论和建议,以便更深入地了解我们的信息。因此,这篇后续文章概述了两个主要目标:发现数据中的意义,以及学习如何进行逐步回归。
上下文
在上一篇文章中,我们讨论了关于新加坡最低工资的话题是如何频繁地成为争论的热点。这是因为新加坡采用累进工资模式,因此没有最低工资。
新加坡政府的官方立场是,有竞争力的薪酬结构将激励劳动力努力工作,这与新加坡文化中根深蒂固的精英管理价值观是一致的。无论支持或反对新加坡最低工资的观点如何,穷人都在努力购买必需品,照顾自己和家人。
我们采取了一种中立的立场,承认双方论点的有效性,而是使用不同国家的某些指标对新加坡最低工资的预测进行了比较。预测的最低工资还与某些工作的累进工资模型(PWM)中的工资下限进行了对比,以引发一些关于最贫困者是否赚得足够多的讨论。
方法论
我们使用来自维基百科和世界数据的数据来收集关于最低工资、生活成本和生活质量的数据。生活质量数据集包括几个类别的分数:稳定性、权利、健康、安全、气候、成本和受欢迎程度。
所有指标和类别的分数都被输入一个线性回归模型,然后利用新加坡的统计数据作为独立变量来预测最低工资。这个线性模型是使用 sklearn 在 Python 上编码的,关于编码的更多细节可以在我们之前的文章中查看。然而,我也将在本文中简要概述建模和预测过程。
新加坡的预计年最低工资为 20,927.50 美元。下图中可以看到一个简单的对比。
新加坡的年最低工资约为 20,000 美元(图片来自作者)
我们的教授鼓励我们使用逐步回归来更好地理解我们的变量。从这个迭代中,我们结合了逐步回归来帮助我们降维,不仅产生一个更简单和更有效的模型,而且从我们的数据中获得洞察力。
逐步回归
那么到底什么是逐步回归呢?在任何一种现象中,都会有某些因素在决定一个结果中发挥更大的作用。简单来说,逐步回归是一个帮助确定哪些因素重要,哪些因素不重要的过程。某些变量具有相当高的 p 值,对我们预测的准确性没有有意义的贡献。在此基础上,只保留重要的因素,以确保线性模型根据有助于产生最准确结果的因素进行预测。
在这篇文章中,我将概述逐步回归的使用,它使用向后消除的方法。这是最初包含所有变量的地方,在每一步中,最不具统计意义的变量被丢弃。换句话说,最‘没用’的变量被踢了。重复这一过程,直到剩下的所有变量都具有统计显著性。
编码位
在继续分析回归模型之前,我们首先修改数据以反映月工资而不是年工资。这是因为我们认识到大多数人倾向于以月为单位而不是以全年为单位来看待他们的工资。以这种方式表达我们的数据可以让我们的受众更好地理解我们的数据。然而,还值得注意的是,这种规模的变化不会影响建模过程或结果。
查看我们之前的模型,我们生成了统计数据来测试模型的准确性。但在此之前,我们首先必须指定相关的 X 和 Y 列,并从数据文件中获取该信息。
## getting column names
x_columns = ["Workweek (hours)", "GDP per capita", "Cost of Living Index", "Stability", "Rights", "Health", "Safety", "Climate", "Costs", "Popularity"]
y = data["Monthly Nominal (USD)"]
接下来,为了收集模型统计数据,我们必须使用 statmodels.api 库。这里创建了一个函数,它从一个列表中获取感兴趣的列,然后用一个普通的最小二乘线性模型来拟合它。然后可以非常容易地打印出统计数据摘要。
## creating function to get model statistics
import numpy as np
import statsmodels.api as smdef get_stats():
x = data[x_columns]
results = sm.OLS(y, x).fit()
print(results.summary())get_stats()
原始回归统计数据(图片来自作者)
这里我们关注的是列“P > |t|”。本专栏引用了来自加州大学洛杉矶分校数字研究与教育研究所的一些技术解释,给出了用于检验零假设的双尾 p 值。
p 值小于α的系数在统计上是显著的。例如,如果您选择 alpha 为 0.05,则 p 值为 0.05 或更小的系数在统计上是显著的(即,您可以拒绝零假设,并说该系数与 0 显著不同)。”
换句话说,我们通常希望删除 p 值大于 0.05 的变量。从上面的初步总结中可以看出,统计学意义最小的变量是“安全性”, p 值为 0.968。因此,我们希望删除“安全”这一变量,如下所示。下面也显示了新的摘要。
x_columns.remove("Safety")
get_stats()
仅去除“安全”后的回归统计(图片来自作者)
这一次,新的统计意义最小的变量是“健康”。同样,我们也想去掉这个变量。
x_columns.remove("Health")
get_stats()
去除“安全”和“健康”后的回归统计(图片来自作者)
我们继续这个过程,直到所有的 p 值都低于 0.05。
x_columns.remove("Costs")
x_columns.remove("Climate")
x_columns.remove("Stability")
最后,我们发现还有 5 个变量,即工作周、人均 GDP、生活成本指数、权利和受欢迎程度。由于每个 p 值都低于 0.05,所有这些变量都被认为具有统计学意义。
我们现在可以根据这组新变量建立一个线性模型。我们也可以用这个来预测新加坡的最低工资。正如所见,预测的月最低工资约为 1774 美元。
## creating a linear model and prediction
x = data[x_columns]
linear_model = LinearRegression()
linear_model.fit(x, y)
sg_data = pd.read_csv('testing.csv')
x_test = sg_data[x_columns]
y_pred = linear_model.predict(x_test)
print("Prediction for Singapore is ", y_pred)>> Prediction for Singapore is [1774.45875071]
在数据中寻找意义
这是整个过程中最重要的部分。惠普(Hewlett-Packard)前首席执行官卡莉·菲奥莉娜(Carly Fiorina)曾经说过:“我们的目标是将数据转化为信息,将信息转化为洞察力。”这正是我们的目标。
“我们的目标是将数据转化为信息,将信息转化为洞察力.”
~卡莉·菲奥莉娜,惠普前首席执行官
仅从变量来看,我们就可以很容易地预测出哪些变量具有统计学意义。例如,人均国内生产总值和生活费用指数在逻辑上是一个国家最低工资的良好指标。甚至一周工作的小时数作为一个指标也是有意义的。
然而,我们注意到“权利”仍然包含在线性模型中。这促使我们首先来看看权利和最低工资之间的关系。在绘制图表时,我们发现了这种美学上令人愉悦的关系。
月最低工资侵犯权利(图片由作者提供)
最初,我们不会认为权利与最低工资相关,因为 GDP 和生活成本这两个更明显的候选因素在最低工资水平中的贡献更大。这让我们重新考虑我们如何理解最低工资,并迫使我们深入研究。
从世界数据来看,“权利”涉及公民权利,主要围绕人民参政和腐败。我们发现民权指数包括民众的民主参与和打击腐败的措施。该指数还包括公众对政府的看法,包括来自 Transparency.org 的数据。
“此外,其他因素包括人民的民主参与和(不太强调)反腐败措施。为了不仅评估反腐败措施,而且评估民众对反腐败的看法,还考虑了基于 Transparency.org 的腐败指数。”
这迫使我们考虑民权和最低工资之间的相互关系。了解了这些信息后,我们做了进一步的研究,找到了几篇可能解释这种相关性的文章。
美国民权利益集团——民权和人权领袖会议发布了一份报告,阐述了为什么最低工资是一个民权和人权问题,以及加强最低工资政策的必要性,以减少不平等,确保在低收入工作中挣扎的个人和家庭获得公平的报酬。因此,这是有道理的,因为一个民主参与程度更高的国家也可能对最低工资表示担忧,迫使人们展开讨论,并最终随着时间的推移提高最低工资。
我们研究的下一个变量是受欢迎程度。我们首先研究了如何从世界数据中衡量这一点。
“因此,总体移民率和外国游客数量被视为一个国家受欢迎程度的指标。较低的评级也被用来比较各自国家的难民状况。更多的外国难民导致更高的受欢迎程度,而大量逃离的难民降低了受欢迎程度。”
月最低工资对比人气(图片由作者提供)
乍一看,似乎没有任何关联。然而,如果我们将中国、法国、美国和西班牙视为异常值,大多数数据点似乎更符合指数图。这引发了两个问题。首先,为什么受欢迎程度和最低工资有关系?其次,为什么这四个国家是离群值?
老实说,这难倒了我们。我们根本看不出受欢迎程度与最低工资有什么关联。然而,有一点很重要:在预测一个国家的最低工资时,这种受欢迎程度在某种程度上具有统计学意义。虽然我们可能不是发现这种关系的人,但这让我们深入了解了我们原本意义不大的数据。
结论
引用卡莉·菲奥莉娜的话很重要,“我们的目标是将数据转化为信息,将信息转化为洞察力。”作为人类,我们需要工具和方法将数据转化为信息,需要经验/知识将信息转化为洞察力。
我们首先使用 Python 作为工具,执行逐步回归来理解原始数据。这让我们不仅发现了我们预测到的信息,还发现了我们最初没有考虑到的新信息。很容易猜测工作周、GDP 和生活成本将是最低工资的有力指标。然而,只有通过回归,我们才发现民权和受欢迎程度也具有统计意义。
在这种情况下,我们发现网上有研究可以解释这些信息。这导致了新的见解,即最低工资实际上被视为一项人权,民主参与的增加可能会导致更多关于最低工资的讨论,从而提高最低工资。
然而,并不总是能够那么容易地发现数据中的意义。不幸的是,作为大学生,我们可能不是为我们的信息提供可能解释的最佳人选。这可以从我们试图解释受欢迎程度和最低工资之间的关系中看出。然而,我们有能力获取这些信息并将其传播到世界各地,让它成为一个开放的问题进行讨论。
这就是我们如何利用数据为世界增加价值。
- 与 Erika Medina 合作撰写