一文搞懂NLP框架之RNN、LSTM、Transformer结构原理!

NLP领域中,特征提取可谓是经历了显著的“变迁”与发展。回首过往,RNN曾以其独特的序列建模能力一度引领潮流,如今正如同明日黄花,逐步淡出历史舞台。紧接着,LSTM以解决长时依赖问题的独特设计展现出强大的生命力,虽已非最前沿,却仍老骥伏枥,若能进一步优化,其潜力不可小觑。

而今,Transformer架构如日中天,凭借自注意力机制彻底革新了特征提取的方法,已在NLP诸多任务中发挥着中流砥柱的作用。

本文笔者将深入浅出剖析RNN、LSTM以及Transformer的核心结构原理,一起见证算法是怎样做到一浪更比一浪强的。

RNN

为什么会出现RNN?

要搞明白这个问题,我们是不是可以先回想一下,在RNN之前的模型还有什么可改进点?

没错,从这里着手,问题就将会迎刃而解了。细想BP、CNN(卷积神经网络),可以当做能够拟合任意函数的黑盒子,只要训练数据足够,给定特定的x,就能得到期望的y。结构图如下:

在这里插入图片描述

但是不难发现,它们都只能单独的处理一个个的输入,前一个输入和后一个输入是完全没有关系的。而我们实际应用中肯定有需要处理序列信息的任务吧,即就是前面的输入和后面的输入是有关系的。

例如,当我们理解某句话意思时,孤立的理解每个词肯定是不够的,而是需要处理这些词连接起来的整个序列,“词本无意,意由境生”,也正是此意。还有,处理视频的时候,当前也不能只单独的分析每一帧,而是要分析这些帧连接起来的整个序列。

为了解决一些这样类似的问题,能够更好的处理序列的信息,RNN就诞生了。

RNN解释

我们通常所说的RNN实际上有两种,一种是Recurrent Neural Networks,即循环神经网络,一种是Recursive Neural Networks,即递归神经网络。

循环神经网络,是一种时间上进行线性递归的神经网络,用于处理序列数据

相比于传统的神经网络,它可以处理序列变化的数据。比如某个词汇的含义根据上下文内容不同而有所不同,RNN则可以很好地解决这类问题。

递归神经网络(Recursive Neural Networks)被视为循环神经网络的推广,它是一种在结构上进行递归的神经网络,常用于NLP中的序列学习,它的输入数据本质不一定是时序的,但结构却往往更加复杂。

我们这里只说循环神经网络RNN

首先来看一个简单的RNN,它由输入层、一个隐藏层和一个输出层组成:

在这里插入图片描述

如果将W的那个带箭头的圈去掉,它就变成了最普通的全连接神经网络。

  • x是一个向量,它表示输入层的值。
  • s是一个向量,它表示隐藏层的值(这里隐藏层面画了一个节点,你也可以想象这一层其实是多个节点,节点数与向量s的维度相同)。
  • U是输入层到隐藏层的权重矩阵。
  • o也是一个向量,它表示输出层的值。
  • V是隐藏层到输出层的权重矩阵。

那么,现在我们来看看W是什么。循环神经网络的隐藏层的值s不仅仅取决于当前这次的输入x,还取决于上一次隐藏层的值s。而权重矩阵W就是隐藏层上一次的值作为这一次的输入的权重。

具体如下图所示。可以清楚的看到,上一时刻的隐藏层是如何影响当前时刻的隐藏层的。

在这里插入图片描述

当然我们也可以将上面的图按时间线展开,循环神经网络也可以画成下面的样子:

在这里插入图片描述

现在就可以清晰看出,该网络在 t t t时刻接收输入 x t x_t xt,隐藏层的值 s t s_t st由上一时刻的 s t − 1 s_{t-1} st1 x t x_t xt的权重矩阵W决定。

公式表示如下:

O t = g ( V ∗ S t ) O_t = g(V*S_t) Ot=g(VSt)

S t = f ( U ∗ X t + W ∗ S t − 1 ) S_t = f(U*X_t+W*S_{t-1}) St=f(UXt+WSt1)

f即为RNN的激活函数,通常是tanh。用代码表示RNN如下:

