当前位置: 首页 > news >正文

AI大语言模型学习笔记之三:协同深度学习的黑魔法 - GPU与Transformer模型

Transformer模型的崛起标志着人类在自然语言处理(NLP)和其他序列建模任务中取得了显著的突破性进展,而这一成就离不开GPU(图形处理单元)在深度学习中的高效率协同计算和处理。

Transformer模型是由Vaswani等人在2017年提出的,其核心思想是自注意力机制(self-attention mechanism),它在处理序列数据时能够捕捉长距离依赖关系,从而在NLP等任务中取得了优异的性能。

而GPU(图形处理单元)在这一突破性进展中发挥了重要作用。深度学习模型的训练通常需要大量的计算资源,而传统的中央处理单元(CPU)由于硬件架构的差异和并行处理性能的限制,在处理需要大量矩阵乘法和其他张量操作的高度并行深度学习任务时速度较慢。

在这里插入图片描述

而图形处理单元(GPU)是专门设计用于高度并行计算的专用芯片,特别适合加速深度学习任务。由于Transformer模型具有大量的参数,会对大规模的数据进行大量的高速并行计算和训练,GPU的并行处理能力就为大模型的训练提供了巨大的加速,因此更适合深度学习工作负载,使研究人员和工程师能够充分利用GPU的性能进行模型训练。
在这里插入图片描述

在训练大规模的Transformer模型时,使用GPU可以大幅缩短训练时间,加速模型的研发和部署过程。

因此,Transformer模型在NLP和序列建模任务中的成功与GPU的协同处理密不可分,为深度学习领域的发展和应用带来了显著的影响。

那么,在进行Transformer模型的深度学习任务时,GPU是如何运作的呢?下面我尝试通过一个简单的例子看看是否能够说明各个部件是如何协同工作的。

GPU在Transformer中的角色

Transformer 模型是一种基于自注意力机制的深度神经网络架构,其庞大的参数量和复杂的计算要求对计算机的计算能力的要求非常高。

我们知道目前使用的PC电脑或者服务器主要的计算处理模块都是CPU(中央处理单元),平常用来玩玩游戏、听听音乐、看电影、刷个剧不在话下,用来做专业设计、剪辑短视频、编辑文档、打印文件等工作也是得心应手。
在这里插入图片描述

之所以PC能干这么多不同的事情,主要是因为普通电脑的CPU(中央处理单元)在其架构设计时主要注重了多用途性能和通用的计算能力。CPU被设计成适用于各种任务,包括通用计算、图形界面处理、文件管理、音视频编码解码等。

而当我们进行 AI 深度学习任务时就不一样了。

深度学习的崛起引入了大规模的神经网络和复杂的模型结构,这导致了更多的参数和更复杂的计算图,通常涉及到大规模的矩阵乘法和张量运算,为了提升计算速度,这些操作通常是多个运算并行进行的,对计算机的并行能力提出了很高的要求。

诸如ChatGPT和GPT-4这样最先进的 AI 生成式预训练大语言模型涉及上万亿到上百万亿的参数和海量的数据,通常需要构建及其庞大的 AI GPU Cluster 集群才能满足计算、训练和推理需求,对 GPU 的计算能力要求更是堪称天花板级别的。
在这里插入图片描述

传统CPU虽然具有一些多核心,而且每个核心挺强的,但是数量确实少了点,难以满足深度学习大规模并行计算的需求。与此不同,现代GPU专注于大规模并行计算,拥有许多小型处理单元,使得它们在处理深度学习任务时更为高效。

就拿 英特尔(Intel) 和 英伟达(NVIDIA)2023年各自发布的最新一代架构和核心处理器:
Intel® Xeon® Platinum 8593Q 和 NVIDIA H100 Tensor Core GPU 来说,核心数量和浮点运算性能对比如下:

第五代英特尔  至强  可扩展处理器

