“闭门造车”之多模态思路浅谈:自回归学习与生成

c8151d87cc3ebfd9b3c0525b20ed2b97.gif

©PaperWeekly 原创 · 作者 | 苏剑林

单位 | 科学空间

研究方向 | NLP、神经网络

这篇文章我们继续来闭门造车,分享一下笔者最近对多模态学习的一些新理解。

在前文《“闭门造车”之多模态思路浅谈:无损》中,我们强调了无损输入对于理想的多模型模态的重要性。如果这个观点成立,那么当前基于 VQ-VAE、VQ-GAN 等将图像离散化的主流思路就存在能力瓶颈,因为只需要简单计算一下信息熵就可以表明离散化必然会有严重的信息损失,所以更有前景或者说更长远的方案应该是输入连续型特征,比如直接将图像的原始像素特征 Patchify 后输入到模型中。

然而,连续型输入对于图像理解自然简单,但对图像生成来说则引入了额外的困难,因为非离散化无法直接套用文本的自回归框架,多少都要加入一些新内容如扩散,这就引出了本文的主题——如何进行多模态的自回归学习与生成。当然,非离散化只是表面的困难,更艰巨的部份还在后头。

ad787762c93505380c0627250d37a5fb.png

无损含义

首先我们再来明确一下无损的含义。无损并不是指整个计算过程中一丁点损失都不能有,这不现实,也不符合我们所理解的深度学习的要义——在 2015 年的文章《闲聊:神经网络与深度学习》[1] 我们就提到过,深度学习成功的关键是信息损失。所以,这里无损的含义很简单,单纯是希望作为模型的输入来说尽可能无损。

当前多模态模型的主流架构依然是 Transformer,很多工作都会先对图像进行“前处理”再输入到 Transformer 中,比如简单将图像 Pixels 分 Patch、通过 VAE 来提取特征或者通过 VQ 来离散化等,其共同特点是将图像从 的数组变成 (其中 )的数组,我们都可以称为广义的 “Patchify”。

不同的 Patchify 可能会有不同程度的信息损失,其中 VQ 的信息损失往往是最严重且最明确的,比如最近字节的 TiTok [2] 将 256*256 的图像压缩为 32 个 token,要理解它的信息损失都不用算信息熵,因为它的编码本只有 4096,意味着它顶多能存 张图片,我们知道汉字就不止 4096 个了,换句话说如果图上有 32 个汉字,那么所有排列组合就超出了这种编码方式能表达的上限。

如果图像在输入模型之前就有明显信息损失,那么必然会限制模型的图像理解能力,比如将 TiTok 的 32 个 Token 输入到模型中,那么它基本就没法做 OCR 任务了,而且 VQ 的这个瓶颈非常本质,即使改为 32*32 个 Token 也很难有明显的改善,除非 Token 的数量达到了原始 RGB 的 Pixels 数量级,但这样一来 VQ 的意义也就没有了。

所以,为了更好地适应各种图像理解任务,多模态模型理想的图像输入方式应该就是尽可能无损的连续型特征,由模型自己在计算过程中根据上下文决定要损失什么。

29f0e343e0559a71384710a3788b5f2b.png

自回归式

正如本文开头所说,以连续型特征输入对于图像理解来说其实是一个非常合理和自然的方式,只是对于图像的自回归(AutoRegressive,AR)生成来说会引入额外的困难。看到这里读者可能会有一个疑问:为什么图像非得要做自回归?图像不是有扩散模型这样的更好用的生成方式了吗?

首先,我们知道,“自回归模型 + Teacher Forcing 训练”本身就是一种非常普适的学习途径,是“手把手教学”的典型体现,所以它潜力是足够的;其次,扩散模型这个例子,更加说明了自回归在图像生成中的必要性。

以 DDPM 为例,它实质就是一个自回归模型,在《生成扩散模型漫谈:DDPM = 自回归式VAE》我们就将其冠以自回归之名,它将单个图像解构为序列 ,然后去建模 ,训练方式本质上也是 Teacher Forcing(所以也有 Exposure Bias 问题),可以说 DDPM 不仅是自回归,而且还只是自回归中最简单的 2-gram 模型。