class RNN:
   def step(self, x):
      self.h = np.tanh(np.dot(self.W_hh, self.h) + np.dot(self.W_xh, x)) #更新隐藏层
      y = np.dot(self.W_hy, self.h) #获得输出
   return y

RNN结构

根据输入输出长度的不同,可以将RNN结构分为如下图所示五类。

在这里插入图片描述

one-to-one

在这里插入图片描述

最基本的单层网络,本质也即是全连接神经网络。输入是x,经过变换Wx+b和激活函数f得到输出y。

one-to-many

输入是一个单独的值,输出是一个序列。此时,有两种建模方式:

  • 只在其中的某一个序列进行计算,以序列第一个进行输入计算为例:

在这里插入图片描述

  • 把输入信息X作为每个阶段的输入:

在这里插入图片描述

通常用于图像生成文字(输入的X就是图像的特征,输出的y序列就是一段句子,例如看图说话等)、图像生成语音或音乐等领域。

many-to-one

输入是一个序列,输出是一个单独的值。此时,通常只在最后一个h上进行输出变换就可以了。

在这里插入图片描述

这种结构通常用来处理序列分类问题。如输入一段文字判别它所属的类别,输入一个句子判断其情感倾向,输入一段视频并判断它的类别等等。

many-to-many

最经典的RNN结构,输入输出都是等长的序列数据。

假设输入为X=(x1, x2, x3, x4),每个x是一个单词的词向量。

在这里插入图片描述

为了建模序列问题,RNN引入了隐状态h(hidden state)的概念,h可以对序列形的数据提取特征,接着再转换为输出。先从h1的计算开始看:

在这里插入图片描述

h2的计算和h1类似。要注意的是,在计算时,每一步使用的参数U、W、b都是一样的,也就是说每个步骤的参数都是共享的,这是RNN的重要特点。

在这里插入图片描述

依次计算剩下来的(使用相同的参数U,W,b):

在这里插入图片描述

这里为了方便起见,只画出序列长度为4的情况,实际上,这个计算过程可以无限地持续下去。得到输出值的方法就是直接通过h进行计算:

在这里插入图片描述

正如之前所说,一个箭头就表示对对应的向量做一次类似于f(Wx+b)的变换,这里的这个箭头就表示对h1进行一次变换,得到输出y1。

剩下的输出类似进行(使用和y1同样的参数V和c):

在这里插入图片描述

这也就是最经典的RNN结构,它的输入是x1, x2, …xn,输出为y1, y2, …yn,也就是说,**输入和输出序列必须要是等长的。**由于这个限制的存在,经典RNN的适用范围比较小,但也有一些问题适合用经典的RNN结构建模,如:

计算视频中每一帧的分类标签。因为要对每一帧进行计算,因此输入和输出序列等长。

many-to-many

还有一种many-to-one结构,输入、输出为不等长的序列。

这种结构是Encoder-Decoder,也叫Seq2Seq,是RNN的一个重要变种。原始的many-to-many的RNN要求序列等长,然而我们遇到的大部分问题序列都是不等长的,如机器翻译中,源语言和目标语言的句子往往并没有相同的长度。

为此,Encoder-Decoder结构先将输入数据编码成一个上下文语义向量c。 其中,语义向量c可以有多种表达式,具体如下:

① c = h 4 ①c=h_4 c=h4

② c = q ( h 4 ) ②c=q(h_4) c=q(h4)

③ c = q ( h 1 , h 2 , h 3 , h 4 ) ③c=q(h_1,h_2,h_3,h_4) c=q(h1,h2,h3,h4)

其中,最简单的方法就是把Encoder的最后一个隐状态赋值给c(①),另外还可以对最后的隐状态做一个变换得到c(②),也可以对所有的隐状态做变换(③)。

拿到c之后,再用另一个RNN网络对其进行解码,这部分网络称为Decoder。Decoder的RNN可以与Encoder的一样,也可以不一样。具体做法就是将c当做之前的初始状态h0输入到Decoder中:

在这里插入图片描述

也可以将c当做每一步的输入。

在这里插入图片描述

由于Encoder-Decoder结构不限制输入和输出的序列长度,因此应用的范围非常广泛,如机器翻译、文本摘要、阅读理解、语音识别等。

RNN缺陷

