大规模语言模型--中文 LLaMA和Alpaca

news2024/3/4 12:46:27

中文LLaMA

尽管 LLaMA 和 Alpaca 在 NLP 领域取得了重大进展, 它们在处理中文语言任务时, 仍存在一些局限性。这 些原始模型在字典中仅包含数百个中文 tokens  (可以理解为单词),导致编码和解码中文文本的效率受到了很大 影响。

之前已经对原始 LLaMA 技术进行了深入解读, LLaMA 基于 transformer 结构进行了一些改进, 比如预归一 化、 SwiGLU 激活函数以及旋转embedding 。LLaMA 的参数总数在 7B 到 65B 之间。实验数据表明, LLaMA 在 保持更小模型尺寸的同时,与其他的 LLM 相比(比如 GPT-3),具有相当的竞争性。

LLaMA 在公开可用的语料库中预训练了 1T 到 1.4T 个 token,其中大部分数据是英文, 因此 LLaMA 理解 和生成中文的能力受到限制。为了解决这个问题, 中文版的 LLaMA 在原始 LLaMA 模型的基础上, 扩充了包含 20K 中文 token 的中文词典, 提升了编码效率, 从而提升了模型处理和生成中文文本的能力, 增强了基础语义理 解能力。

然而,直接在中文语料库上对 LLaMA 进行预训练也存在相应的挑战:

  •  1、原始 LLaMA tokenizer 词汇表中只有不到一千个中文字符。虽然 LLaMA tokenizer 可以通过回退到字节 来支持所有的中文字符,但这种回退策略会显著增加序列长度,同时会降低处理中文文本的效率。

  •  2、字节 tokens 不仅用于表示中文字符, 还用于表示其它 UTF-8 tokens,这使得字节 tokens 难以学习中文 字符的语义含义。

为了解决这些问题,作者提出了以下两个解决方案来扩展 LLaMA tokenizer 中的中文词汇:

  •  1、在中文语料库上使用 SentencePiece 训练一个中文tokenizer,使用 20000 个词汇大小。然后将中文tokenizer 与原始 LLaMA tokenizer 合并, 通过组合它们的词汇表, 最终获得一个合并的 tokenizer,称为中文 LLaMA tokenizer,词汇表大小为 49953。

  •  2、为了使模型适应上一步产生的中文 LLaMA tokenizer,研究人员将 word embeddings 和语言模型的head 从 V × H 调整为 V’× H 的形状, 其中 V = 32,000 代表原始词汇表的大小, 而 V’ = 49,953 则是中文 LLaMA tokenizer 的词汇表大小。新行附加到原始嵌入矩阵的末尾, 确保原始词汇表中的 token embedding 不受影 响。

使用中文 LLaMA 分词器, 相比于原始的 LLaMA 分词器, 生成的 token 数减少了一半左右, 原因是, 前者 的编码长度有了明显的减少, 如下表所示。给定固定的上下文长度时, 相比于原始 LLaMA 分词器, 新模型可 以容纳约两倍的信息, 且生成速度快两倍。这表明, 新模型在提高 LLaMA 模型的中文理解和生成能力方面是有 效的。

原始 LLaMA 和中文 LLaMA 的 tokenizer 对比示例。

得到了中文 LLaMA 分词器后,研究人员使用中文 LLaMA 分词器,基于标准 Casual Language Modeling(CLM)

任务, 对中文 LLaMA 模型进行预训练。对于给定的输出 token 序列: x = (x0 , x1 , x2 , ..., xi−1 ),模型使用自回归 的方式训练,以预测下一个 token。目标即最小化负对数似然:

其中, xi  表示预测的 token;x0 , x1 , x2 , ..., xi−1  表示上下文。