处理器核心数量FP64 FLOPSFP32 FLOPSTF32 FLOPS
Intel Xeon 8593Q CPU64 核128 线程5.04 TFLOPS (每秒5.04万亿次)4.96 TFLOPS (每秒4.96万亿次)4.94 TFLOPS (每秒4.94万亿次)
NVIDIA H100 GPU18432 个 CUDA 核心 576个Tensor张量核心60 TFLOPS (每秒60万亿次)60 PFLOPS (每秒60万亿次)1000 PFLOPS(每秒1000万亿次)

在这里插入图片描述

其中,FP64 表示双精度浮点运算,FP32 表示单精度浮点运算,TF32 表示混合精度浮点运算。

从上面的表格可以看出,NVIDIA H100 GPU 在 FP64 和 FP32 两个精度下的每秒浮点运算次数都比 Intel Xeon 8593Q 高出一个数量级(10倍)还要多,在 TF32 精度下的每秒浮点运算次数高出了约200多倍。这意味着 NVIDIA H100 GPU 在浮点计算方面具有明显的优势。

而传统的 CPU 架构在面对 AI 深度学习这种大数据量高并发张量计算时可能就显得力不从心,因为它们的设计更注重于处理多样化且频繁切换的任务,而非大规模数据的并行计算。

另外,深度学习框架和库通常会使用针对GPU设计的特定指令集和特殊优化,而这些优化使得GPU处理器更好地与深度学习任务协同工作。相较之下,CPU在这方面的优化可能比较有限,导致在同样进行深度学习任务时性能较慢。

因此,GPU 处理器在 Transformer 模型中的角色主要体现在其强大的并行计算能力,使得处理大规模、高度并行的深度学习任务变得高效和可行。这为深度学习在一系列自然语言处理(NLP)大模型和其他序列建模任务中的成功进展提供了重要的计算基础。

并行化的自注意力机制

Transformer中的自注意力机制(Self-Attention)是其核心组成部分之一,用于建立输入序列中每个元素与其他元素之间的关联。

为了更好的理解Transformer中的自注意力机制(Self-Attention),让我从一个简单的例子开始。假设你说了一句话:“我爱北京天安门”。我们想知道这句话中的每个词与其他词的关系。

在传统的自然语言处理(NLP)模型中,会将这句话的每个词转换为一个向量,然后使用这些向量来计算词与词之间的关系。例如,我们可以计算“我”与“爱”之间的关系。

在注意力计算(Attention Computation)中,查询向量 ( q ) 与输入序列 ( H = [h_1, h_2, …, h_n] ) 之间的计算用于权重分配,以便更加关注输入序列中与查询相关的部分。在机器翻译任务中,尤其是基于 Seq-to-Seq 模型的机器翻译任务,查询向量 ( q ) 通常是解码器(Decoder)端前一个时刻的输出状态向量。

我们考虑一个简化的注意力计算过程,其中使用了点积注意力(Dot-Product Attention)的形式:

Attention ( q , H ) = Softmax ( q ⋅ H T d ) ⋅ H \text{Attention}(q, H) = \text{Softmax}\left(\frac{q \cdot H^T}{\sqrt{d}}\right) \cdot H \ Attention(q,H)=Softmax(d qHT)H 

其中,( · ) 表示矩阵乘法, ( H T )  \ (H^T) \  HT  表示输入序列的转置, ( d )  \ (\sqrt{d} ) \  d   用于缩放,以防止点积的数值过大。Softmax 函数用于将点积的结果转化为权重分布。

在机器翻译中,( q ) 可以是解码器的前一个时刻的隐藏状态,而 ( H ) 是编码器的所有隐藏状态。这样,计算得到的注意力权重将反映出解码器当前时刻对编码器各个时刻隐藏状态的关注程度。

机器翻译示例图

通过将查询向量 ( q ) 与输入序列 ( H ) 进行点积计算,并使用 Softmax 函数生成权重分布,注意力机制使得模型能够自动关注输入序列中与当前解码器状态相关的部分,这对于更好地捕捉输入和输出序列之间的关联关系非常有帮助。

但是,这种方法存在一个问题。它假设每个词与其他词的关系都是相同的。例如,它假设“我”与“爱”的关系与“爱”与“北京”的关系相同。

自注意力机制(self-Attention)可以解决这个问题。它允许模型根据每个词的上下文来计算词与词之间的关系。

