全面解释人工智能LLM模型的真实工作原理(二)
前一篇:《全面解释人工智能LLM模型的真实工作原理(一)》
序言:在上一篇文章中,我们从原理上构建了一个识别“叶子”和“花朵”的神经网络,并详细讲解了它的工作过程。这包括对输入数字逐个与权重相乘后求和,加上偏置值,最后通过非线性处理和统计分布计算来得出输出。这些操作使用了简单的数学运算(乘法、加法和非线性处理)。本节的重点是解答神经网络的权重和偏置值是如何得到的以及最关键的概念:如何让神经网络输出chatGPT一样的句子。为了让神经网络学到合适的权重和偏置,我们需要提供大量的学习数据(如大量的“叶子”和“花朵”图片),让网络在学习过程中调整每个神经元的权重和偏置值,最终实现正确分类。(请动一下您的小手,订阅作者!)
如何训练这个神经网络(模型)?
在上例中,我们为了测试,给模型预设了合适的权重和偏置,这样才能得到准确的输出。但在实际应用中,权重和偏置值是如何获得的呢?获得合适的‘权重’和‘偏置’这个过程就称为“训练模型”或“训练神经网络”,也可以理解为“人工智能的自我学习”;没错,这个过程就是“训练AI”。人类需要做的就是为模型提供优质数据来进行训练。
假设我们收集了一些数据,包括各种类型的“叶子”和“花朵”。然后,我们用工具将它们的颜色和体积转换成数字,给每个数据样本贴上“叶子”或“花朵”的标签(给数据取名字就称为“标注数据”),最终这些数据组成了我们的“训练数据集”。
训练神经网络的工作原理如下:
- 初始化权重
首先,从随机数开始,将神经元的每个参数/权重设为一个随机数。(启动训练程序时,计算机内存中未初始化的都是随机数,一般无须特别设定)
- 输入数据并获得初始输出
我们给神经网络输入“叶子”的数据表示(如 R=32,G=107,B=56,Vol=11.2),期望输出层第一个神经元的值大于第二个神经元的值,表示识别出“叶子”。假如预期“叶子”神经元的值是0.8,代表“花”的神经元值是0.2。
- 计算损失
因为初始权重是随机的,实际输出往往和预期有差异。比如,两个神经元的初始输出分别是0.6和0.4。我们可以通过求差并将差值平方相加计算损失:(0.8 - 0.6)² + (0.2 - 0.4)² = 0.04 + 0.04 = 0.08。理想情况下,我们希望损失接近于零,也就是“最小化损失”。
- 计算梯度并更新权重
计算每个权重对损失的影响(称为梯度),看向哪个方向调整才能减少损失。梯度指示了每个参数的变化方向——权重会朝损失减少的方向略微调整一点。这个过程称为“梯度下降”。
- 重复迭代
持续重复这些步骤,通过不断更新权重,使得损失逐步减少,最终得到一组“训练好的”权重或参数。这就是神经网络的训练过程,称为“梯度下降”。
补充说明
• 多个训练样本
训练中通常会使用多个样本。微调权重以最小化某个样本的损失可能会导致其他样本的损失增大。为了解决这个问题,通常会计算所有样本的平均损失,并基于平均损失的梯度来更新权重。每次完整的样本循环称为“一个 epoch”,多个 epoch 的训练可以帮助逐步找到更优的权重。
• 自动计算梯度
实际上,无需手动微调权重来计算梯度,数学公式可以直接推导出每个参数的最佳调整方向。例如,如果上一步权重为 0.17,且神经元的输出希望增大,那么将权重调整为 0.18 可能更有效。
在实践中,训练深度网络是一个复杂的过程,训练中可能会遇到梯度失控的情况,例如梯度值趋于零或趋向无穷大,这分别称为“梯度消失”和“梯度爆炸”问题。虽然上述的损失定义有效,但在实际应用中,通常会使用更适合特定任务的损失函数来提高训练效果。
这些原理怎样帮助神经网络生成语言?
请记住,神经网络只能接收输入一组数字,基于训练好的参数进行数学运算,最后输出另一组数字。关键在于如何解释这些数字,并通过训练来自动调整参数。如果我们能够把两组数字解释为“叶子/花朵”或“一小时后是晴天或雨天”,同样也可以将它们解释为“句子的下一个字符”。
但是,英语字母远不止两个,所以我们需要将输出层的神经元数量扩展,例如扩展到26个以上的神经元(再加上一些符号,如空格、句号等)。每个神经元对应一个字母或符号,然后我们在输出层中找出数值最大的神经元,并将其对应的字符作为输出字符。现在我们就有了一个可以接收输入并输出字符的网络。
如果我们给神经网络输入“Humpty Dumpt”这个字符串,然后让它输出一个字符,并将其解释为“网络预测到的下一个字符”,我们可以通过训练,确保网络在收到这样的字符串“Humpty Dumpt”输入时输出字母“y”,从而达到我们想要的结果“Humpty Dumpty”。
不过,这里有一个问题:如何将字符串输入到网络中?毕竟,神经网络只接受数字!通常实践中我们可以通过“one-hot编码”或其他编码方法将字符串转换成数值数组,使其可以被神经网络理解和处理。
这里我们用一个最简单的解决方案来编码:直接为每个字符分配一个数字。例如,a=1,b=2,依此类推。现在我们可以输入“humpty dumpt”并训练网络输出“y”。网络的工作过程如下:
先在神经网络的输入层输入一串句子(字符串),它将会在输出层预测下一个字符。这样的方法可以帮助我们构建完整的句子。例如,当我们预测出“y”后,可以将这个“y”添加到前面输入的字符串尾部,并再次送回神经网络的输入层,让它预测下一个字符。如果训练得当,网络会预测出一个空格;如此循环下去,最终生成出完整的句子:“Humpty Dumpty sat on a wall”。这样,我们就得到了一个生成式 AI(人工智能语言模型),神经网络现在可以生成人类的自然语言了!
当然,在真实应用中例如chatGPT,我们不会使用这种简单的字符编号方法。在后文中,我们会介绍一种更合理的编码方式。如果你迫不及待,可以查看附录中的“编码”部分。
细心的读者可能会注意到,我们无法直接输入“Humpty Dumpty”,因为如图所示,输入层只有12个神经元,对应于“humpty dumpt”中的每个字符(包括空格),并没有多余的神经元留给字母‘y’输入了。那么,如何在下一步中加入“y”呢?如果在输入层加上第13个神经元,就需要重新调整整个网络,这显然不太现实。解决方案很简单:我们可以将最早的字符“h”剔除,保留最近的12个字符输入。例如,我们输入“umpty dumpty”,网络会预测出一个空格;然后我们输入“mpty dumpty ”,网络会输出“s”,如此循环下去,过程如下所示:
这种方法有个问题,即当我们输入“ sat on the wal”时,会丢失之前的许多信息。那么,现代顶尖神经网络是如何解决的呢?原理基本相似。神经网络的输入的长度是固定的(取决于输入层的大小),这种长度称为“上下文长度”,即网络用来预测后续内容的参考范围。现代网络的上下文长度可以很长(通常达到几万甚至几十万个字符。例如,ChatGPT的4o模型支持12.8万个字符,Claude则支持25.6万个字符。这意味着它们在输入层中使用了超过10万个神经元来接收用户的输入。试想一下,上千亿参数意味着有多少神经元在参与运算?),这对提升效果非常有帮助。尽管某些方法允许输入无限长度的序列,但固定上下文长度较大的模型在性能上已经优于这些方法。
细心的读者可能还会注意到,我们在输入和输出端对同一个字母的解释方式不同!例如,输入“h”时我们用数字8表示它,但在输出层,我们并不直接要求模型输出数字8来代表“h”,而是生成26个数值,并选择其中最大值对应的字母作为输出。如果第8个数值最大,我们将其解释为“h”。为什么不在两端使用相同的表示方式呢?事实上,这是为了构建更有效的模型——不同的输入和输出解释方式为模型性能的提升提供了更多可能。实践表明,这种不同的表示方式对语言生成更有效。实际上,我们在输入端的数字表示方式也并非最佳,稍后会介绍更优的方法。
本节是搞明白chatGPT输出人类自然语言句子的核心原理,希望感兴趣的朋友如果没有搞明白,多读几篇或者在评论区留言与作者交流,我会毫无遗漏的回答所有的评论。
未完待续…
全面解释人工智能LLM模型的真实工作原理(二)的更多相关文章
- linux下的工作模型以及Nginx工作原理
Web服务器主要任务就是处理来自客户端的请求,一般情况下Web服务器处理并发连接请求的工作模型有以下几种方式: 1.单线程web服务器(Single-threaded web servers) 此 ...
- Hadoop周边生态软件和简要工作原理(二)
转自: http://www.it165.net/admin/html/201307/1532.html Sqoop: sqoop在hadoop生态系统中也是应用率比较高的软件,主要是用来做ETL工具 ...
- How Javascript works (Javascript工作原理) (二) 引擎,运行时,如何在 V8 引擎中书写最优代码的 5 条小技巧
个人总结: 一个Javascript引擎由一个标准解释程序,或者即时编译器来实现. 解释器(Interpreter): 解释一行,执行一行. 编译器(Compiler): 全部编译成机器码,统一执行. ...
- Android 基于Netty的消息推送方案之概念和工作原理(二)
上一篇文章中我讲述了关于消息推送的方案以及一个基于Netty实现的一个简单的Hello World,为了更好的理解Hello World中的代码,今天我来讲解一下关于Netty中一些概念和工作原理的内 ...
- Zookeeper工作原理二
ZooKeeper是Hadoop的正式子项目,它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护.名字服务.分布式同步.组服务等.ZooKeeper的目标就是封装好复杂易出错的关键服务 ...
- (译)UEFI 启动:实际工作原理
本文是我翻译自国外技术博客的一篇文章,其中讲述了 UEFI 的一些基本概念和细节. 本文的原始链接位于: https://www.happyassassin.net/2014/01/25/uefi-b ...
- java线程内存模型,线程、工作内存、主内存
转自:http://rainyear.iteye.com/blog/1734311 java线程内存模型 线程.工作内存.主内存三者之间的交互关系图: key edeas 所有线程共享主内存 每个线程 ...
- Java虚拟机工作原理具体解释
一.类载入器 首先来看一下java程序的运行过程. 从这个框图非常easy大体上了解java程序工作原理.首先,你写好java代码,保存到硬盘其中.然后你在命令行中输入 javac YourClass ...
- MVC 模型、视图、控制及其单入口文件的mvc的工作原理
什么是mvc,mvc就是模型视图控制,模型就是model,在项目中负责数据库相关的操作,视图就是view ,负责页面的展示和数据的展示,控制就是controller ,负责中间的逻辑转换,数 ...
- Nginx(十)-- 进程模型及工作原理
1.nginx进程模型 Nginx是一个master和worker的模型.master主要用来管理worker进程,master就比作老板,worker就是打工仔,master指挥worker来做事情 ...
随机推荐
- 花样玩转“所见即所得”的可视化开发UI
随着技术的发展,用户对软件的界面美观度和交互体验的要求越来越高.在这样的背景下,可视化开发UI(User Interface)成为了提升用户体验和开发效率的重要工具. 通过图形界面来设计和构建用户界面 ...
- 结构开发笔记(三):solidworks软件(二):小试牛刀,绘制一个立方体
前言 solidworks草图大师,基本的使用过程. 所有的零件基础都是从平面绘制开始,然后凸出来厚度. 本篇绘制一个简单的立方体,熟悉基本操作. 立方体绘制过程 选取一个平面绘制一个 ...
- 从0实现基于Linux socket聊天室-多线程服务器模型-1
前言 Socket在实际系统程序开发当中,应用非常广泛,也非常重要.实际应用中服务器经常需要支持多个客户端连接,实现高并发服务器模型显得尤为重要.高并发服务器从简单的循环服务器模型处理少量网络并发请求 ...
- 一文讲透CRC校验码-附赠C语言实例
一口君最近工作用到CRC校验,顺便整理本篇文章和大家一起研究. 一.CRC概念 1. 什么是CRC? CRC(Cyclic Redundancy Checksum)是一种纠错技术,代表循环冗余校验和. ...
- 配置mysql数据库主从复制
数据库安装 Step1 先删除data文件 Step2 再根据ini配置文件初始化 mysqld --initialize-insecure --user=mysql Step3 安装mysql服务 ...
- HEOI游记
\(NOI2024河北省选-HEOI游记\) ·评价 其实作为体验名额,最大的感觉就是自费旅游了一趟. 为什么说是自费呢?下面清点一下账单: 1.两晚酒店 1200 2.KFC 和 拉面 112 3. ...
- windows权限维持汇总
Windows 权限维持 一.文件层面 1)attrib 使用 Attrib +s +a +h +r 命令 s:设置系统属性(System) a:设置存档属性(Archive) h:设置隐藏属性(Hi ...
- k8s网络原理之Calico
什么是Calico: Calico是一个基于BGP的纯三层网络方案,其会为每个容器(pod)分配一个可路由的IP,在通信时不需要解包和拆包,因此网络性能损耗小,易于排查和水平扩展.Calico网络功能 ...
- 一分钟搭建Ghost个人网站博客系统
什么是Ghost博客系统 Ghost 是一款设计简约.主题精致的个人博客系统,Ghost支持多用户创建和编辑,支持Markdown格式撰写文章,编辑的内容可即时预览. 创建轻量云主机 这里默认你已经有 ...
- .NET 8.0 前后分离快速开发框架
前言 大家好,推荐一个.NET 8.0 为核心,结合前端 Vue 框架,实现了前后端完全分离的设计理念.它不仅提供了强大的基础功能支持,如权限管理.代码生成器等,还通过采用主流技术和最佳实践,显著降低 ...