事实上,从早期的 PixelRNN [3]、PixelCNN [4]、NVAE [5] 等工作,到如今流行的扩散模型以及将图像 VQ 之后当文本那样训练语言模型,它们传递出来的信号更多的是——对于图像来说,问题并不是该不该做自回归,而是以何种方式来更好地去做自回归。它的作用不仅是为多模态模型赋予图像生成能力,而且还是一个重要的无监督学习途径。

笔者的偶像 Feynman 说过一句著名的话 “What I cannot create, I do not understand”,这句话放到大模型也是成立的,也就是说“不会生成就不会理解”。当然,这句话看上去有点武断,因为通过有监督学习各种图文数据对似乎也能获得足够的图像理解能力。

然而,单纯通过有监督的方式去学习图像理解,一方面覆盖面可能有限,另一方面也受限于人的理解水平,所以我们需要无监督的生成式预训练来获得更充分的图像理解能力,这跟文本的 “Pretrain + SFT” 的 Pipeline 是一致的。

38349563ac84c758b829f52822dcb4ce.png

平方误差

可能有部份读者觉得,将图像分 Patch 排序后,不也就可以跟文本一样预测下一个 Patch 吗?就算输入格式不离散化而是改为连续特征,那也只需要把交叉熵损失换成平方误差就行了?看上去图像的自回归学习也没有什么困难?思路上确实如此,但事实上这里边提到的两个关键地方——“分 Patch 排序“损失函数”——都是难以解决的问题。

这一节我们先来看损失函数问题。假设图像已经按某种方式分 Patch 排序好,那么图像就变成了 Patch 的一维序列,自回归学习也确实是对下一个 Patch 的预测,如下图所示:

eec9acf9a4163a4ef473126acc75c758.png

▲ 图像自回归学习的最朴素想法是用平方误差预测下一个 Patch

然而,这里的损失函数却没法简单地用平方误差(MSE,或者等价地,欧氏距离,L2 距离),这是因为平方误差背后的关于分布的假设是高斯分布:

b918e75b9b02bc394d2e2dd39335ff94.png

即高斯分布 的负对数似然正好是平方误差(其中 是常数),这意味着用平方误差的话对 的假设为 ,但我们仔细想想就会发现,这个假设跟真实情况还是相距甚远的,因为如果它成立,那么通过 就可以完成 的采样,其实 是标准高斯分布的噪声,那么 必然会有很多噪点,而真实情况显然未必如此。

可能又有读者反驳:为什么非得要从概率似然的角度来理解呢?我就纯粹将它理解为一个回归拟合问题不行吗?可能真的不大行。从概率角度理解主要有两方面的考虑:

第一,生成建模最终都要面临采样,写出概率分布才能构建采样方式;

第二,单纯从回归的角度来看,我们也需要论证平方误差的合理性,因为我们还有很多其他损失可以用,比如 L1 距离(MAE)、Hinge Loss 等等,这些损失并不相互等价,也不尽合理(事实上,这些损失都不合理,因为它们都是从纯数学角度定义出来的度量,跟人类视觉认知并不完全吻合)。

4c06e6fcc2677fcd4c28ac61b8d88d37.png

噪声之奇

由于是输入的图片特征本质决定了平方误差的不合理性,所以解决这个问题的唯一思路就是修改图片的输入格式,使得它相应的条件分布更符合高斯分布。目前看来,有两个具体的方案可以参考。

第一个方案是通过预训练的 Encoder 来编码图片,其中训练 Encoder 时通常会加入 VAE 的 KL 散度等正则项来缩小方差,说得更直观一点,就是将特征都压缩在一个球附近(参考《从几何视角来理解VAE的尝试》[6]),用这些特征作为图像的输入,会使得 是高斯分布的假设更加合理一些,所以我们可以用平方误差来自回归训练,训练完之后,我们还需要另外训一个 Decoder,来将采样出来的图片特征解码为一张图片。这大体上就是 Emu2 [7] 所采用的方案,缺点是 Pipeline 看起来太长,不够端到端。

第二个方案可能会出乎很多人意料,那就是加噪,这是笔者闭门造车的想法。刚才我们说如果 真的是高斯分布,那么直观来看 应该有很多噪点才对,但事实上没有。那为了满足这个条件,我们自己加一些噪声不就行了?加了噪声也不一定能让 变成高斯分布,但可以让它更接近,尤其是当我们渐进地加噪声的时候,如下图所示