在我们的例子中,自注意力机制可以计算“我”与“爱”之间的关系,同时考虑“北京”和“天安门”这两个词。例如,它可以发现“我”与“爱”之间的关系更强,因为它们都是动词。

在自注意力机制中,采用了查询-键-值(Query-Key-Value)的机制,其中查询向量(Query vector)可以根据输入信息进行生成,而不是事先确定。

BERT(Bidirectional Encoder Representations from Transformers)是一个使用自注意力机制的预训练模型,下面让我们简要讨论BERT中的自注意力机制。

自注意力机制的计算过程

在上图中,我们有输入信息
H = [ h 1 , h 2 ] \ H = [h_1, h_2] \  H=[h1,h2] 
其中蓝色矩阵的每一行代表一个对应的输入向量。此外,图中还有三个矩阵
W q , W k , W v \ W_q, W_k, W_v \  Wq,Wk,Wv 
它们负责将输入信息 ( H ) 依次转换到相应的查询空间
Q = [ q 1 , q 2 ] \ Q = [q_1, q_2] \  Q=[q1,q2] 
键空间
K = [ k 1 , k 2 ] \ K = [k_1, k_2] \  K=[k1,k2] 
值空间
V = [ v 1 , v 2 ] \ V = [v_1, v_2] \  V=[v1,v2] 
[ q 1 = h 1 W q , q 2 = h 2 W q ] ⇒ Q = H W q [ k 1 = h 1 W k , k 2 = h 2 W k ] ⇒ K = H W k [ v 1 = h 1 W v , v 2 = h 2 W v ] ⇒ V = H W v \begin{align*} [q_1 = h_1W_q, q_2 = h_2W_q] & \Rightarrow Q = HW_q \\ [k_1 = h_1W_k, k_2 = h_2W_k] & \Rightarrow K = HW_k \\ [v_1 = h_1W_v, v_2 = h_2W_v] & \Rightarrow V = HW_v \\ \end{align*} [q1=h1Wq,q2=h2Wq][k1=h1Wk,k2=h2Wk][v1=h1Wv,v2=h2Wv]Q=HWqK=HWkV=HWv

在获得输入信息在不同空间的表示 ( Q, K, ) 和 ( V ) 后,我们以 ( h_1 ) 为例,计算这个位置的一个 attention 输出向量 ( \text{context}_1 ),它代表在这个位置模型应该重点关注的内容,如图3所示。

在这里插入图片描述

可以看到,在获得原始输入 ( H ) 在查询空间、键空间和值空间的表示 ( Q, K, ) 和 ( V ) 后,计算 ( q_1 ) 在 ( h_1 ) 和 ( h_2 ) 的分数 ( s_{11} ) 和 ( s_{12} ),这里的分数计算采用的是点积操作。

然后将分数进行缩放并使用 softmax 进行归一化,获得在 ( h_1 ) 这个位置的注意力分布: ( a_{11} ) 和 ( a_{12} ),它们代表模型当前在 ( h_1 ) 这个位置需要对输入信息 ( h_1 ) 和 ( h_2 ) 的关注程度。最后,根据该位置的注意力分布对 ( v_1 ) 和 ( v_2 ) 进行加权平均,获得最终在 ( h_1 ) 这个位置的 Attention 向量 ( \text{context}_1 )。

同理,可以获得第2个位置的 Attention 向量 ( \text{context}_2 ),或者继续扩展输入序列获得更多的 ( \text{context}_i ),原理都是一样的。

讨论到这里,相信你已经知道什么是注意力机制了,但为了更正式一点,我重新组织一下注意力机制的计算过程。

自注意力机制的计算过程可以分为以下几个步骤:

  • 将每个词转换为一个向量。
  • 计算每个词与其他词之间的相似度。
  • 使用相似度来计算每个词的注意力权重。
  • 使用注意力权重来加权每个词的向量。

最终,每个词都会得到一个加权后的向量,这个向量包含了该词与其他词的关系。

假设当前有输入信息 ( H = [h_1, h_2, …, h_n] ),我需要使用自注意力机制获取每个位置的输出