采用 LoRA 的高效参数微调方法,在冻结原模型 LLaMA 参数的情况下,通过往模型中加入额外的网络层,并 只训练这些新增的网络层参数。这种方法大大减少了总可训练参数, 使得用更少的计算资源训练 LLaMA,LoRA 的原理其实并不复杂, 它的核心思想是在原始预训练语言模型旁边增加一个旁路, 做一个降维再升维的操作, 来 模拟所谓的 intrinsic rank  (预训练模型在各类下游任务上泛化的过程其实就是在优化各类任务的公共低维本征 (low-dimensional intrinsic) 子空间中非常少量的几个自由参数)。为了在计算资源紧张的情况下实现参数高效的 训练,作者将 LoRA 训练应用于论文中的所有中文 LLaMA 和 Alpaca 模型,包括预训练和微调阶段。

在训练时, 固定预训练语言模型的参数, 只训练降维矩阵 A 与升维矩阵 B。而模型的输入输出维度不变, 输 出时将 BA 与预训练语言模型的参数叠加。用随机高斯分布初始化 A,用 θ 矩阵初始化 B。这样能保证训练开始 时,新增的通路 BA = θ 从,而对模型结果没有影响。​

在推理时, 将左右两部分的结果加到一起即可, h = Wx + BAx = (W + BA)x,所以, 只要将训练完成的 矩阵乘积 BA 跟原本的权重矩阵 W 加到一起作为新权重参数替换原始预训练语言模型的 W 即可, 不会增加额 外的计算资源。

Tokenizer

LLaMA 的训练语料以英文为主, 使用字节对编码(BPE) 算法对数据进行分词, 使用 SentencePiece 的实现, 词表大小只有 32000。词表里的中文 token 很少, 只有几百个, 预训练中没有出现过或者出现得很少的语言学习 得不充分,而且,对中文分词的编码效率比较低。值得注意的是,作者将所有数字分割成单个数字。

讲解 SentencePiece 之前, 我们先讲解下分词器(Tokenizer)。简单点说分词器就是将字符序列转化为数字序 列, 对应模型的输入。通常情况下, Tokenizer 有三种粒度: word/char/subword,这三种粒度分词截然不同, 各有 利弊:

  • 1. word: 按照词进行分词, 如: Today is sunday. 则根据空格或标点进行分割 [today, is, sunday, .],对于 word 粒 度分词, 其优点是词的边界和含义得到保留; 缺点是: 1) 词表大, 稀有词学不好; 2 ) OOV  (可能超出词 表外的词); 3) 无法处理单词形态关系和词缀关系, 会将两个本身意思一致的词分成两个毫不相同的 ID, 在英文中尤为明显,如: cat ,cats。

  •  2. character:按照单字符进行分词, 就是以 char 为最小粒度。如: Today is sunday. 则会分割成 [t,o,d,a,y, ....  ,s,u,n ,d ,a,y ,.],对于 character 粒度分词, 其优点是词表极小, 比如: 26 个英文字母几乎可以 组合出所有词, 5000 多个中文常用字基本也能组合出足够的词汇; 缺点是: 1) 无法承载丰富的语义, 英 文中尤为明显,但中文却是较为合理,中文中用此种方式较多。 2)序列长度大幅增长;

  • 3. subword:按照词的 subword 进行分词。如: Today is sunday. 则会分割成 [to,day,is ,s,un,day ,.],为 了平衡以上两种方法, 提出了基于 subword 进行分词: 它可以较好的平衡词表大小与语义表达能力; 常见的子词算法有 Byte-Pair Encoding (BPE) / Byte-level BPE  (BBPE )、WordPiece 、SentencePiece 等。​