同普通卷积神经网络类似的是,RNN的优化也使用的是反向传播,不过是带时序的版本,即BPTT(Backpropagation Through Time),它与BP的原理完全一样,只不过计算过程与时间有关。

与普通的反向传播算法一样,它重复地使用链式法则,区别在于损失函数不仅依赖于当前时刻的输出层,也依赖于下一时刻。所以参数W在更新梯度时,必须考虑当前时刻的梯度和下一时刻的梯度,传播示意图如下:

在这里插入图片描述

而计算梯度时,t时刻的导数会传播到t-1,t-2,… ,1时刻,这样就有了连乘的系数。

连乘一直带来了两个问题:梯度爆炸和消失。 而且,在前向过程中,开始时刻的输入对后面时刻的影响越来越小,这就是长距离依赖问题。这样依赖,RNN就失去了“记忆”能力。

为了缓解这些问题,LSTM便应运而生。

LSTM

为什么会出现LSTM?

这个在上一章节末刚刚谈到的,因为RNN会导致"梯度消失"和"梯度爆炸"问题,学习能力有限,在实际任务中的效果很难达到预期。为了增强RNN的学习能力,缓解网络的梯度消失等问题,LSTM(Long short-term memory, LSTM)神经网络便横空出世了。它可以对有价值的信息进行长期记忆,不仅减小循环神经网络的学习难度,并且由于其增加了长时记忆,在一定程度上也缓解了梯度消失的问题。(注:梯度爆炸的问题用一般的梯度裁剪方法就可以解决)。

LSTM VS RNN

RNN都具有一种重复神经网络模块的链式的形式,在标准的RNN中,这个重复的模块只有一个非常简单的结构,例如一个tanh层。

在这里插入图片描述

而在LSTM中的重复模块中,不同于RNN,这里有四个神经网络层,以一种非常特殊的方式进行交互:

在这里插入图片描述

LSTM核心解释

LSTM通过“门”结构来删除或者增加信息到细胞状态cell state。这个cell state承载着之前所有状态的信息,每到新的时刻,就有相应的操作来决定舍弃什么旧信息以及添加什么新信息。这个状态与隐藏层状态h不同,在更新过程中,它的更新是缓慢的,而隐藏层状态h的更新是迅速的。

LSTM的网络结构图如下,输入包括 h t − 1 h_{t-1} ht1 x t x_t xt,输出 h t h_t ht,状态为 c t − 1 c_{t-1} ct1, c t c_t ct

在这里插入图片描述

遗忘门与遗忘阶段

遗忘门决定从上一时刻的状态 c t − 1 c_{t-1} ct1中丢弃哪些信息。它通过将上一状态的输出 h t − 1 h_{t-1} ht1和当前状态输入信息 x t x_t xt作为输入,经过一个Sigmoid激活函数,生成一个在[0,1]范围内的遗忘因子。当遗忘门输出为0时,表示完全丢弃对应部分的细胞状态;输出为1时,则表示完全保留。这个阶段完成了对上一个节点cell state进行选择性忘记。

在这里插入图片描述

输入门与选择记忆阶段

输入门决定哪些新的信息应当加入到细胞状态中。同样地,将上一状态的输出 h t − 1 h_{t-1} ht1和当前状态输入信息 x t x_t xt作为输入,通过sigmoid函数生成一个在[0,1]之间的保留因子it,表示信息应保留的程度。同时,还有一个“候选细胞状态”通过上一状态的输出 h t − 1 h_{t-1} ht1、当前状态输入信息 x t x_t xt以及tanh激活函数生成,这个候选状态包含了新的潜在信息。

新的细胞状态 C t C_t Ct是上一时刻细胞状态经过遗忘门过滤后的信息 f t ∗ C t − 1 f_t*C{t-1} ftCt1与当前时刻经过输入门过滤后的信息 i t ∗ C t i_t*C_t itCt的加权和,这样就实现了对历史信息的选择性保留和新信息的选择性添加。它将用于产生下一状态的隐藏层 h t h_t ht,也就是当前单元的输出。

在这里插入图片描述

在这里插入图片描述

输出门与输出阶段