context = [ context 1 , context 2 , . . . , context n ] \text{context} = [\text{context}_1, \text{context}_2, ..., \text{context}_n] context=[context1,context2,...,contextn]
首先,需要将原始输入映射到查询空间 ( Q )、键空间 ( K ) 和值空间 ( V ),相关计算公式如下:

Q = H W q = [ q 1 , q 2 , . . . , q n ] K = H W k = [ k 1 , k 2 , . . . , k n ] V = H W v = [ v 1 , v 2 , . . . , v n ] \begin{align*} Q & = HW_q = [q_1, q_2, ..., q_n] \\ K & = HW_k = [k_1, k_2, ..., k_n] \\ V & = HW_v = [v_1, v_2, ..., v_n] \\ \end{align*} QKV=HWq=[q1,q2,...,qn]=HWk=[k1,k2,...,kn]=HWv=[v1,v2,...,vn]

接下来,计算每个位置的注意力分布,并将相应结果进行加权求和:

context i = ∑ j = 1 n softmax ( s ( q i , k j ) ) ⋅ v j \text{context}_i = \sum_{j=1}^n \text{softmax}(s(q_i, k_j)) \cdot v_j contexti=j=1nsoftmax(s(qi,kj))vj

其中 ( s(q_i, k_j) ) 是经过上述点积、缩放后的分数值。

最后,为了加快计算效率,可以使用矩阵计算的方式,一次性计算出所有位置的 Attention 输出向量:

context = softmax ( Q K T / d ) V \text{context} = \text{softmax}(QK^T/\sqrt{d})V context=softmax(QKT/d )V

这就是自注意力机制(self-Attention)的原理。

在进行自注意力计算时,GPU处理器的并行计算能力就可以大显身手了。以一个批次大小为64的例子为例,GPU处理器能够同时计算64个样本中每个样本的自注意力,加速整个模型的训练过程。

# 伪代码示例:Transformer中的自注意力计算
import torch
import torch.nn.functional as Fdef self_attention(Q, K, V):attention_scores = torch.matmul(Q, K.transpose(-2, -1)) / torch.sqrt(Q.size(-1))attention_weights = F.softmax(attention_scores, dim=-1)output = torch.matmul(attention_weights, V)return output# 在GPU上进行自注意力计算
Q_gpu = Q.to('cuda')
K_gpu = K.to('cuda')
V_gpu = V.to('cuda')output_gpu = self_attention(Q_gpu, K_gpu, V_gpu)

这里,Q、K、V是输入序列的查询、键和值的表示,通过GPU上的矩阵乘法和softmax计算,同时处理多个样本的注意力权重。

多头注意力的并行化

Transformer模型中还引入了多头注意力机制,通过并行计算多个注意力头,提高了模型的表示能力。GPU处理器的并行计算能力极大地加速了多头注意力的计算,每个注意力头都可以在不同的GPU核心上独立计算。

# 伪代码示例:Transformer中的多头注意力计算
class MultiHeadAttention(torch.nn.Module):def __init__(self, num_heads, hidden_size):# 初始化多个注意力头self.attention_heads = [self_attention(Q, K, V) for _ in range(num_heads)]def forward(self, input):# 并行计算多个注意力头outputs = [attention_head(input) for attention_head in self.attention_heads]# 合并多个头的输出output = torch.cat(outputs, dim=-1)return output# 在GPU上进行多头注意力计算
multihead_attention_gpu = MultiHeadAttention(num_heads=8, hidden_size=256).to('cuda')
output_gpu = multihead_attention_gpu(input_gpu)

在上述示例中,每个注意力头的计算可以独立地在GPU上进行,最后再通过GPU处理器的并行计算能力将它们合并。

CUDA流的优化

GPU通过CUDA流式处理的机制实现了高效的计算,这在Transformer模型的训练中尤为重要。例如,当进行反向传播时,GPU能够异步执行计算任务,从而实现数据的流水线处理,极大地提升了大模型的整体训练效率。

# 伪代码示例:反向传播过程中的CUDA流处理
loss.backward()
optimizer.step()# 在GPU上异步执行计算任务
torch.cuda.synchronize()