BPE 和 BBPE :  BPE 即字节对编码。其核心思想是从字母开始, 不断找词频最高、且连续的两个 token 合 并, 直到达到目标词数。 BBPE:BBPE 核心思想将 BPE 的从字符级别扩展到子节(Byte) 级别。 BPE 的一个问 题是如果遇到了 unicode 编码, 基本字符集可能会很大。 BBPE 就是以一个字节为一种“字符”,不管实际字符集 用了几个字节来表示一个字符。这样的话, 基础字符集的大小就锁定在了 256  (28 )。采用 BBPE 的好处是可以 跨语言共用词表, 显著压缩词表的大小。而坏处就是, 对于类似中文这样的语言, 一段文字的序列长度会显著 增长。因此, BBPE based 模型可能比 BPE based 模型表现的更好。然而, BBPE sequence 比起 BPE 来说略长, 这也导致了更长的训练/推理时间。 BBPE 其实与 BPE 在实现上并无大的不同, 只不过基础词表使用256 的字节集。​

WordPiece : WordPiece 算法可以看作是 BPE 的变种。不同的是, WordPiece 基于概率生成新的 subword 而 不是下一最高频字节对。 WordPiece 算法也是每次从词表中选出两个子词合并成新的子词。 BPE 选择频数最高的 相邻子词合并,而 WordPiece 选择使得语言模型概率最大的相邻子词加入词表。

SentencePiece :  SentencePiece 它是谷歌推出的子词开源工具包, 它是把一个句子看作一个整体, 再拆成片 段, 而没有保留天然的词语的概念。一般地, 它把空格也当作一种特殊字符来处理, 再用 BPE 或者 Unigram 算法 来构造词汇表。 SentencePiece 除了集成了 BPE、ULM 子词算法之外, SentencePiece 还能支持字符和词级别的分 词。当前主流的一些开源大模型有很多基于 BBPE 算法使用 SentencePiece 实现分词器,下面来讲解 SentencePiece 工具的具体使用。

SentencePiece 是一种无监督的文本 tokenizer 和detokenizer ,主要用于基于神经网络的文本生成系统, 其中, 词汇量在神经网络模型训练之前就已经预先确定了。SentencePiece 实现了 subword 单元(例如,字节对编码 (BPE)) 和 unigram 语言模型), 并可以直接从原始句子训练字词模型 (subword model)。这使得我们可以制作一个不依赖 于特定语言的预处理和后处理的纯粹的端到端系统。 SentencePiece 特性如下:

  • Token 数量是预先确定的: 神经网络机器翻译模型通常使用固定的词汇表进行操作。与大多数假设无限词 汇量的无监督分词算法不同, SentencePiece 在训练分词模型时, 使最终的词汇表大小固定, 例如: 8k 、16k 或 32k。

  • 从原始句子进行训练: 以前的子词(sub-word) 实现假设输入句子是预标记(pre-tokenized) 的。这种约束是 有效训练所必需的, 但由于我们必须提前运行依赖于语言的分词器, 因此使预处理变得复杂。 SentencePiece  的实现速度足够快, 可以从原始句子训练模型。这对于训练中文和日文的 tokenizer 和 detokenizer 很有用, 因为在这些词之间不存在明确的空格。

  • 空格被视为基本符号:  自然语言处理的第一步是文本 tokenization, 例如, 标准的英语分词器(tokenizer) 将 对文本 Hello world 进行分段。分为 [Hello] [World] [.] 这三个 token。这种情况将导致原始输入和标记化 (tokenized) 序列不可逆转换。例如,  “World”和“. ”之间没有空格的信息。空格将从标记化序列中删除, 例如:Tokenize(  “World. ”) == Tokenize(  “World . ”)。但是, SentencePiece 将输入文本视为一系列 Unicode  字符。空格也作为普通符号处理。为了明确地将空格作为基本标记处理, SentencePiece 首先使用元符号”ff” (U+2581) 转义空格。 HelloffWorld. 然后, 将这段文本分割成小块, 例如: [Hello] [ffWor] [ld] [.]。由于空格保 留在分段文本中, 我们可以毫无歧义地对文本进行 detokenize 。detokenized = ”.join(pieces).replace(’ ’, ’ ’), 此特性可以在不依赖特定于语言的资源的情况下执行 detokenization。

  • 子词正则化和 BPE-dropout: 子词正则化和 BPE-dropout 是简单的正则化方法, 它们实际上通过实时子词采 样来增强训练数据,这有助于提高神经网络机器翻译(NMT)模型的准确性和鲁棒性。