输出门决定如何将当前细胞状态 C t C_t Ct转换为当前时刻的隐藏状态 h t h_t ht,即要将何种信息输出给下一个时间步或其他层使用。它同样通过Sigmoid函数处理 h t − 1 h_{t-1} ht1 x t x_t xt得到一个在[0,1]范围内的输出因子 O t O_t Ot
然后,细胞状态 C t C_t Ct先经过tanh函数压缩到[-1,1]范围内并提取有用信息,再与输出门的输出结果 O t O_t Ot相乘,最终生成LSTM block当前时刻的隐藏状态 h t h_t ht

在这里插入图片描述

LSTM缺陷

LSTM的门结构能够有效减缓长序列问题中可能出现的梯度消失或爆炸,虽然并不能杜绝这种现象,但在更长的序列问题上表现优于传统RNN。

但是,LSTM内部结构相对较复杂, 因此训练效率在同等算力下较传统RNN低很多。

Transformer

为什么会出现Transformer?

对RNN和LSTM进行一番分析之后,不难看出,二者还共同存在一个问题:

效率:均需要逐个词处理,后一个词要等到前一个词的隐藏状态输出以后才能开始处理,而不能完全并行地处理序列中的词。

终于,2017年Google在神作《Attention is all you need》提出了Transformer架构,通过自注意力机制彻底摆脱了RNN的时间顺序约束,实现了完全并行化的序列处理。

Transfromer是一个N进N出的结构,也就是说每个Transformer单元相当于一层的RNN层,接收一整个句子所有词作为输入,然后为句子中的每个词都做出一个输出。但是与RNN不同的是,Transformer能够同时处理句子中的所有词,并且任意两个词之间的操作距离都是1,这么一来就很好地解决了上面提到的RNN的效率问题和距离问题。

Transformer精髓

Transformer的关键创新在于其自注意力机制(Self-Attention Mechanism),这是其架构的核心基石。它允许模型在生成当前词的表示时,不仅考虑当前位置的信息,还能充分考虑整个输入序列所有词的上下文信息,并对其进行加权融合。这样使得,模型可以更好地捕捉词语之间的依赖关系和长距离依赖。

注意力机制的计算效率通过使用矩阵运算和并行计算得到提高。

除此之外,Transformer还结合了残差连接(Residual Connections)和层归一化(Layer Normalization)技术,这两种技术的引入极大提升了模型训练的稳定性和收敛速度。

以机器翻译任务为例,下面这句话中,通过理解上下文可以看出,it指代的是The animal,而Tranformer就能很好地帮我们得出这个结论。

在这里插入图片描述

Transformer架构

宏观层面

首先将这个模型可以看成是一个黑箱操作。在机器翻译中,就是输入一种语言,经Transformer输出另一种语言。

在这里插入图片描述

拆开这个黑箱,可以看到它的本质就是一个Encoder-Decoder结构,由编码组件、解码组件和它们之间的连接组成。

在这里插入图片描述

Encoders由6个Encoder block组成,同样Decoders是6个Decoder block组成,每个block结构相同,但不共享参数。与所有的生成模型相同的是,编码器的输出会作为解码器的输入,如图所示:

在这里插入图片描述

微观层面

Transformer内部结构如下图所示,由编码器(Encoder)和解码器(Decoder)两大部分组成。

左边的Encoder最后演化成了如今鼎鼎大名的Bert,右边的Decoder则变成了无人不知的GPT模型。

在这里插入图片描述

再更细化可分为输入、输出、编码器、解码器四部分。

输入

输入部分包含:

  • 源文本嵌入层及其位置编码器
  • 目标文本嵌入层及其位置编码器

在这里插入图片描述

无论源文本嵌入还是目标文本嵌入,都是为了将文本中词汇的数字表示转换为向量表示。

在Embedding层后加入位置编码器,则是将词汇位置不同可能会产生不同语义的信息加入到词嵌入张量中,以弥补位置信息的缺失。

输出

输出部分包含:

  • 线性层:通过对上一步的线性变化得到指定维度的输出,也就是转换维度的作用。
  • softmax层:使最后一维的向量中的数字缩放到0~1的概率值域内, 并满足他们的和为1。

在这里插入图片描述

编码器

在这里插入图片描述

  • 由N个编码器层堆叠而成。
  • 每个编码器层由两个子层连接结构组成。
  • 第一个子层连接结构包括一个多头自注意力子层和归一化层以及一个残差连接。
  • 第二个子层连接结构包括一个前馈全连接子层和归一化层以及一个残差连接。