a443c0260b36ff450e70c465234ff557.png

▲ 通过加噪拓展每个 Patch,让平方误差成为可行的损失函数

了解扩散模型的读者不难想到,通过加噪来构建渐变序列,然后以平方误差为损失来训练递归去噪模型,这不就是扩散模型吗?没错,扩散模型的核心思想正是“通过渐进式加噪让平方误差成为合理的损失函数”,而上述方案也是借用了这一思想。

当然,跟常规扩散模型的不同之处也是很明显的,比如扩散模型是对整张图片加噪,这里是对 Patch 加噪,扩散模型是建模 ,这里是建模 ,等等。从最终形式上来看,这里提出的是一种结合扩散模型来进行图像的自回归学习的方案。

cb4e5409fc1502809b49fc868e91b8eb.png

效率问题

通过加噪来延长序列,使得朴素的平方误差可用,从而让图像的自回归学习跟我们开始构思的方案基本一致(就只是输入多了一步加噪),这无疑是一个非常让人舒适的结果。然而,事情并没有那么乐观,这个方案至少有两大问题,这两个问题也可以概括为同一个词——效率。

第一,是学习效率问题。这个问题我们在第一篇介绍扩散模型的文章《生成扩散模型漫谈:DDPM = 拆楼 + 建楼》就已经讨论过了,大致意思就是这种 时刻的加噪图预测 时刻的加噪图的训练目标,需要对噪声进行双重采样,这会导致更大的训练方差,因此需要更多的训练步数才能把这个方差降下来,而经过一系列降方差技巧后,我们发现更高效的方式是直接预测原图(或者等价地,预测它与原图的差):

04016bca891134f1ac1507f790ed1d68.png

▲ 相比预测下一步噪声图,直接预测原图效率更高

可能有读者不能理解,刚刚不才说原图没有噪点不符合高斯分布,不能用平方误差为损失吗?这个问题还真不大容易从直观上来解释,我们可以理解为这是高斯分布的一个巧合,这时候平方误差还是可以用的,更标准的解释可以参考《生成扩散模型漫谈:DDPM = 贝叶斯 + 去噪》、《生成扩散模型漫谈:DDIM = 高观点DDPM》这两篇。

第二,是计算效率问题。这个其实很好理解,假如每个 Patch 通过加噪变成 T 个 Patch,那么序列长度就变为原来的 T 倍,这样一来训练成本和推理成本都会显著增加。此外,从理论上来说,加噪的 Patch 对图像理解并无实质帮助,只保留没加噪的那个干净 Patch 原则上也能达到同样的效果,换句话说,这种方案对于图像理解来说存在大量冗余的输入和计算量。

解决这个问题同样有两个思路,下面我们逐一介绍。

6777a748aeaef2753ca69ebd401dc38f.png

分离扩散 

如果限定必须在单个 Transformer 内解决的话,我们可以考虑给 Attention 加 Mask,这又包括两部分:1)扩散模型的理论和实践告诉我们,要预测 的话只用 就够了,可以忽略更早的输入,这意味同一个 Patch 的不同加噪结果之间不需要相互 Attend;2)出于减少冗余的考虑,对于不同 Patch 之间的预测以及后面文本 Token 的预测,我们只需要 Attend 到没加噪的 Patch。这就形成了大致如下的 Attention Mask:

ad8d32c5927a3dd2e24e101865beca54.png

▲ 出于简化模型和去冗余的考虑所设计的 Attention Mask

由于这种 Attention Mask 具有固定的 Sparse Pattern,所以它有很大的提速空间,并且由于带噪的 Patch 的注意力是独立的,因此我们训练时也不必一次性把 T−1 个带噪 Patch 都算进去,每次采样一部份计算就行。当然,这顶多只算一个雏形,实践中还有一些细节需要仔细斟酌一下,比如加噪的 Patch 之间基本没有关联,那么它们的位置编码需要单独设计一下,等等,这里就不展开讨论了。

如果允许两个不同的模型串联(但仍然可以端到端训练),那么我们还可以把扩散模型单独分离出来,Transformer 只负责处理没有噪声的 Patch,Transformer 的输出则作为扩散模型的条件,如下图所示:

13037f18657e39527c75fe10e06e7a1d.png

▲ 将扩散模型分离出来,Transformer 的输出作为扩散的输入条件

这大体上就是 Kaiming 的新工作《Autoregressive Image Generation without Vector Quantization》[8] 所提的方案,但它更早在《Denoising Autoregressive Representation Learning》[9] 就已经被提出,其好处是让 Transformer 部份更加纯粹和优雅,同时也可以起到节省计算量的作用,这是因为 1)单独分离出来的扩散模型可以做得更小一些;2)扩散模型部份我们可以按照常规的训练策略每次只采样一个噪声步计算。

从损失函数的角度来看,它就是利用了一个额外的扩散模型来作为预测下一个 Patch 的损失,从而解决平方误差的缺点。

60a88164646f00571e111a5cb1f613ad.png

生成方向

前面我们提到图像的自回归学习的两个关键之处分别是“分 Patch 排序”和“损失函数”,刚才我们花了四个小节勉强把损失函数这一块稍微捋顺了一下,但这只能算是刚刚摸到了门槛。然而,接下来我们将会发现一个更让人悲观的结果——对于“分 Patch 排序”这个问题,我们连门槛都很难摸到。

从最终目标来看,“分 Patch 排序”是为了给自回归学习制定一个生成序列和方向,它分为“分 Patch” 和“排序”两步。“分 Patch” 我们也称 “Patchify”,狭义的 Patchify 就是对像素数组的简单变形和转置,即将 的数组先变形为 ,然后转置为 ,最后变形为 。

但广义来说,Patchify 可以泛指一切将图像从 的数组变成 (其中 )的数组的方案,比如 Stable Diffusion 的 Encoder 将图像编码为 Latent、各种 VQ-Tokenizer 将图像变成离散的 ID,这些都算是广义的 Patchify。

“排序”就比较好理解了,我们知道图像有“长”和“宽”两个方向(维度),大部份 Patchify 方法的输出特征依然保留了这个二维性质,而自回归生成则是单向的,所以需要指定一个生成顺序。常见的顺序比如 1)从左往右再从上往下;2)从中心到四周螺旋;3)从左上角出发走 “Z” 字等等,这些排序设计由来已久,它们可以追溯到第一代图像自回归模型——直接在图像 Pixels 上做的自回归模型,即前面提到的 PixelRNN / PixelCNN 等。

98c10df820bab444c5cba8dddf5f51ab.png

▲ 朴素的 Patchify 和两种不同的排序方式

总的来说,“分 Patch 排序”是将图像解构为一个可供自回归学习的一维序列的过程,更通俗点就是将图像从二维序列转成一维序列,所以从最最广义的角度来讲,扩散模型来构建的不同噪声强度的带噪图片序列,以及《Visual Autoregressive Modeling: Scalable Image Generation via Next-Scale Prediction》[10] 多个 scale 构成的序列,都可以归入此列。

所以,现在我们已经提到了多种解构图像的方案,那么很自然的问题就是:哪个方案更好?判断依据是什么呢?

e2ee8ed05fa73e856d2182c4f4f07e0d.png

世界模型

要回答这个问题,我们首先要搞清楚,图像生成或者说视觉生成的本质难度是什么。在《“闭门造车”之多模态思路浅谈:无损》中,我们简单提到图像生成的困难在于连续型概率建模的困难,但实际上这是一个非常表面的判断,如果仅仅是这样的话,那么情况就乐观得多了,因为我们已经发展了不少诸如扩散模型的连续型生成模型,但实际上其中的困难比我们想象的更为深远...