上述代码中,反向传播和优化步骤进行了异步执行,通过torch.cuda.synchronize()等待计算完成,确保了计算的正确性。

GPU在Transformer 大模型中的协同计算处理任务中功不可没,其在架构和功能设计中体现出的强大的并行计算、流式处理和多头注意力的优势,堪称黑魔法,为AI 大模型的深度学习任务提供了强大的堪称黑魔法般的加持。

通过以上的例子来理解 GPU 在 Transformer 模型中的运行和处理机制,我们能够更加深入地体会深度学习和大语言模型这一魔法舞台的精彩。

正是在GPU的协同处理的魔法加持下,Transformer模型才得以在自然语言处理等领域创造出一系列令人瞩目的成果,极大地推进了诸如ChatGPT、Claude、Gemini、LLama、Vicuna 等杰出的生成式 AI 大模型的研究进展和部署应用。

相关文章:

AI大语言模型学习笔记之三:协同深度学习的黑魔法 - GPU与Transformer模型

Transformer模型的崛起标志着人类在自然语言处理(NLP)和其他序列建模任务中取得了显著的突破性进展,而这一成就离不开GPU(图形处理单元)在深度学习中的高效率协同计算和处理。 Transformer模型是由Vaswani等人在2017年…...

c++阶梯之auto关键字与范围for

auto关键字&#xff08;c11&#xff09; 1. auto关键字的诞生背景 随着程序的逐渐复杂&#xff0c;程序代码中用到的类型也越来越复杂。譬如&#xff1a; 类型难以拼写&#xff1b;含义不明确容易出错。 比如下面一段代码&#xff1a; #include <string> #include &…...

第八篇:node模版引擎Handlebars及他的高级用法(动态参数)

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! ​ 目录 &#x1f4d8; 引言&#xff1a; &#x1f…...

css3 属性 backface-visibility 的实践应用

backface-visibility 是一个用于控制元素在面对屏幕不同方向时的可见性的CSS3特性。它有两个可能的值&#xff1a; visible&#xff1a;当元素不面向屏幕&#xff08;即背面朝向用户&#xff09;时&#xff0c;元素的内容是可以被看到的。hidden&#xff1a;当元素不面向屏幕…...

嵌入式学习第十七天

C语言小项目&#xff1a; 制作俄罗斯方块小游戏&#xff08;全部&#xff09; 主函数部分 #include <stdio.h> #include <unistd.h> #include <string.h> #include <signal.h> #include <stdlib.h> #include <time.h> #include "b…...

使用Python的Turtle模块简单绘制烟花效果

import turtle import random# 初始化屏幕 screen turtle.Screen() screen.bgcolor("black") screen.title("烟花模拟")# 创建一个Turtle来绘制烟花 firework turtle.Turtle() firework.hideturtle() firework.speed(0) # 设置绘图速度为最快# 绘制烟花…...

数学建模-退火算法和遗传算法

退火算法和遗传算法 一&#xff0e;退火算法 退火算法Matlab程序如下&#xff1a; [W]xlsread(D:100个目标经度纬度);>> x[W(:,1)];>> y[W(:,2)];>> w[x y];;d1[70, 40];>> w[d1;w;d1]ww*pi/180;%角度化成弧度dzeros(102);%距离矩阵初始化for i1:101…...

Qt开源版 vs 商业版 详细比较!!!!

简单整理Qt开源版与商业版有哪些差别&#xff0c;仅供参考。 简单对比 开源版商业版许可证大部分采用对商业使用不友好的LGPLv3具备商业许可证保护代码专有许可证相关大部分模块使用LGPLv3和部分模块使用GPL组成仅第三方开源组件使用Qt的其他许可证Qt模块功能支持支持技术支持…...

华为云CodeArts Snap荣获信通院优秀大模型案例及两项荣誉证书

2024年1月25日&#xff0c;中国人工智能产业发展联盟智能化软件工程工作组&#xff08;AI for Software Engineering&#xff0c;下文简称AI4SE&#xff09;在京召开首届“AI4SE创新巡航”活动。在活动上&#xff0c;华为云大模型辅助系统测试代码生成荣获“2023AI4SE银弹优秀案…...