解码器

在这里插入图片描述

  • 由N个解码器层堆叠而成。
  • 每个解码器层由三个子层连接结构组成。
  • 第一个子层连接结构包括一个多头自注意力子层和归一化层以及一个残差连接。
  • 第二个子层连接结构包括一个多头注意力子层和归一化层以及一个残差连接。
  • 第三个子层连接结构包括一个前馈全连接子层和归一化层以及一个残差连接。

Transformer优缺点

优点

  • 并行处理:Transformer能够高效进行并行计算,提高了训练速度。
  • 全局信息捕获:可以通过自注意力机制获取全局上下文信息,这对于理解复杂的语言结构至关重要。
  • 长距离依赖:通过自注意力机制,Transformer能够直接捕获任意两个输入位置之间的依赖关系,有效地解决了长距离依赖问题。

缺点

  • 计算资源消耗:由于自注意力机制涉及到大规模的矩阵运算,尤其是全尺寸的注意力矩阵,这可能导致Transformer在计算和内存资源上的需求较高。

可以说,RNN、LSTM和Transformer分别代表了不同阶段NLP特征提取技术的演进历程,它们各自的特点与优势推动了NLP乃至整个人工智能领域向前发展,不断刷新着我们对自然语言理解和生成能力的认知边界。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

STM32中C编程引入C++程序

C具备类的创建思想很实用于实际场景多相似性的框架搭建;同种类型或相似类型的C的优势明显因此进行相互嵌套使用 需要在C中使用C类的话,你可以通过C的“extern "C"”语法来实现。这允许你在C代码中使用C的链接方式,而在C代码中使用…

SCP收容物051~060​

注 :此文接SCP收容物041~050​,本文只供开玩笑 ,与steve_gqq_MC合作。 --------------------------------------------------------------------------------------------------------------------------------- 目录 SCP-051 SCP-052 SCP-053 SCP-054 SCP-0…

【C语言】青蛙跳台阶问题

题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。现求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 题目分析: 当 n 等于 1 时,青蛙只能跳一级台阶到达,因此只有一种跳法,直接返回 1。当 n 等于 2 时…

万字源码解析!彻底搞懂 HashMap【二】:putVal 方法和 resize 方法(重点)

HashMap 的底层原理和扩容机制一直都是面试的时候经常被问到的问题,同时也是集合源码中最难阅读的一部分😢,之前更新的 ArrayList 源码阅读收获了很多朋友的喜欢,也给了我很多自信;本次我准备完成一个关于 HashMap 源码…

CST操作教程|精简仿真结果容量和隐藏结构的加密保护功能

使用Archive As精简仿真结果容量 结果保持不变,缩小仿真结果容量的方法。 File > Project > Archive As simulation后保存数据时仿真文件容量太大很是让人头大。为什么文件容量变这么大呢?通常不是因为CST图标形状的.cst文件造成的,而是因为生…

C++set和map详细介绍

文章目录 前言一、关联式容器和序列式容器二、set1.set文档介绍2.set成员函数1.构造函数2.迭代器3.容量4.修改5.其他 三.multiset四.map1.map文档介绍2.map成员函数1.构造2.insert插入3.count4.迭代器5.【】和at 五.multimap总结 前言 在本篇文章中,我们将会学到关…

DC-DC芯片D1509适用于工控主板、TV板卡、安卓主板、车载功放电源等产品方案应用。

一、应用领域 适用于工控主板、TV板卡、安卓主板、车载功放电源等产品方案应用。 二、功能介绍 D1509是芯谷科技推出的一款输入耐压40V、输出电压1.23-37V可调、输出电流最大2.0A的高效率、高精度DC-DC芯片,其输出电压有固定3.3V、5.0V和12.0V的版本&#xff…

BM96 主持人调度(二)(贪心算法)

一开始写的时候忘了给start、end数组赋值了 import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** 计算成功举办活动需要多少名主持人* param n int整型 有n个活动* param start…

C#:用定时器监控定时器,实现中止定时器正在执行的任务,并重启

Windows服务中使用的比较多的是定时器,但这种定时任务有个比较大的毛病:有时会莫名其妙地停止执行(长时间执行不完,假死),必须得手工重启Windows服务才能恢复正常。这个就太麻烦了。 有没有办法来实现定时…