中文 LLaMA 经过词表扩充后,我们来对比一下几个基座模型 Tokenizer 的区别,如下表所示:

基座模型的 tokenizer 对比示例

“中文平均 token 数”表示了 tokenizer 分词后,每个中文字符对应的平均 token 数。从结果来看:

  • LLaMA 的词表是最小的, LLaMA 在中英文上的平均 token 数都是最多的, 这意味着 LLaMA 对中英文分词都会比较碎, 比较细粒度。尤其在中文上平均 token 数高达 1.45,这意味着 LLaMA 大概率会将中文字 符切分为 2 个以上的token。​​

  • 中文 LLaMA(Chinese LLaMA) 扩展词表后, 中文平均 token 数显著降低, 会将一个汉字或两个汉字切分为 一个 token ,提高了中文编码效率。

  • ChatGLM-6B 是平衡中英文分词效果最好的tokenizer 。由于词表比较大,中文处理时间也有增加。

  •  BLOOM 虽然是词表最大的, 但由于是多语种的, 在中英文上分词效率与 ChatGLM-6B 基本相当。需要注意的是, BLOOM 的 tokenizer 用了 transformers 的 BloomTokenizerFast 实现,分词速度更快。​

从一个例子来直观对比不同 tokenizer 的分词结果。“男儿何不带吴钩, 收取关山五十州。”共有 16 字。几个 tokenizer 的分词结果如下:

  •  LLaMA 分词为 24 个 token :[ ’ 男’, ’<0xE5>’, ’<0x84>’, ’<0xBF>’, ’ 何’, ’ 不’, ’<0xE5>’, ’<0xB8>’, ’<0xA6>’, ’<0xE5>’, ’<0x90>’, ’<0xB4>’, ’<0xE9>’, ’<0x92>’, ’<0xA9>’, ’,’, ’ 收’, ’ 取’, ’ 关’, ’ 山’, ’ 五’, ’ 十’, ’ 州’, ’。’]

  •  Chinese LLaMA 分词为 14 个 token :[ ’ 男’, ’ 儿’, ’ 何’, ’ 不’, ’ 带’, ’ 吴’, ’ 钩’, ’ ,’, ’ 收取’, ’ 关’, ’ 山’, ’ 五十’, ’ 州’, ’。 ’]

  •  ChatGLM-6B 分词为 11 个 token :[ ’ 男儿’, ’ 何不’, ’ 带’, ’ 吴’, ’ 钩’, ’,’, ’ 收取’, ’ 关山’, ’ 五十’, ’ 州’, ’。 ’]   

  • Bloom 分词为 13 个 token :[’ 男’, ’ 儿’, ’ 何不’, ’ 带’, ’ 吴’, ’ 钩’, ’ ,’, ’ 收取’, ’ 关’, ’ 山’, ’ 五十’, ’ 州’, ’。 ’]

中文 Alpaca

在获得了预训练的中文 LLaMA 模型后, 作者利用斯坦福羊驼(Alpaca) 训练采用的方法——指令微调继续 训练该模型, 得到一个遵循指令的 LLaMA 模型—— 中文 Alpaca。继斯坦福羊驼(Stanford Alpaca) 之后, UC 伯 克利、 CMU、斯坦福等机构的学者, 联手发布了最新开源大模型骆马(Vicuna),包含 7B 和 13B 参数。我们已 经清楚 ChatGPT 的训练步骤, 可以借鉴 ChatGPT 的训练步骤, 得到一个类 ChatGPT 大模型, 下面以 Alpaca 为例介绍:​

  •  第一步:收集标注数据(人工标注的 prompt + 期望回答),在已有的大语言模型基础上(GPT3 、GPT-3.5、 ChatGPT),进行有监督训练,得到“模型 A ”。

  •  第二步: 收集对比数据。给定一个 prompt,第一步的模型会产生多个输出, 标注人员会对这些输出答案进 行排序,训练一个 pairwise 模型(Reward 模型),即“模型 B”,模型 B 与模型 A 的模型结构不同。

  •  第三步: 基于第一步、第二步的模型, 基于 PPO 强化学习算法, 训练得到最终模型, 即“模型 C”,模型 C 与模型 A 的结构相同。