小程序的应用、页面、组件生命周期(超全版)

小程序生命周期 应用的生命周期 onLaunch: 初始化小程序完成时触发&#xff0c;且全局只触发一次&#xff1b; onShow: 小程序初始化完成&#xff08;启动&#xff09;或从后台切换到前台显示时触发&#xff1b; onHide: 小程序从前台切换到后台隐藏时触发&#xff08;如切换…...

TCP四次握手

TCP 协议在关闭连接时&#xff0c;需要进行四次挥手的过程&#xff0c;主要是为了确保客户端和服务器都能正确地关闭连接。 # 执行流程 四次挥手的具体流程如下&#xff1a; 客户端发送 FIN 包&#xff1a;客户端发送一个 FIN 包&#xff0c;其中 FIN 标识位为 1&#xff0c…...

EBC金融英国CEO:高波动性周期下,如何寻找市场的稳定性?

利率主导的市场&#xff0c;将在2024年延续。目前&#xff0c;固收市场对于降息的定价&#xff0c;正通过利率传导至不同资产中。尽管市场迫切利用通胀去佐证降息&#xff0c;但各国央行仍囿于通胀目标的政策桎梏。政策和市场预期的博弈将继续牵动市场脉搏&#xff0c;引发价格…...

C++ Web 编程

什么是 CGI&#xff1f; 公共网关接口&#xff08;CGI&#xff09;&#xff0c;是一套标准&#xff0c;定义了信息是如何在 Web 服务器和客户端脚本之间进行交换的。CGI 规范目前是由 NCSA 维护的&#xff0c;NCSA 定义 CGI 如下&#xff1a;公共网关接口&#xff08;CGI&…...

docker笔记整理

Docker 安装 添加yum源 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 安装docker yum -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin 启动docker systemctl start docker 查看docker状态 s…...

什么是git,怎样下载安装?

简介&#xff1a; 应用场景&#xff1a; 应用场景&#xff1a;团队企业开发 作用&#xff1a; 安装&#xff1a; 1.网址&#xff1a;Git - Downloads 很卡很慢 2.可以选择镜像网站下载&#xff08;推荐&#xff09; CNPM Binaries Mirror...

Camille-学习笔记-测试流程和测试设计

## 测试用例学习路线 startmindmap * 测试用例 ** 黑盒测试方法论 *** 等价类 *** 边界值 *** 因果图 *** 判定表 *** 场景法 *** 基于模型的测试 ** 白盒测试方法论 ** 测试用例基础概念 ** 测试用例设计 ** 面试测试用例设计 ** 常用测试策略与测试手段 endmindmap **测试用…...

【Python笔记-设计模式】建造者模式

一、说明 又称生成器&#xff0c;是一种创建型设计模式&#xff0c;使其能够分步骤创建复杂对象。允许使用相同的创建代码生成不同类型和形式的对象。 (一) 解决问题 对象的创建问题&#xff1a;当一个对象的构建过程复杂&#xff0c;且部分构建过程相互独立时&#xff0c;可…...

【LVGL源码移植】

LVGL源码移植 ■ LVGL源码移植一&#xff1a;下载LVGL源码二&#xff1a;修改LVGL文件夹1: 将这5个文件&#xff0c;复制到一个新的文件夹2: 简化文件&#xff0c;减少内存消耗&#xff08;去除不必要的文件&#xff09;3: 为了规范化&#xff0c;我们将下列文件进行重命名 三&…...

双非本科准备秋招(14.2)—— 进程与线程

进程 进程是运行着的程序&#xff0c;是程序在操作系统的一次执行过程&#xff0c;进程是操作系统分配资源的基本单位。 启动一个java程序&#xff0c;操作系统就会创建一个java进程 进程也可以看作一个程序的实例&#xff0c;大部分程序可以运行多个实例进程&#xff0c;比如记…...

数据结构和算法笔记5:堆和优先队列