我们所说的图像,大体上可以分为人类创造的图片以及相机拍摄的照片两种,在相机、手机普及之后,互联网上的图像实际上已经以照片为主,所以图像生成基本上也等价于照片生成。照片是什么呢?它是光的记录,是三维世界的光在二维平面的投影。那光又是什么呢?光是电磁波,电磁波是麦克斯韦方程组(Maxwell's equations)[11] 的解!

从这个思考中我们发现一个不可否认的事实:一张真实的自然照片,它本质上就是麦克斯韦方程组的一个解,这也就意味着,完美的图像生成不可避免地要触碰到物理定律——众多理论物理学家孜孜不倦地追求的世界本源!

无独有偶,在 Sora 出现之后,我们经常会用“是否符合真实世界的物理规律”来评价模型生成的视频质量,实际上看似更加简单图片生成,同样可以有“符合物理规律”这个评价维度,比如图片上的光影分布规律等,只不过到了视频这里,在光学(电磁学)的基础上多了一个动力学。

沿着这个思维链头脑风暴下去,会越来越让人觉得震撼甚至惊悚,因为这等价于说完美的视觉生成模型实际上就是在数值模拟各种物理定律,或者更夸张地说,它实际在模拟整个世界、整个宇宙的演化,它本质上就是一个世界模型。这已经不是地狱级难度可以形容的了,这简直就是创世级难度。

可能有读者质疑:麦克斯韦方程组是难,但不也被人类发现了?我们还发现了更多更难的物理规律,比如量子力学、广义相对论等等,并且还在不断逼近终极定律(大统一理论),所以这件事情的难度似乎没有那么高?

不,大家不要混淆了,即便我们真的能够发现完全正确的物理定律,那跟有能力“用这些定律去数值模拟”是两回事。比如我们能手写出一个方程,但未必能通过手算去求解它,所以我们能发现物理规律,不代表我们能利用这些物理规律去推演或者模拟真实世界,更具体一点,我们现在能在这里说照片的本质就是麦克斯韦方程组的一个解,但没有谁能够手绘一张照片出来。

(注:以上的一系列思考,起源于“图像本质是麦克斯韦方程组的一个解”,这是在一次技术交流中我的 leader 周昕宇分享给我的,当我第一次听到这个看上去荒谬但事实上不得不接受的观点时,我内心是错愕且震撼的,霎时间有种明悟了多模态模型的本质困难的感觉。)

18cfed57c2bcab74de7fc1625c091119.png

人价值观

总的来说,这个头脑风暴想要表达的观点就是,一个完美的视觉生成模型,它是一个真正意义上的世界模型,它的难度可谓是创世级别的。那么我们想要创世吗?我们有能力创世吗?

笔者认为在可以想象的时间内,答案都是否定的,毕竟那意味着要以人力跟全宇宙对抗的感觉了。所以这里的关键就是放弃“完美”这个概念,就好比人不能手绘出一张照片,但这依然不影响人作画,也不影响人通过手绘的方式来传递信息。又比如说我们评价模型生成的视频是否符合物理规律,并非真的是测量了视频的轨迹然后代入物理公式来判断的,而单纯是肉眼目测加上我们对物理规律的直观感知。

说白了,可以有损,但对人的价值观无损就行了。那这跟前面说的“分 Patch 排序”又有什么关系呢?我们一开始就说了,自回归学习不单是要为模型赋予生成能力,同时也是作为一种无监督学习途径,来提高模型的理解能力(不会生成就不会理解)。如果我们有一个真正无限拟合能力(创世能力)的模型,那么所有的“分 Patch 排序”都是等价的,因为精确的联合分布不依赖于随机变量的分解方式。但很遗憾我们没有,那么我们只能有所取舍。

注意,我们希望通过学习生成来促进理解,这里的“理解”必然是要对齐人的视觉理解的,这是我们训练 AI 的目的。然而,前面列举出来的一些“分 Patch 排序”方式,没有一种是符合人的视觉理解方式的。

更直接地说,人对图片的理解并不是从左往右或者从上往下,也不是从中间到四周还是走 “Z” 字,甚至说人理解图像都不是按照 Patch 为单位的,当然也不是 Diffusion 那样逐渐加噪的方式。

如果我们用已有的各种“分 Patch 排序”方案去做自回归学习,确实有机会赋予模型在一定范围内的视觉生成能力,但由于这些图片解构方式本质上都不符合人的视觉理解模式,那么很难认为这种自回归学习可以促进模型的视觉理解能力——更准确地说,是很难促进模型模仿人视觉理解的能力。

造成这个困难的主要原因,是因为图像它是一个“结果”,并不包含“过程”。就拿人类创作的图像来说,不管是手绘的还是 PS 的,其过程都是一步一步操作的,但最终呈现出来的是一张掩盖了它创作过程的图像。

这跟文字不一样,我们虽然不知道作家是怎么构思出这段文字的,但我们知道大部份人都是从左往右写字的,所以文字本身就已经包含了它的创作(书写)过程,但如果是一幅画呢?看了一幅画,我们知道画家先画哪一块、哪一笔吗?显然不行,这也是为什么大部份人都会写字但无法临摹一幅画。更深一步想,这可以理解为人类似乎更擅长沿着时间维度模仿,而不擅长沿着空间维度,因为时间维度只有一个,空间维度却有三个,后者自由度太大。

目前看来,就只有一个非常“妥协”的方法来解决这个问题,就是用尽可能多的、符合人类价值观的图文数据(当然,图像的其他有价值的监督信号也可以),去有监督地训练一个“分 Patch 排序”模型。注意跟常见的 Vision Encoder 不同,这个模型要直接输出一维序列,而不是保留图片的二维性,这样就免去了事后排序这一步。

模型的设计我们可以参考 TiTok [2](这是我们第三次提到 TiTok了),它本质上是利用 Cross Attention 将二维序列转一维序列,除此之外用 Q-Former [12] 也能实现类似的效果。总之,模型设计上不会有太多难度,核心工作变成了图文对的数据工程了。

但这样一来,模型能走多远就不好说了,因为我们本希望通过自回归学习来促进模型的理解能力,但现在自回归学习又依赖于一个通过理解任务训练出来的 Encoder,理想情况下这两个模型会相互促进、共同进化,但不理想的情况下模型能力就受限于训练 Encoder 的有监督数据的数量和质量,无法形成真正的无监督学习了。

20d9896c5c47c45fa1617eb3d43f9de3.png

文章小结

这篇文章继续“闭门造车”了一些有关多模态学习的思路,主要围绕视觉的自回归学习进行展开,大体内容是:

1. 自回归学习既为模型赋予了生成能力,同时也是通过生成来促进理解能力的无监督学习途径;

2. 对于图像来说,问题不在于要不要做自回归,而是以何种方式才能更好地做自回归;

3. 将图像以连续型特征的方式输入时,它的自回归学习有两大难题:分 Patch 排序和损失函数;

4. 损失函数不能简单用平方误差,而是可以考虑后面接一个小型的扩散模型来预测下一个 Patch;

5. “分 Patch 排序”是图像自回归学习的根本难题,它的选择关系到自回归学习能否真正促进理解;

6. 完美的图像/视觉生成,不可避免要跟物理规律建立联系,从而构成“世界模型”;

7. 但世界模型难以实现,所以选择跟人类价值观相符的“分 Patch 排序”方式尤为重要;

8. 最后,看上去只能“妥协”地通过有监督学习来获得一个对齐人类价值观的“分 Patch 排序”模型。

这里边可能有不少“暴论”和“谬论”,请读者自行甄别和海涵。将这些思考写下来的主要目的,是为了未来的某一天再回过头来看看,自己当初的想法有几分可行,又有几分可笑。

outside_default.png

参考文献

outside_default.png

[1] https://kexue.fm/archives/3331

[2] https://papers.cool/arxiv/2406.07550

[3] https://papers.cool/arxiv/1601.06759

[4] https://papers.cool/arxiv/1606.05328

[5] https://kexue.fm/archives/7574

[6] https://kexue.fm/archives/7725

[7] https://papers.cool/arxiv/2312.13286

[8] https://papers.cool/arxiv/2406.11838

[9] https://papers.cool/arxiv/2403.05196

[10] https://papers.cool/arxiv/2404.02905

[11] https://en.wikipedia.org/wiki/Maxwell%27s_equations

[12] https://papers.cool/arxiv/2301.12597

更多阅读

5fed8d1073f735abd400e4f0ac765661.png

3ad591c4c6d01221a3815911816ce518.png

cd699392482e28f4cad1b5b35433e621.png

c6b208e8bfeaf23c499c68e181a637b5.gif

#投 稿 通 道#

 让你的文字被更多人看到 

如何才能让更多的优质内容以更短路径到达读者群体,缩短读者寻找优质内容的成本呢?答案就是:你不认识的人。

总有一些你不认识的人,知道你想知道的东西。PaperWeekly 或许可以成为一座桥梁,促使不同背景、不同方向的学者和学术灵感相互碰撞,迸发出更多的可能性。 

PaperWeekly 鼓励高校实验室或个人,在我们的平台上分享各类优质内容,可以是最新论文解读,也可以是学术热点剖析科研心得竞赛经验讲解等。我们的目的只有一个,让知识真正流动起来。

📝 稿件基本要求:

• 文章确系个人原创作品,未曾在公开渠道发表,如为其他平台已发表或待发表的文章,请明确标注 

• 稿件建议以 markdown 格式撰写,文中配图以附件形式发送,要求图片清晰,无版权问题

• PaperWeekly 尊重原作者署名权,并将为每篇被采纳的原创首发稿件,提供业内具有竞争力稿酬,具体依据文章阅读量和文章质量阶梯制结算

📬 投稿通道:

• 投稿邮箱:hr@paperweekly.site 

• 来稿请备注即时联系方式(微信),以便我们在稿件选用的第一时间联系作者

• 您也可以直接添加小编微信(pwbot02)快速投稿,备注:姓名-投稿

4f7c9bb3e00dcfc12daf7a24d71e4f30.png

△长按添加PaperWeekly小编

🔍

现在,在「知乎」也能找到我们了

进入知乎首页搜索「PaperWeekly」

点击「关注」订阅我们的专栏吧

·

·

·

7e322a42ff2a6a3f58d5cb00cf55b0d9.jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/375097.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mac生成.dmg压缩镜像文件

mac生成.dmg压缩镜像文件 背景准备内容步骤1,找一个文件夹2,制作application替身1,终端方式2,黄金右手方式 3,.app文件放入文件夹4,制作.dmg压缩镜像文件5,安装.dmg 总结 背景 为绕开App Store…

Go语言---并发编程之channel(双channel,单channel)以及应用实例(生产者消费者、打印机模型)

Channel goroutine 运行在相同的地址空间,因此访问共享内存必须做好同步。goroutine 通过通信来共享内存,而不是其享内存来通信。 引用类型 channel 是CSP 模式的具体实现,用于多个 goroutine 通讯。其内部实现了同步,确保并发安全。 chan…

FastAPI 学习之路(三十四)数据库多表操作

之前我们分享的是基于单个表的数据库表的操作,我们在设计数据库的时候也设计了跨表,我们可以看下数据库的设计 class User(Base):__tablename__ "users"id Column(Integer, primary_keyTrue, indexTrue)email Column(String(10), uniqueTr…

Python:Python基础知识(注释、命名、数据类型、运算符)

.注释 Python有两种注释方法:单行注释和多行注释。单行注释以#开头,多行注释以三个单引号 或三个双引号 """ 开头和结尾。 2.命名规则 命名规则: 大小写字母、数字、下划线和汉字等字符及组合; 注意事项: 大小写敏感、首…

ESP32FreeRTOS开发笔记:1.双核并行

ESP32 的 Arduino 框架内部集成了 FreeRTOS,允许开发者利用其多任务处理功能。在代码中,xTaskCreatePinnedToCore 函数是 FreeRTOS 提供的 API,用于创建任务并指定任务在哪个核心上运行。 FreeRTOS 是一个流行的实时操作系统内核,…

JavaSE学习笔记之内部类、枚举类和基本类型包装类

今天我们继续复习Java相关的知识,和大家分享有关内部类等方面的知识,希望大家喜欢。 目录​​​​​​​ 内部类 成员内部类 ​编辑 静态内部类 局部内部类 匿名内部类 枚举类 定义方法 基本类型包装类 自动装箱和拆箱 内部类 成员内部类 成…

《Windows API每日一练》9.1.5 自定义资源

自定义资源(Custom Resources)是在 Windows 程序中使用的一种资源类型,用于存储应用程序特定的数据、图像、音频、二进制文件等。通过自定义资源,开发者可以将应用程序所需的各种资源文件集中管理和存储,便于在程序中访…

从人工巡检到智能预警:视频AI智能监控技术在水库/河湖/水利防汛抗洪中的应用

一、背景需求分析 近日,我国多省市遭遇连日暴雨,导致水库、湖泊、河道等水域水位暴涨,城市内涝频发。随着夏季汛期的到来,降雨天气频繁,水利安全管理面临严峻挑战。为保障水库安全、预防和减少洪涝灾害,采…

文档去重(TF-IDF,MinHash, SimHash)

2个doc有些相似有些不相似,如何衡量这个相似度; 直接用Jaccard距离,计算量太大 TF-IDF: TF*IDF TF:该词在该文档中的出现次数, IDF:该词在所有文档中的多少个文档出现是DF,lg(N/(1DF)) MinHash …

windows上修改redis端口号

概况 redis是一个开源的内存数据结构存储系统,常用做数据库、缓存和消息代理。默认的端口号为6379 更改redis端口号步骤如下 先停止redis服务 redis-cli shutdowm 打开redis配置文件 在redis安装目录下,即redis.windows.conf文件。 port 6396 然后…

i18n、L10n、G11N 和 T9N 的含义

注:机翻,未校对。 Looking into localization for the first time can be terrifying, if only due to all of the abbreviations. But the meaning of i18n, L10n, G11N, and T9N, are all very easy to understand. 第一次研究本地化可能会很可怕&…

NI VST 毫米波测试仪器创新

目录 概览​从UHF至V频段的频率覆盖范围:54 GHz远程测量模块​PXIe-5842:VST架构的扩展54 GHz扩频PXIe-5842功能​​宽频覆盖范围​IF和毫米波测试端口可满足多频带需求​高达2 GHz瞬时带宽误差矢量幅度测量性能相位相干同步基于PXI平台集成多种仪器 互补…

Jmeter多用户登录操作实战

在使用Jmeter性能测试时,首先要解决的问题恐怕就会并发压测和多用登录的问题.今天就一篇文章讲清楚这两个问题的解决方案: 一.多并发压测如何配置线程? (1)同时并发:设置线程组、执行时间、循环次数,这种方式可以控制接口请求的…

01表操作/数类型定义

文章目录 表操作表的创建列的类型定义整数类型浮点类型和定点数类型日期和时间类型 表操作 表的创建 列的类型定义 整数类型 浮点类型和定点数类型 日期和时间类型

探索【Python面向对象】编程:新时代的高级编程范式详解

目录 1. 面向对象编程概念(OOP) 1.1 什么是类和对象? 1.2 类的定义 1.3 类和对象的关系 1.4 小李的理解 2. 抽象 2.1 抽象的概念 2.2 抽象类和方法 2.3 小李的理解 3. 类和实例 3.1 类的定义和实例化 3.2 类的属性和方法 3.3 小…

【Android】基于 LocationManager 原生实现定位打卡

目录 前言一、实现效果二、定位原理三、具体实现1. 获取权限2. 页面绘制3. 获取经纬度4. 方法调用5. 坐标转换6. 距离计算7. 完整代码 前言 最近公司有个新需求,想要用定位进行考勤打卡,在距离打卡地一定范围内才可以进行打卡。本文将借鉴 RxTool 的 Rx…

【安全设备】入侵检测

一、什么是入侵检测 入侵检测是一种网络安全技术,用于监测和识别对计算机系统或网络的恶意使用行为或未经授权的访问。入侵检测系统(IDS)是实现这一目标的技术手段,其主要目的是确保计算机系统的安全,通过及时发现并报…

蜂窝互联网接入:连接世界的无缝体验

通过Wi—Fi,人们可以方便地接入互联网,但无线局域网的覆盖范围通常只有10~100m。当我们携带笔记本电脑在外面四处移动时,并不是在所有地方都能找到可接入互联网的Wi—Fi热点,这时候蜂窝移动通信系统可以为我们提供广域…

Lingo学习(三)——工厂合并、运算符、内置函数

一、工厂合并 (一) 工厂合并——生产二维矩阵 【引入】 sets: factory /1..6/ : a; plant /1..8/ : d; Cooperation(factory,p lant) : c, x; endsets 以上程序可…

Ubuntu编译PX4固件

目录 前言 准备编译参考 前言 要想自己编译PX4固件需要交叉编译器,交叉编译器可以将 x86架构 平台上写好程序编译出来,而编译出来的可执行文件是能用到 arm架构 的平台上。 本次编译是以 px4 v1.13.2 为例。 我的配置如下: 虚拟机 Ubuntu 18…