因此, 在类 ChatGPT 大模型的训练过程中, 为了进行第一步的训练, 目前通常使用 OPT 、BLOOM 、GPT- J、LLaMA 等开源大模型替代 GPT3 、GPT3.5 等未开源的模型。 Stanford Alpaca 提供了基于“指令遵循数据”对 LLAMA 进行微调(supervised finetuning)的代码,完成了“类 ChatGPT 大模型训练步骤”中的第一步。

Alpaca 7B 是由 Meta 的 LLaMA 7B 模型通过 52K 指令微调得到的模型。 Alpaca 与 OpenAI 的text-davinci-003 (GPT-3.5)表现类似,模型容量惊人的小,易于复现,且复现成本低(<600 美元)。

GPT-3.5 (text-davinci-003) ,ChatGPT ,Claude 和 Bing Chat 等指令遵循模型的功能越来越强大。许多用户定 期与这些模型进行交互, 且在工作中使用它们。尽管这些模型得到了广泛部署, 但它们仍有许多不足之处: 产 生虚假信息、传播社会偏见、甚至制造有毒言论。

为了解决这些紧迫问题, 学术界的参与至关重要。不幸的是, 在学术界进行指令遵循研究十分困难, 因为没 有一个易于实现的模型可以在功能上接近于 closed-source  (未开源)模型(比如 OpenAI 的 GPT-3.5 )。

文章提到, Alpaca 小羊驼仅用于学术研究, 禁止任何商业用途。原因有三: 1 、Alpaca 基于 LLaMA,它有 非商业许可证,因此 Alpaca 也必须继承这一点; 2、指令数据基于 OpenAI 的 text-davinci-003,其使用条款禁止 开发与 OpenAI 竞争的模型; 3 、没有设计足够的安全措施,因此羊驼还未准备好作为一般用途。

训练方法

在学术预算下, 训练高质量的指令遵循模型具有两个挑战, 1) 一个强大的预训练语言模型; 2) 高质量的 指令遵循数据。 Meta 最新发布的 LLaMA 模型解决了第一个挑战。对于第二个挑战,根据 self-instruct 论文的介绍, 可以使用现有的强大语言模型, 自动生成指令数据。 Alpaca 正是由LLaMA 7B 模型经过有监督微调结合由OpenAI 的 GPT-3.5 生成的 52K 指令数据训练而来。​

下图说明了羊驼模型的训练方法。首先, 从 self-instruct 种子集合中生成 175 个由人类撰写的指令-输出 pair 对。然后提示 text-davinci-003 使用上下文实例中的种子集合,生成更多的指令。通过简化生成过程,对 self-instruct 方法进行了改进,显著降低了成本。上述的数据生产过程产生了 52K 条独特的指令及其对应的输出,使用OpenAI 的 API,花费不足 500 美元。

Alpaca的训练示例​

得到了这个指令遵循数据集后, 利用全分片数据并行和混合精度训练等技术, 基于 Hugging Face 的训练框 架, 对 LLaMA 模型进行微调。在首次运行中, 在 8 个 80GB A100 显卡上微调 LLaMA-7B 模型, 耗时 3 小时, 这 在大多数云计算供应商上的花费不足 100 美元。

评估和局限

在 self-instruct 评估集合上, 对 Alpaca 进行人类评估。 self-instruct 评估集合由 self-instruct 的作者收集, 涵盖 了一系列面向用户的指令, 包括电子邮件写作、社交媒体、生产力工具。作者对 text-davinci-003 和 Alpaca 7B 进行 了比较, 发现两个模型的性能非常相近: Alpaca 在与text-davinci-003 的比较中, 赢得了 90 胜, 而text-davinci-003 赢得了 89 胜。

