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

news2024/11/15 21:51:29

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.coloradmin.cn/o/1920434.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

压缩文件的解析方式

我们常用的压缩文件有两种:后缀为.zip或者.rar,接下来将介绍解析两种压缩文件的代码。需要用到三个jar包:commons-io-2.16.1.jar、junrar-7.5.5.jar、slf4j-api-2.0.13.jar,可以在官网下载,也可以发私信。 这段代码是一…

2.GAP:通用访问协议

GAP的简单理解 GAP这个名字,直接翻译过来不好理解。 简单点可以理解为: 这是蓝牙设备在互联之前,过程中,第一个用于交流的协议。在代码上,会给这个协议实现,连接参数的设置,连接事件的实现&am…

【算法】二叉树-迭代法实现前后中序遍历

递归的实现就是:每一次递归调用都会把函数的局部变量,参数值和返回地址等压入调用栈中,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,这就是递归为什么可以返回上一层位置的原因 可以用栈实现二叉树的前中后序遍历 1. 前序…

【数学趣】拉窗帘模型之求面积引发的6个解法

抖音上推了一个趣题 题 求橙色部分的面积 蓝色部分是2个正方形。大的正方形边长为6。(小的正方形一半被一个黄色三角形遮住了一半) 答案 18 解法1:拉窗帘 先写一个代号,方便证明,H G 代表正方形。(G…

AV1 编码标准中帧内预测技术详细说明

AV1 编码标准帧内预测 AV1(AOMedia Video 1)是一种开源的视频编码格式,旨在提供比现有标准更高的压缩效率和更好的视频质量。在帧内预测方面,AV1相较于其前身VP9和其他编解码标准,如H.264/AVC和H.265/HEVC,…

暑假第一次作业

第一步:给R1,R2,R3,R4配IP [R1-GigabitEthernet0/0/0]ip address 192.168.1.1 24 [R1-Serial4/0/0]ip address 15.0.0.1 24 [R2-GigabitEthernet0/0/0]ip address 192.168.2.1 24 [R2-Serial4/0/0]ip address 25.0.0.1 24 [R3-GigabitEthernet0/0/0]ip address 192.…

【Mutilism用74ls192和与非门设计3进制24进制加法计数器2荔枝】2022-5-10

缘由【数电 数字逻辑】如何用74ls192和与非门设计任意进制加法计数器?-嵌入式-CSDN问答

Qt学生管理系统(付源码)

Qt学生管理系统 一、前言1.1 项目介绍1.2 项目目标 2、需求说明2.1 功能性说明2.2 非功能性说明 三、UX设计3.1 登录界面3.2 学生数据展示3.3 信息插入和更新 三、架构说明3.1 客户端结构如下3.2 数据流程图3.2.1 数据管理3.2.2 管理员登录 四、 设计说明3.1 数据库设计3.2 结构…

基于Python+Flask+MySQL的新冠疫情可视化系统

基于PythonFlaskMySQL的新冠疫情可视化系统 FlaskMySQL 基于PythonFlaskMySQL的新冠疫情可视化系统 项目主要依赖前端:layui,Echart,后端主要是Flask,系统的主要支持登录注册,Ecahrt构建可视化图,可更换主…

Qt 统计图编程

学习目标:Qt 折线图,柱形图和扇形统计图编程 学习基础 Qt QChart 曲线图表操作-CSDN博客 学习内容 Qt中绘制三种常见的图表非常方便, 主要步骤如下: 1. 折线图: - 使用QLineSeries定义折线数据,添加多个坐标点 - 使用QValueAxis创建X轴和Y轴 - 将…

数据结构——查找算法

文章目录 1. 查找算法 2. 顺序查找 2. 二分查找 1. 查找算法 查找算法是用于在数据集中定位特定元素的位置的算法。查找是计算机科学中一项基本操作,几乎在所有应用程序中都需要使用。例如,数据库查询、信息检索、字典查找等都涉及到查找操作。查找算…

【Mutilism数字电路实现32进制5线32译码器】2022-5-7

缘由3-8译码器到74HC138-编程语言-CSDN问答 2片16004非门2个组成8进制和4进制实现。 按138逻辑表把E3也接入置零,同时把E1也接入反向使得切换时138保持高电平输出,就看不到转换时第一个出现短暂低电平,是最完美的解决方案,二级反向…

分布式I/O从站的认知

为什么需要分布式I/O从站? 当PLC与控制机构距离过远时,远距离会带来信号干扰,分布式I/O从站只需要一个网络线缆连接。 ET200分布式I/O从站家族 体积紧凑、功能强大。 ET200SP ET200M ET200S ET200iSP ET200 AL ET200pro ET200 eco PN 通讯协议…

yarn底层原理详解:(第33天)

系列文章目录 一、yarn总体架构 二、yarn核心组件及功能 三、yarn资源分配与调度 四、yarn提交和执行流程 五、yarn调度算法 六、yarn安全性与容错性 文章目录 系列文章目录前言一、总体架构二、核心组件及功能1. ResourceManager(RM)2. NodeManager&am…

达梦数据库dm8安装步骤及迁移

目录 前言: 一、安装部署 1、下载 2、创建用户及安装目录 3、挂载下载的镜像 4、环境配置 5、安装 二、基本使用 1、DM工具使用 2、兼容性配置 2.1 兼容GBK字符集编码 2.2 兼容UTF-8字符集编码 3、创建用户和密码,表空间 4、整理数据库配置 5、启动脚本设置 …

13、Python之函数:简单的参数默认值其实并不简单

目录 引言 日志打印的问题 返回参数默认值的问题 问题产生的原因 关于参数默认值的最佳实践 总结 引言 在前一篇关于Python函数的文章中,我们介绍了函数的基本使用、函数的默认参数、lambda函数的用法,相当于对Python中的函数有了一个入门的介绍。…

动态规划之数字三角形模型+最长上升子序列模型

首先,我们从集合角度重新看待DP: 直接看题:https://www.acwing.com/problem/content/1029/ 就是取纸条的原题,我们令f[i1,j1,i2,j2]表示从(1,1),(1,1)分别走到(i1,j1),(i2,j2)的路径的max i1j1i2j2,于是我们可以把状…

ESP32的芯片有几种

ESP32系列 ESP32芯片截止到24年7月有5个系列: ESP32-C3 ESP32由ESP32-P 系列、ESP32-S 系列、ESP32-C 系列、ESP32-H 系列、ESP32 系列构成。其中ESP32-S分为S3和S2两个小系列;ESP32-C系列分为C6、C5、C3、C2四个小系列,具体如下。 说明&am…

合宙 Air780E模块 AT 指令 MQTT连接

固件说明 重启模块 //tx ATRESET//rx ATRESETOK ^boot.romv!\n RDY^MODE: 17,17E_UTRAN ServiceCGEV: ME PDN ACT 1NITZ: 2024/07/10,08:33:440,0查询模块版本信息 //tx ATCGMR//rx ATCGMRCGMR: "AirM2M_780E_V1161_LTE_AT"OK基本流程 4G模块支持MQTT和MQTT SSl协…

5 MySql

5 MySql 一、简介二、SQL语言2.1 导入外部SQL文件2.2 显示表结构2.3 与创建数据库相关的语句2.4 与表相关的语句2.5 操作表中的数据2.6 7种基本的sql查询 三、SQL的注意点3.1 与集合函数相关3.2 SQL语句的书写与执行过程 四、约束 constraint4.1 作用4.2 功能分类4.3 自增 五、…