Vue3快速上手 详细内容

Vue3快速上手 1.Vue3简介 2020年9月18日,Vue.js发布3.0版本,代号:One Piece(海贼王)耗时2年多、2600次提交、30个RFC、600次PR、99位贡献者github上的tags地址:Release v3.0.0 One Piece vuejs/core Git…

什么是国密SSL证书,和其他SSL证书的区别?

我们要了解什么是SSL证书。SSL(Secure Sockets Layer,安全套接层)是一种安全协议,主要用于在互联网上对通信双方进行身份验证以及保障数据的安全传输。而SSL证书则是由权威的数字证书认证机构签发的,用于证明网站身份的…

【Linux】磁盘与文件系统管理

目录 一、 磁盘结构 1. 数据结构 2. 物理结构 3. 硬盘的接口类型 二、 如何使用Linux中的磁盘 三、 文件系统 四、 磁盘分区 1. MBR分区 2. 分区的优缺点 3. 磁盘及分区的管理工具 五、格式化与挂载 1. 格式化 2. 挂载 六、实例演示 1. 演示分区格式化挂载 2. …

C语言写流星雨代码

目录 需要包含的头文件 图片素材的路径 初始化背景图片 报错怎么解决? 初始化流星雨 放置流星雨图片 让流星雨动起来 总不能让流星砸到地面吧 是不是应该再来一点背景音乐? 所有代码 需要包含的头文件 IMAGE img;//创建流星雨的图片变量void…

HTML - 请你说一下如何阻止a标签跳转

难度级别:初级及以上 提问概率:55% a标签的默认语义化功能就是超链接,HTML给它的定位就是与外部页面进行交流,不过也可以通过锚点功能,定位到本页面的固定id区域去。但在开发场景中,又避免不了禁用a标签的需求,那么都有哪些方式可以禁用…

Jmeter针对多种响应断言的判断

有时候response返回的结果并非一种,有多种,需要对这几种进行判断的时候需要使用Bean Shell。 (1)首先获取响应数据 String response prev.getResponseDataAsString(); ResponseCode 响应状态码 responseHeaders 响应头信息 res…

DFS:深搜+回溯+剪枝解决排列、子集问题

创作不易&#xff0c;感谢三连支持&#xff01;&#xff01; 一、全排列I . - 力扣&#xff08;LeetCode&#xff09; class Solution { public://全局变量vector<vector<int>> ret;vector<int> path;bool check[6];vector<vector<int>> perm…

虚拟网络设备性能优化

在现代网络架构中&#xff0c;虚拟网络设备扮演着越来越重要的角色&#x1f310;&#xff0c;特别是在云计算☁️和容器化技术&#x1f4e6;广泛应用的背景下。虚拟网络设备如虚拟以太网设备&#xff08;veth&#xff09;、虚拟交换机&#xff08;vSwitch&#xff09;、和虚拟路…

YOLOv9综合指南

YOLOv9是YOLO系列中用于实时目标检测的最新进展&#xff0c;引入了可编程梯度信息&#xff08;PGI&#xff09;和通用高效层聚合网络&#xff08;GELAN&#xff09;等新技术来解决信息瓶颈并提高检测精度和效率。 在这篇文章中&#xff0c;我们研究了 YOLOv9 的一些关键优势。 …

Java并发编程: Java线程组(ThreadGroup)

文章目录 一、介绍二、线程组特性1、关联性&#xff08;1&#xff09;一级关联性&#xff08;2&#xff09;多级关联性 2、自动归属属性3、根线程组 三、线程组作用1、统一异常处理机制 一、介绍 Java线程组&#xff08;ThreadGroup&#xff09;是一种用于组织和管理线程的机制…

【计算机毕业设计】在线商品管理系统的设计与实现——后附源码

&#x1f389;**欢迎来到琛哥的技术世界&#xff01;**&#x1f389; &#x1f4d8; 博主小档案&#xff1a; 琛哥&#xff0c;一名来自世界500强的资深程序猿&#xff0c;毕业于国内知名985高校。 &#x1f527; 技术专长&#xff1a; 琛哥在深度学习任务中展现出卓越的能力&a…
最新文章