文章里也提到了 Alpaca 的一些局限性,包括幻觉、毒性以及偏见。幻觉似乎是羊驼的常见出错模式。

ps: 欢迎扫码关注公众号^_^.

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

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

相关文章

基于微信小程序的游戏账号交易买卖平台设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

oracle-使用PLSQL工具自行修改用户密码

1、使用PLSQL工具&#xff0c;输入用户名和原密码登录&#xff0c;如下图 2、登录后&#xff0c;在会话下拉菜单中找到”Change password..” 3、在跳出的窗口中配置新密码&#xff0c;修改完成后单击”确认”&#xff0c;后退出PLSQL 4、重新打开PLSQL&#xff0c;使用新密码登…

1 论文笔记:Efficient Trajectory Similarity Computation with ContrastiveLearning

2022CIKM 1 intro 1.1 背景 轨迹相似度计算是轨迹分析任务&#xff08;相似子轨迹搜索、轨迹预测和轨迹聚类&#xff09;最基础的组件之一现有的关于轨迹相似度计算的研究主要可以分为两大类&#xff1a; 传统方法 DTW、EDR、EDwP等二次计算复杂度O(n^2)缺乏稳健性 会受到非…

淘宝商品sku信息抓取接口api

在电商行业中&#xff0c;SKU是一个经常被使用的术语&#xff0c;但是对于很多人来说&#xff0c;这个词可能还比较陌生。在这篇文章中&#xff0c;我们将详细解释什么是SKU&#xff0c;以及在电商业务中它的作用和意义。 什么是SKU&#xff1f; SKU是“Stock Keeping Unit”…

Golang中的包和模块设计

Go&#xff0c;也被称为Golang&#xff0c;是一种静态类型、编译型语言&#xff0c;因其简洁性和对并发编程的强大支持而受到开发者们的喜爱。Go编程的一个关键方面是其包和模块系统&#xff0c;它允许创建可重用、可维护和高效的代码。本博客文章将深入探讨在Go中设计包和模块…

C++11(列表初始化,声明,范围for)

目录 一、列表初始化 1、一般的列表初始化 2、容器的列表初始化 二、声明 1、 auto 2、decltype 3、nullptr 三、 范围for 一、列表初始化 1、一般的列表初始化 在C98中&#xff0c;标准允许使用花括号{}对数组或者结构体元素进行统一的列表初始值设定。 int main() {…

【C++入门指南】类和对象(上)

【C杂货店】类和对象&#xff08;上&#xff09; 一、面向过程和面向对象初步认识二、类的引入三、类的定义四、类的访问限定符及封装4.1 访问限定符4.2 封装 五、类的作用域六、类的实例化七、类对象模型7.1 类对象的存储规则7.2 例题7.3结构体内存对齐规则 八、this指针8.2 t…

YOLOV8-DET转ONNX和RKNN

目录 1. 前言 2.环境配置 (1) RK3588开发板Python环境 (2) PC转onnx和rknn的环境 3.PT模型转onnx 4. ONNX模型转RKNN 6.测试结果 1. 前言 yolov8就不介绍了&#xff0c;详细的请见YOLOV8详细对比&#xff0c;本文章注重实际的使用&#xff0c;从拿到yolov8的pt检测模型&…

Go_原子操作和锁

原子操作和锁 本文先探究并发问题&#xff0c;再探究锁和原子操作解决问题的方式&#xff0c;最后进行对比。 并发问题 首先&#xff0c;我们看一下程序 num该程序表面看上去一步就可以运行完成&#xff0c;但是实际上&#xff0c;在计算机中是分三步运行的&#xff0c;如下…

计算机图像处理-中值滤波