今天来讲一下堆&#xff0c;在网上看到一个很好的文章&#xff0c;不过它实现堆是用Golang写的&#xff0c;我这里打算用C实现一下&#xff1a; Golang: Heap data structure 1. 基本概念 满二叉树&#xff08;二叉树每层节点都是满的&#xff09;&#xff1a; 完全二叉树&a…...

第8章 SpringBoot任务管理

学习目标 熟悉SpringBoot整合异步任务的实现 熟悉SpringBoot整合定时任务的实现 熟悉SpringBoot整合邮件任务的实现 开发web应用时,多数应用都具备任务调度功能。常见的任务包括异步任务,定时任务和发邮件任务。我们以数据库报表为例看看任务调度如何帮助改善系统设计。报表可…...

Qt5 基于OpenGL实现六轴机械臂三维仿真

需求 在Qt中通过OPenGL方式加载三维模型STL文件&#xff0c;然后将多个结构的STL文件类型的模型进行组装&#xff0c;形成6轴机械臂三维模型的显示&#xff0c;并且可以对每个关节进行关节角度的控制。 新建一个C类STLFileLoader&#xff0c;用于加载STL文件&#xff0c;并进…...

路由进阶

文章目录 1.路由的封装抽离2.声明式导航 - 导航链接3.声明式导航-两个类名自定义匹配的类名 4.声明式导航 - 跳转传参查询参数传参动态路传参两种传参方式的区别动态路由参数可选符 5.Vue路由 - 重定向6.Vue路由 - 4047.Vue路由 - 模式设置8.编程式导航 - 两种路由跳转9.编程式…...

分类预测 | Matlab实现SCN-Adaboost随机配置网络模型SCN的Adaboost数据分类预测/故障识别

分类预测 | Matlab实现SCN-Adaboost随机配置网络模型SCN的Adaboost数据分类预测/故障识别 目录 分类预测 | Matlab实现SCN-Adaboost随机配置网络模型SCN的Adaboost数据分类预测/故障识别分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现SCN-Adaboost随机配置网…...

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之TextPicker组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之TextPicker组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、TextPicker组件 TextClock组件通过文本将当前系统时间显示在设备上。支持不…...

linux中vim的操作

(码字不易&#xff0c;关注一下吧w~~w) 命令模式&#xff1a; 当我们按下esc键时&#xff0c;我们会进入命令模式&#xff1b;当使用vi打开一个文件时也是进入命令模式。 光标移动&#xff1a; 1 保存退出&#xff1a;ZZ 2 代码格式化&#xff1a;ggG 3 光标移动&#xff…...

《统计学习方法:李航》笔记 从原理到实现(基于python)-- 第5章 决策树

文章目录 第5章 决策树5.1 决策树模型与学习5.1.1 决策树模型5.1.2 决策树与if-then规则5.1.3 决策树与条件概率分布5.1.4 决策树学习5.2 特征选择5.2.1 特征选择问题5.2.2 信息增益5.2.3 信息增益比5.3.1 ID3算法5.3.2 C4.5的生成算法5.4 决策树的剪枝5.5 CART算法5.5.1 CART生…...

【C++11(一)】列表初始化and右值引用

一、 统一的列表初始化 1.1 &#xff5b;&#xff5d;初始化 在C98中&#xff0c;标准允许 使用花括号{}对数组或者结构体元素 进行统一的列表初始值设定 C11扩大了用大括号 括起的列表(初始化列表)的使用范围 使其可用于所有的内置类型和 用户自定义的类型 使用初始化列表时…...

为什么SSL会握手失败?SSL握手失败原因及解决方案

随着网络安全技术的发展&#xff0c;SSL证书作为网站数据安全的第一道防线&#xff0c;被越来越多的企业选择。SSL证书使用的是SSL协议&#xff0c;而SSL握手是SSL协议当中最重要的一部分。当部署SSL证书时&#xff0c;如果服务器和客户端之间无法建立安全连接&#xff0c;就会…...

STM32——智能小车

STM32——智能小车 硬件接线 B-1A – PB0 B-1B – PB1 A-1A – PB2 A-1B – PB10 其余接线参考51单片机小车项目。 1.让小车动起来 motor.c #include "motor.h" void goForward(void) {// 左轮HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);HAL_GPIO…...