非线性滤波 非线性滤波是利用原始图像跟模版之间的一种逻辑关系得到结果&#xff0c;常用的非线性滤波方法有中值滤波和高斯双边滤波&#xff0c;分别对应cv2.medianBlur(src, ksize)方法和cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])方法。 …

Linux高性能服务器编程 学习笔记 第九章 IO复用

IO复用使程序能同时监听多个文件描述符&#xff0c;这可以提高程序的性能&#xff0c;通常网络程序在以下情况需要使用IO复用&#xff1a; 1.客户端进程需要同时处理多个socket。 2.客户端进程需要同时处理用户输入和网络连接。 3.TCP服务器要同时处理监听socket和连接socket…

c#设计模式-结构型模式 之装饰者模式

&#x1f680;介绍 在装饰者模式中&#xff0c;装饰者类通常对原始类的功能进行增强或减弱。这种模式是在不必改变原始类的情况下&#xff0c;动态地扩展一个对象的功能。这种类型的设计模式属于结构型模式&#xff0c;因为这种模式涉及到两个类型之间的关系&#xff0c;这两个…

《C++ Primer》练习7.31:定义互相嵌套的类

类可以先声明再定义&#xff0c;可以用下面这个题目理解一下 class Y; class X {Y *y; };class Y {X x; };未出现的类类型要在前面声明。 参考 《C Primer》

前端架构师之02_ES6_高级

1 类和继承 1.1 class类 JavaScript 语言中&#xff0c;生成实例对象的传统方法是通过构造函数。 // ES5 创建对象 // 创建一个类&#xff0c;用户名 密码 function User(name,pass){// 添加属性this.name name;this.pass pass; } // 用 原型 添加方法 User.prototype.sho…

集合-ArrayList源码分析(面试)

系列文章目录 1.集合-Collection-CSDN博客​​​​​​ 2.集合-List集合-CSDN博客 3.集合-ArrayList源码分析(面试)_喜欢吃animal milk的博客-CSDN博客 目录 系列文章目录 前言 一 . 什么是ArrayList? 二 . ArrayList集合底层原理 总结 前言 大家好,今天给大家讲一下Arra…

使用Qt验证RGB格式

下面我们用不同的颜色来绘制一块矩形区域&#xff0c;来对比学习RGB颜色。 一片漆黑的黑色 黑色在RGB中是三个颜色分量都是0。也就是没有颜色。 下面我们绘制一个水平100个像素&#xff0c;垂直200个像素的矩形区域&#xff0c;颜色设置为黑色。 #ifndef MAINWINDOW_H #def…

基于B2B平台的医疗病历交互系统

目录 前言 一、技术栈 二、系统功能介绍 医院管理 医院注册 医院文章 医生信息 医院注册 医疗安排 院区注册 医院公告 医院工作人员 病人病历 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 进入21世纪&#xff0c;计算机技术迅速向着网络化的、集…

el-menu 导航栏学习(1)

最简单的导航栏学习跳转实例效果&#xff1a; &#xff08;1&#xff09;index.js路由配置&#xff1a; import Vue from vue import Router from vue-router import NavMenuDemo from /components/NavMenuDemo import test1 from /components/test1 import test2 from /c…

Qt::图层框架-图片图层-序列图层-QGraphicsPixmapItem

二维矢量动画智能制作软件开发合集 链接&#xff1a;软件开发技术分享及记录合集 个人开发二维矢量动画智能制作软件界面如下&#xff1a; 目录 一、图片序列图层原理 二、图片序列图层代码实现 三、图片序列图层软件测试视频 结束语 一、图片序列图层原理 本软件的11种…

凉鞋的 Godot 笔记 102. 场景与节点的增删改查

在上一篇&#xff0c;我们完成了 Godot 引擎的 Hello World 输出&#xff0c;并且完成了第一个基本循环: 通过这次基本循环的完成&#xff0c;我们获得了一点点的 Godot 使用经验&#xff0c;这非常重要。 有实践经验后再去补充理论 和 先学习理论后去实践相比&#xff0c;前者…