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

深度学习-11.用于自然语言处理的循环神经网络

Deep Learning - Lecture 11 Recurrent Networks for Natural Language Processing

  • 介绍
  • 文本表示
    • 用数字表示单词
    • 词嵌入(word embedding)
  • 机械翻译
    • 编码器 - 解码器循环模型(Encoder-decoder recurrent models)
    • 双向循环网络
  • 注意力机制(方法)
    • 编码器 - 解码器循环神经网络缺乏注意力机制
    • Bahdanau注意力机制
    • 点积注意力
    • 示例:谷歌机械翻译系统
  • 总结
  • 引用

本节目标:

  • 解释用于自然语言处理的方法,包括:
    • 文本表示和词嵌入;
    • 编码器-解码器架构;
    • 注意力模型。
  • 设计并实现用于自然语言处理的深度学习方法。

介绍

循环神经网络常常被应用于诸如机器翻译、语音识别和语音合成等序列问题中。

  • 循环网络的记忆存储于内部状态 x t x_t xt
  • 门控循环网络(GRU和LSTM)具备长期记忆能力,而简单RNN只有短期记忆。
  • 循环网络单元对比
    • 简单RNN(Simple RNN) x t = tanh ⁡ ( A x t − 1 + B u t ) x_t = \tanh(Ax_{t - 1} + Bu_t) xt=tanh(Axt1+But)用于更新内部状态,结合上一时刻状态 x t − 1 x_{t - 1} xt1和当前输入 u t u_t ut y ^ t = g ( C x t ) \hat{y}_t = g(Cx_t) y^t=g(Cxt)计算输出,将内部状态转换为模型预测值。
    • 门控循环单元网络(GRU RNN) x t = z t ⊙ x t − 1 + ( 1 − z t ) ⊙ tanh ⁡ ( A x ( r t ⊙ x t − 1 ) + B x u t ) x_t = z_t \odot x_{t - 1} + (1 - z_t) \odot \tanh(A_x(r_t \odot x_{t - 1}) + B_xu_t) xt=ztxt1+(1zt)tanh(Ax(rtxt1)+Bxut),利用更新门 z t z_t zt和重置门 r t r_t rt,灵活控制信息传递; y ^ t = g ( C x t ) \hat{y}_t = g(Cx_t) y^t=g(Cxt)用于输出计算。
    • 长短期记忆网络(LSTM RNN) s t = f t ⊙ s t − 1 + i t ⊙ tanh ⁡ ( A s x t − 1 + B s u t ) s_t = f_t \odot s_{t - 1} + i_t \odot \tanh(A_sx_{t - 1} + B_su_t) st=ftst1+ittanh(Asxt1+Bsut)更新记忆单元,由遗忘门 f t f_t ft 、输入门 i t i_t it等控制; x t = o t ⊙ tanh ⁡ ( s t ) x_t = o_t \odot \tanh(s_t) xt=ottanh(st)更新内部状态,通过输出门 o t o_t ot y ^ t = g ( C x t ) \hat{y}_t = g(Cx_t) y^t=g(Cxt)计算最终输出。

循环网络按照时间展开的示意图如下:
其中每个绿色方块都时循环网络中的一个单元,因此他们可以是上述的简单RNN或门控制循环单元或长短期记忆网络中的一种。
在这里插入图片描述

文本表示

用数字表示单词

深度学习系统需要将文本表示为数字,而这个问题包含多个方面。
在这里插入图片描述

  • 示例讲解:以句子“The cat sat on the mat.”为例。
    • 词元(Tokens)化:对原始输入文本去除标点和大写字母后,生成词元(Tokens),即“the”“cat”“sat”“on”“the”“mat”。
    • 整数表示:给每个不同的词元分配一个唯一的整数,如“the”为1、“cat”为2等,整句表示为“1 2 3 4 1 5”
    • 独热编码(One hot encoding):将每个整数表示转换为向量形式,向量中只有对应位置为1,其余为0,例如“the”对应的向量是[1, 0, 0, 0, 0, 0] 。
  • 存在问题:若词汇表中包含数千个不同的单词,使用独热编码会导致许多稀疏的输入向量,在计算上效率较低。

词嵌入(word embedding)

词嵌入在自然语言处理中很受欢迎,它能在低维空间中高效表示单词。

  • 原理阐述:词嵌入的思路是对原始词表示进行降维。公式为 z = W x z = Wx z=Wx
    其中, x ∈ R n x \in \mathbb{R}^n xRn是单词的独热编码表示; W ∈ R d × n W \in \mathbb{R}^{d \times n} WRd×n是权重矩阵,用于降维,且 d ≪ n d \ll n dn z ∈ R d z \in \mathbb{R}^d zRd是嵌入后的词表示。
  • 简单来说:权重矩阵的行数等于嵌入维度(左侧竖着的红线),列数等于不同单词的数量(上方横着的红线)。
    上方说了, d < < n d<<n d<<n,所以权重矩阵的行数远小于列数。(要不怎么降维)
    在这里插入图片描述

示例
以GloVe词嵌入(6B.300d)中与食物相关的区域为例,展示了将4000个单词嵌入到2维空间的情况。图中每个点代表一个单词,相近的点表示语义相近的单词 。
在这里插入图片描述

巧妙之处在于,这个权重矩阵可以作为深度网络中的一层,通过反向传播算法来进行学习。
如下展示了如何创建一个循环模型(门控循环单元,GRU),并将词嵌入层作为该模型中的一层。

Matlab示例代码

%% Define GRU Network with word embedding layer
% define network parameters
inputSize = 10; % input size
embeddingDimension = 100; % word embedding dimension
numWords = 20000; % number of unique words
numHiddenUnits = 128; % number of hidden units
numClasses = 5; % number of classes
% define network layers
layers = [sequenceInputLayer(inputSize)wordEmbeddingLayer(embeddingDimension,numWords)gruLayer(numHiddenUnits,'OutputMode','last')fullyConnectedLayer(numClasses)softmaxLayerclassificationLayer];

Python示例代码

# Define GRU network with word embedding layer 
# define network parameters
inputSize = 10 # input size
embeddingDimension=100 # embedding dimension
numWords = 20000 # Only consider the top 20k words
numHiddenUnits=128 # number of hidden units
numClasses = 5
# create a model using the sequential class
model = keras.Sequential()
model.add(layers.Embedding(input_dim=numWords,
output_dim=embeddingDimension,
input_length=inputSize))
model.add(layers.GRU(numHiddenUnits))
model.add(layers.Dense(numClasses, activation="softmax"))

机械翻译

编码器 - 解码器循环模型(Encoder-decoder recurrent models)

机器翻译系统通常采用编码器 - 解码器结构。
在这里插入图片描述

模型组件及原理

  • 编码器(Encoder):由Encoder RNN构成,公式为 x t = tanh ⁡ ( A x t − 1 + B u t ) x_t = \tanh(Ax_{t - 1} + Bu_t) xt=tanh(Axt1+But),其中 x t x_t xt是当前时刻的隐藏状态, x t − 1 x_{t - 1} xt1是上一时刻的隐藏状态, u t u_t ut是当前时刻的输入。编码器的作用是将输入(如“The past few days”)映射为一个上下文向量 c c c ,捕捉输入序列的整体信息。
  • 解码器(Decoder):由Decoder RNN构成,公式为 x t ′ = tanh ⁡ ( A x t − 1 ′ + B y ^ t − 1 ) x'_t = \tanh(Ax'_{t - 1} + B\hat{y}_{t - 1}) xt=tanh(Axt1+By^t1) y ^ t = g ( C x t ′ ) \hat{y}_t = g(Cx'_t) y^t=g(Cxt),其中 x t ′ x'_t xt是解码器当前时刻的隐藏状态, y ^ t − 1 \hat{y}_{t - 1} y^t1是上一时刻的预测输出。解码器利用编码器生成的上下文向量 c c c来解码出翻译结果(如“les derniers jours” )。
  • 分类器输出(Classifier output):最终输出是一个经过softmax函数处理的结果,表示词汇表中每个单词的“概率”,基于这些概率选择合适的单词组成翻译文本。

双向循环网络

双向循环网络在自然语言处理中很常用,其特点是能够对数据进行正向和反向处理。
![j(https://i-blog.csdnimg.cn/direct/82d45491d4a048a0a30955d998cd49a0.png)

工作原理

  • 正向状态处理:公式为 x ⃗ t = tanh ⁡ ( A ⃗ x ⃗ t − 1 + B ⃗ u t ) \vec{x}_t = \tanh(\vec{A}\vec{x}_{t - 1} + \vec{B}u_t) x t=tanh(A x t1+B ut) ,其中 x ⃗ t \vec{x}_t x t表示在时刻 t t t的正向隐藏状态, x ⃗ t − 1 \vec{x}_{t - 1} x t1是上一时刻的正向隐藏状态, u t u_t ut是时刻 t t t的输入, A ⃗ \vec{A} A B ⃗ \vec{B} B 是相应的权重矩阵。通过该公式,网络按时间顺序从前往后处理输入数据。
  • 反向状态处理:公式为 x ← t = tanh ⁡ ( A ← x ← t + 1 + B ← u t ) \overleftarrow{x}_t = \tanh(\overleftarrow{A}\overleftarrow{x}_{t + 1} + \overleftarrow{B}u_t) x t=tanh(A x t+1+B ut) ,这里 x ← t \overleftarrow{x}_t x t是时刻 t t t的反向隐藏状态, x ← t + 1 \overleftarrow{x}_{t + 1} x t+1是下一时刻的反向隐藏状态, A ← \overleftarrow{A} A B ← \overleftarrow{B} B 是对应的权重矩阵。该公式使网络能逆时间顺序处理数据。
  • 状态整合:最终的状态 x j x_j xj可以通过将正向和反向的状态相加组合得到,即 x j = [ x ⃗ j T + x ← j T ] x_j = [\vec{x}_j^T + \overleftarrow{x}_j^T] xj=[x jT+x jT] ,从而融合了数据前后的信息。

示例
如下是一个从英语到西班牙语的翻译示例,基于编码器 - 解码器结构。

在这里插入图片描述

模型结构

  • 编码器(Encoder):采用不带输出层的双向循环网络(Bidirectional Recurrent Network)。它接收英语单词(如“the”“past”“few”“days” )作为输入,通过正向处理公式 x ⃗ t = tanh ⁡ ( A ⃗ x ⃗ t − 1 + B ⃗ u t ) \vec{x}_t = \tanh(\vec{A}\vec{x}_{t - 1} + \vec{B}u_t) x t=tanh(A x t1+B ut)和反向处理公式 x ← t = tanh ⁡ ( A ← x ← t + 1 + B ← u t ) \overleftarrow{x}_t = \tanh(\overleftarrow{A}\overleftarrow{x}_{t + 1} + \overleftarrow{B}u_t) x t=tanh(A x t+1+B ut) ,将输入序列转换为一个最终状态,这个最终状态会成为上下文向量 c c c
  • 解码器(Decoder):是一个带有输出层的标准循环网络(Recurrent Network with output layer)。初始状态 x 0 ′ x'_0 x0由编码器的上下文向量 c c c初始化,后续状态通过公式 x t ′ = tanh ⁡ ( A x t − 1 ′ + B y ^ t − 1 ) x'_t = \tanh(Ax'_{t - 1} + B\hat{y}_{t - 1}) xt=tanh(Axt1+By^t1)更新,输出 y ^ t = g ( C x t ′ ) \hat{y}_t = g(Cx'_t) y^t=g(Cxt) ,生成对应的西班牙语单词(如“los”“últimos”“días” )。

关键细节

  • 上下文向量的作用:编码器的最终状态形成的上下文向量用于初始化解码器的状态,使解码器能够利用编码器提取的输入序列整体信息。
  • 输入更新机制:每个翻译出的单词会在接下来的时间步作为解码器的新输入,帮助生成后续单词。
  • 句子结束标识:解码器会预测一个特殊的“句子结束”字符“” ,用于指示翻译的句子已完成。

Pyhton代码示例

  • 编码器模型:下面构建编码器模型,这是一个基于门控循环单元(GRU)的双向循环网络。我们使用Keras来构建该模型,注意其中词嵌入层的使用 。
# import layers from keras
from keras import layers
# define model parameter constants
embed_dim = 256 # the word embedding dimension
latent_dim = 1024 # the state dimension
########### Encoder ##############
# source input (english text)
source = keras.Input(shape=(None,), dtype="int64", name="english")
# word embedding layer for the English words
x = layers.Embedding(vocab_size, embed_dim)(source)
# bidirectional GRU layer, which performs the encoding
encoded_state = layers.Bidirectional(layers.GRU(latent_dim), merge_mode="sum")(x)
  • 解码器模型:构建解码器模型,这是一个基于门控循环单元(GRU)的单向循环网络。(还是用Keras)请注意,在训练阶段会使用词掩码技术,以防止模型在预测阶段通过获取当前单词的译文来 “作弊” 。
########### Decoder ##############
# define the preceding Spanish word at time step t-1 as an input 
past_target = keras.Input(shape=(None,), dtype="int64", name="spanish")
# word embedding layer for the Spanish word input at time t-1
# note a mask flag is set to 'True' so that the input at the current time-step is not used 
# which would be cheating (i.e. if the model has access to the translated word, the model learns nothing)
x = layers.Embedding(vocab_size, embed_dim, mask_zero=True)(past_target)
# define a standard GRU layer for the decoder
decoded_state = layers.GRU(latent_dim, return_sequences=True)(x, initial_state=encoded_state)
  • 输出层:输出层包含一个softmax激活函数,用于对单词进行分类。
########### Output layers ##############
# dropout layer 
x = layers.Dropout(0.5)(decoded_state)
# dense layer with softmax activation at the output to classify the word
target_next_step = layers.Dense(vocab_size, activation="softmax")(x)
# define the encoder-decoder model
model = keras.Model([source, past_target], target_next_step)

训练和往常一样,使用自适应矩估计(ADAM)优化器以及(稀疏)分类交叉熵损失函数。

########### Training ##############
# compile the model
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
# train the model
model.fit(train_ds, epochs=1, validation_data=val_ds)

注意力机制(方法)

注意力机制很重要,因为它有助于解码语义。
在这里插入图片描述

  • 第一个句子:英文句子是“The animal didn’t cross the street because it was too tired.”,对应的法语翻译是“L’animal n’a pas traversé la rue parce que qu’il était trop fatigué.”。这里“it”指代“animal”(动物)。
  • 第二个句子:英文句子是“The animal didn’t cross the street because it was too wide.”,法语翻译是“L’animal n’a pas traversé la rue parce que qu’elle était trop large.”。此处“it”指代“street”(街道)。

在这里插入图片描述

  • 每个句子中的单词被竖向排列,并用浅蓝色块表示,重点单词“it”用深蓝色块突出。
  • 从“it”出发,有线条指向句子中与之相关的单词,如第一个句子中“it”与“animal”相连,第二个句子中“it”与“street”相连,以此展示注意力机制在确定指代关系和理解语义方面的作用,即通过聚焦到相关的单词,帮助准确理解句子含义,进而进行正确翻译。

编码器 - 解码器循环神经网络缺乏注意力机制

标准的编码器 - 解码器结构没有注意力机制,所有输入都通过最终状态来表示。

标准编码器将输入映射为一个上下文向量𝒄;解码器根据该上下文向量来解码出译文 。

存在的问题
这种结构将源句子的所有必要信息都压缩到一个固定长度的向量 c c c中,在处理长句子时会面临困难。因为长句子包含的信息量大,很难完整且有效地通过单一的固定长度向量来表示,可能导致信息丢失或难以准确提取关键信息,进而影响翻译的准确性和效果。

在这里插入图片描述

Bahdanau注意力机制

注意力机制被发现能有效提升机器翻译,通过让模型学习关注序列中的任意单词来实现。

Bahdanau注意力机制使用前馈神经网络,学习关注编码器中不同的状态。它本质上是一种加权求和的方式,帮助模型在翻译时聚焦到输入序列中相关的部分。
在这里插入图片描述

  • 上下文向量计算:上下文向量 c t = ∑ j = 1 N w t j x j c_t = \sum_{j = 1}^{N} w_{tj}x_j ct=j=1Nwtjxj 其中 w t j w_{tj} wtj是注意力权重。

    • 上下文向量(Context vector)
      公式 c t = ∑ j = 1 N w t j x j c_t = \sum_{j = 1}^{N} w_{tj}x_j ct=j=1Nwtjxj ,表示在时刻 t t t的上下文向量 c t c_t ct是通过对编码器不同状态 x j x_j xj j j j从1到 N N N )进行加权求和得到的,其中 w t j w_{tj} wtj是对应的注意力权重。这个上下文向量会用于解码器在相应时刻的计算,帮助解码器聚焦输入序列中的相关信息。

    • 注意力权重(Attention weight)
      公式 w t j = softmax ( w t j ′ ) w_{tj} = \text{softmax}(w'_{tj}) wtj=softmax(wtj) ,注意力权重 w t j w_{tj} wtj是对 w t j ′ w'_{tj} wtj使用Softmax函数进行归一化处理得到的。归一化后的权重取值在0到1之间,且所有权重之和为1,用来衡量编码器各个状态在生成当前上下文向量时的重要程度。

    • 对齐模型(Alignment model)
      对齐模型是一个前馈神经网络。公式 w t j ′ = a ( x t − 1 ′ , x j ) w'_{tj} = a(x'_{t - 1}, x_j) wtj=a(xt1,xj) 表示 w t j ′ w'_{tj} wtj是通过一个函数 a a a计算得出,该函数的输入是解码器上一时刻的状态 x t − 1 ′ x'_{t - 1} xt1和编码器在 j j j时刻的状态 x j x_j xj 。这个函数 a a a的参数是需要通过训练学习得到的,以使得模型能够根据不同输入自适应地调整注意力权重。

  • 编码器:采用双向循环神经网络(Bidirectional RNN Encoder),输入序列为 u 1 , u 2 , u 3 , … , u N u_1, u_2, u_3, \ldots, u_N u1,u2,u3,,uN(如“The past few days” ),输出不同时刻的状态 x j x_j xj ,且 x j = [ x ⃗ j T + x ← j T ] T x_j = [\vec{x}_j^T + \overleftarrow{x}_j^T]^T xj=[x jT+x jT]T ,即整合正向和反向的隐藏状态。

  • 解码器:由Decoder RNN构成,根据前一时刻的状态和上下文向量 c t c_t ct逐步生成翻译结果(如“les derniers jours” )。

点积注意力

注意力机制可以高效的“点积”形式实现,这种形式基于向量之间的相关性,且无需学习复杂的模型。

点积注意力模型介绍

  • 上下文向量:与Bahdanau注意力模型类似,点积注意力模型中时刻 t t t的上下文向量 c t = ∑ j = 1 N w t j x j c_t = \sum_{j = 1}^{N} w_{tj}x_j ct=j=1Nwtjxj ,通过对编码器状态 x j x_j xj加权求和得到。
  • 注意力权重:计算方式为 w t j = softmax ( w t j ′ ) w_{tj} = \text{softmax}(w'_{tj}) wtj=softmax(wtj) ,对 w t j ′ w'_{tj} wtj进行Softmax归一化处理。
  • 点积注意力计算:独特之处在于 w t j ′ = x t − 1 ′ T x j w'_{tj} = x'^{T}_{t - 1}x_j wtj=xt1Txj ,即通过解码器上一时刻的状态 x t − 1 ′ x'_{t - 1} xt1与编码器状态 x j x_j xj做点积来计算,点积值越大表明相关性越强,反之则越弱。

在这里插入图片描述
与Bahdanau注意力模型对比
右侧列出Bahdanau注意力模型的关键公式,与之相比,点积注意力无需像Bahdanau模型那样通过前馈神经网络(对齐模型)来学习 w t j ′ w'_{tj} wtj 。此外,点积注意力是Transformer架构的基础,其在现代自然语言处理模型中有着重要地位。

示例:谷歌机械翻译系统

在2016年,由于取得成功,谷歌翻译(GNMT)开始采用带有注意力机制的编码器 - 解码器循环神经网络
在这里插入图片描述

图表展示了不同翻译模型的翻译质量对比,纵轴为“Translation quality”(翻译质量),刻度从1到6,6代表“perfect translation”(完美翻译) 。横轴列出了不同的翻译方向及模型,包括“English > Spanish”(英语到西班牙语)、“English > French”(英语到法语)、“English > Chinese”(英语到中文)、“Spanish > English”(西班牙语到英语)、“French > English”(法语到英语)、“Chinese > English”(中文到英语) ,每种翻译方向下对比了三种模型:

  • human(人工翻译),用橙色表示。
  • neural (GNMT)(基于神经网络的谷歌翻译模型),用绿色表示。
  • phrase - based (PBMT)(基于短语的机器翻译模型),用蓝色表示。

从图中可以看出,在多数语言对的翻译中,GNMT模型的表现优于基于短语的机器翻译模型,且更接近人工翻译的质量。

总结

  • 可以使用独热编码(one-hot encoding)等方法对文本进行编码,以便在深度学习系统中处理,但这些方法得到的编码维度较高。
  • 词嵌入(Word embedding )方法可用于压缩独热编码后的单词。
  • 循环神经网络(RNN)的编码器 - 解码器模型适用于输入和输出数量不对应的机器翻译问题。
  • 与基本的编码器 - 解码器模型相比,注意力模型能够提升(翻译)效果 。

引用

  • (编码器 - 解码器循环模型)Sutskever, I., Vinyals, O., & Le, Q. V. (2014). Sequence to sequence learning with neural networks. Advances in Neural Information Processing Systems, 27.
  • (循环神经网络缺乏注意力机制)Cho, K., Gulcehre, B. V. M. C., Bahdanau, D., Schwenk, F. B. H., & Bengio, Y. Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation. Proceedings of the 2014 Conference on Empirical Methods in Natural Language Processing (EMNLP), pages 1724–1734
  • (Bahdanau注意力机制)Bahdanau, D., Cho, K., & Bengio, Y. (2014). Neural machine translation by
    jointly learning to align and translate. arXiv preprint arXiv:1409.0473.
  • (点积注意力)Luong, et al. (2015). Effective approaches to attention-based neural machine translation.
    In Proc 2015 Empirical Methods in Natural Language Processing, pages 1412–1421
  • (谷歌机械翻译系统)Wu, Y., Schuster, M., Chen, Z., Le, Q. V., Norouzi, M., Macherey, W., … & Dean, J. (2016). Google’s neural machine translation system: Bridging the gap between human and machine translation. arXivpreprint arXiv:1609.08144.

相关文章:

深度学习-11.用于自然语言处理的循环神经网络

Deep Learning - Lecture 11 Recurrent Networks for Natural Language Processing 介绍文本表示用数字表示单词词嵌入(word embedding) 机械翻译编码器 - 解码器循环模型&#xff08;Encoder-decoder recurrent models&#xff09;双向循环网络 注意力机制&#xff08;方法&am…...

2025年软考报名费用是多少?全国费用汇总!

软考报名时间终于确定了&#xff01;想要参加2025年软考的同学们注意啦&#xff01;特别是那些一年只有一次考试机会的科目&#xff0c;千万不要错过哦&#xff01;这里为大家整理了各地的报名时间、科目、费用等信息&#xff0c;快来看看吧&#xff01; 一、2025年软考时间安…...

el-input实现金额输入

需求&#xff1a;想要实现一个输入金额的el-input&#xff0c;限制只能输入数字和一个小数点。失焦数字转千分位&#xff0c;聚焦转为数字&#xff0c;超过最大值&#xff0c;红字提示 效果图 失焦 聚焦 报错效果 // 组件limitDialog <template><el-dialog:visible.s…...

C++11相较于C++98的新特性介绍:列表初始化,右值引用与移动语义

一&#xff0c;列表初始化 1.1C98中传统的{} C98中一般数组和结构体可以使用{}进行初始化&#xff1a; struct Date {int _year;int _month;int _day; };int main() {int a[] { 1,2,3,4,5 };Date _date { 2025,2,27 };return 0; } 1.2C11中的{} C11以后想统一初始化方式&…...

ISIS(中间系统到中间系统)——基础

ISIS是一项通用的动态路由协议&#xff0c;其隶属于链路状态路由协议&#xff0c;最初运行与OSI七层的网络层&#xff0c;采用组播地址224.0.0.14和224.0.0.15两个组波段&#xff0c;由于其较高的拓展性与高速收敛&#xff0c;被大多数运营商网络所使用 起源 ISIS最初是由国际…...

如何使用useContext进行全局状态管理?

在 React 中&#xff0c;使用 useContext 进行全局状态管理是一种有效的方法&#xff0c;尤其在需要在多个组件之间共享状态时。useContext 允许你在组件树中传递数据&#xff0c;而无需通过每个组件的 props 逐层传递。以下是关于如何使用 useContext 进行全局状态管理的详细指…...

docker容器网络配置及常用操作

Linux内核实现名称空间的创建 ip netns&#xff08;网络名称空间&#xff09;命令 可以借助ip netns命令来完成对 Network Namespace 的各种操作。ip netns命令来自于iproute安装包&#xff0c;一般系统会默认安装&#xff0c;如果没有的话&#xff0c;请自行安装。 注意&am…...

GMII(Gigabit Media Independent Interface)详解

一、GMII的定义与作用 GMII&#xff08;千兆介质无关接口&#xff09;是用于千兆以太网&#xff08;1Gbps&#xff09;的标准化接口&#xff0c;连接 MAC层&#xff08;数据链路层&#xff09;与 PHY芯片&#xff08;物理层&#xff09;。其核心目标是支持高速数据传输&#x…...

Wireshark Lua 插件教程

本⽂主要介绍 Lua 脚本在 Wireshark 中的应⽤, Lua 脚本可以在 Wireshark 中完成如下功能: 从⽹络包中提取数据, 或者统计⼀些数据包(Dumper) 需要解析⼀种 Wireshark 不提供原⽣⽀持的协议(Dissector) ⽰例 协议解析 VREP 协议是 NOGD 框架对于 TRIP 协议的⼀种延伸和扩展…...

【多模态大模型】GLM-4-Voice端到端语音交互机器人VoiceAI

写在前面&#xff1a;开源选手中最能打的 GLM-4-Voice&#xff0c;由智谱 AI 和清华大学共同研发&#xff0c;并发表论文 “GLM-4-Voice: Towards Intelligent and Human-Like End-to-End Spoken Chatbot”&#xff0c;旨在打造智能且类人化的端到端语音聊天机器人。GLM-4-Voi…...

Unity 列表滚动到指定位置

使用场景 策划提出需求&#xff1a;当玩家打开领奖界面时&#xff0c;奖励列表需要自动滑动到可以领奖的奖励栏处或者正在进行的任务栏处。 思路 1、将Content设置好对齐方式和锚点 子物体的预制体和Content&#xff1a;pivot轴心点设置为(0,1),并且设置为左上角对齐。 2、主…...

使用Crawlee可破题js渲染采集数据

使用 Crawlee 实现自动化爬虫流程 1. Crawlee 简介 Crawlee 是一个强大的爬虫框架&#xff0c;用于快速构建和维护可靠的爬虫。它支持多种爬虫类型&#xff0c;包括基于 Cheerio 和 Playwright 的爬虫&#xff0c;能够高效处理静态和动态网页。 2. 项目目标 通过自动化脚本实…...

小红的字母游戏(A组)

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 题目描述 小红有一个长度为 nnn 的字符串 sss&#xff0c;仅包含小写字母&#xff0c;小红可以选出 kkk 个字符&#xff0c;组成一个新的字符串 ttt&#xff0c;对于 ttt 的每一个字符 tit_it…...

MFC线程

创建线程 HANDLE m_hThread; m_hThread CreateThread(NULL, 0, save_snapshot, (LPVOID)this, 0, &iThreadId);开启线程循环等待 DWORD WINAPI save_snapshot(LPVOID pVoid) {while (true){//持续循环等待事件到达。接收到事件信号后才进入if。if (::WaitForSingleObjec…...

目标检测YOLO实战应用案例100讲-面向无人机图像的小目标检测

目录 知识储备 YOLO v8无人机拍摄视角小目标检测 数据集结构 环境部署说明 安装依赖 模型训练权重和指标可视化展示 训练 YOLOv8 PyQt5 GUI 开发 主窗口代码 main_window.py 使用说明 无人机目标跟踪 一、目标跟踪的基本原理 二、常用的目标跟踪算法 基于YOLOv…...

【Java分布式】Nacos注册中心

Nacos注册中心 SpringCloudAlibaba 也推出了一个名为 Nacos 的注册中心&#xff0c;相比 Eureka 功能更加丰富&#xff0c;在国内受欢迎程度较高。 官网&#xff1a;https://nacos.io/zh-cn/ 集群 Nacos就将同一机房内的实例划分为一个集群&#xff0c;一个服务可以包含多个集…...

VSCode轻松调试运行.Net 8.0 Web API项目

1.背景 我一直都是用VS来开发.NetCore项目的&#xff0c;用的比较顺手&#xff0c;也习惯了。看其他技术文章有介绍VS Code更轻量&#xff0c;更方便。所以我专门花时间来使用VS Code&#xff0c;看看它是如何调试代码、如何运行.Net 8.0 WebAPI项目。这篇文章是一个记录的过程…...

PageHelper新发现

PageHelper 背景解决reasonablepageSizeZero 背景 今天发现了一个很有趣的现象&#xff0c;接手一个很老的项目springmvc项目、使用PageHelper分页实现常见的后端接口分页功能。但是发现当页码参数大于实际的页码数时、正常不应该返回数据&#xff0c;但是目前确一直返回数据不…...

python编写liunx服务器登陆自动巡检脚本

前言&#xff1a; 用户需要一份用Python编写的Linux系统巡检脚本&#xff0c;检查内存、磁盘、CPU使用率&#xff0c;还有网络连通性。 首先&#xff0c;我得确定用户的使用场景。可能用户是系统管理员&#xff0c;需要定期监控服务器状态&#xff0c;确保系统正常运行。 或者…...

基于 Flink CDC YAML 的 MySQL 到 Kafka 流式数据集成

本教程的演示都将在 Flink CDC CLI 中进行&#xff0c;无需一行 Java/Scala 代码&#xff0c;也无需安装 IDE。 这篇教程将展示如何基于 Flink CDC YAML 快速构建 MySQL 到 Kafka 的 Streaming ELT 作业&#xff0c;包含整库同步、表结构变更同步演示和关键参数介绍。 准备阶段…...

数据结构——并查集

AcWing - 算法基础课 Acwing——合并集合 代码如下&#xff1a; #include <bits/stdc.h>using namespace std; #define fs first #define sc second #define endl \n #define all(x) x.begin(), x.end() typedef long long ll; typedef pair<int, int> PII;cons…...

详细解析d3dx9_27.dll丢失怎么办?如何快速修复d3dx9_27.dll

运行程序时提示“d3dx9_27.dll文件缺失”&#xff0c;通常由DirectX组件损坏或文件丢失引起。此问题可通过系统化修复方法解决&#xff0c;无需重装系统或软件。下文将详细说明具体步骤及注意事项。 一.d3dx9_27.dll缺失问题的本质解析 当系统提示“d3dx9_27.dll丢失”时&…...

【STL】4.<list>

list 前言list容器一.list初始化二.常用函数三.排序 总结 前言 stl系列主要讲述有关stl的文章&#xff0c;使用STL可以大大提高程序开发的效率和代码的可维护性&#xff0c;且在算法比赛中&#xff0c;STL可以帮助我们更方便地实现各种算法。提高我们的效率。 list容器 要使用…...

小程序中头像昵称填写

官方文档 参考小程序用户头像昵称获取规则调整公告 新的小程序版本不能通过wx.getUserProfile和wx.getUserInfo获取用户信息 <van-field label"{{Avatar}}" label-class"field-label" right-icon-class"field-right-icon-class"input-class&…...

vLLM服务设置开机自启动(Linux)

要在开机时进入指定的 conda 环境并启动此 vllm 服务&#xff0c;您可以通过以下步骤设置一个 systemd 服务来自动执行脚本。 一、第一步&#xff1a;创建一个启动脚本 1.打开终端并创建启动脚本&#xff0c;例如 /home/username/start_vllm.sh&#xff08;请替换 username 为…...

Cherno 游戏引擎笔记(91~111)

好久不见&#xff01; 个人库的地址&#xff1a;&#xff08;GitHub - JJJJJJJustin/Nut: The game_engine which learned from Cherno&#xff09;&#xff0c;可以看到我及时更新的结果。 -------------------------------Saving & Loading scene-----------------------…...

面试八股文--数据库基础知识总结(1)

1、数据库的定义 数据库&#xff08;DataBase&#xff0c;DB&#xff09;简单来说就是数据的集合数据库管理系统&#xff08;Database Management System&#xff0c;DBMS&#xff09;是一种操纵和管理数据库的大型软件&#xff0c;通常用于建立、使用和维护数据库。数据库系统…...

算法系列之动态规划

动态规划&#xff08;Dynamic Programming&#xff0c;简称DP&#xff09;是一种用于解决复杂问题的算法设计技术。它通过将问题分解为更小的子问题&#xff0c;并存储这些子问题的解来避免重复计算&#xff0c;从而提高算法的效率。本文将介绍动态规划的基本概念、适用场景、复…...

网站漏洞安全测试 具体渗透思路分析

渗透测试这些是经常谈到的问题了&#xff0c;我觉得当有了渗透接口测试之后你就会发现渗透测试这一方面也就是&#xff1a;1.基本漏洞测试&#xff1b;2.携带"低调"构思的心血来潮&#xff1b;3.锲而不舍的信念。我们在对网站&#xff0c;APP进行渗透测试的过程中会发…...

Spring Boot(七):Swagger 接口文档

1. Swagger 简介 1.1 Swagger 是什么&#xff1f; Swagger 是一款 RESTful 风格的接口文档在线自动生成 功能测试功能软件。Swagger 是一个规范和完整的框架&#xff0c;用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。目标是使客户端和文件系统作为服务器以同样的…...

【Mac电脑本地部署Deepseek-r1:详细教程与Openwebui配置指南】

文章目录 前言电脑配置&#xff1a;安装的Deepseek版本&#xff1a;使用的UI框架&#xff1a;体验效果展示&#xff1a;本地部署体验总结 部署过程Ollama部署拉取模型运行模型Openwebui部署运行Ollama服务在Openwebui中配置ollama的服务 后话 前言 deepseek最近火的一塌糊涂&a…...

测试的BUG分析

在了解BUG之前,我们要先了解软件测试的生命周期,因为大多数BUG都是在软件测试的过程中被发现的 软件测试的生命周期 在了解 软件测试的生命周期 之前,我们要先了解 软件的生命周期 ,虽然他们之间只差了两个字,但是差距还是很大的 首先是 软件生命周期 ,这个是站在 软件 的角…...

linux里面的过滤符号 | 是如何实现的

ls -l | grep ".txt" 的实现过程涉及无名管道的创建、进程的创建&#xff08;fork()&#xff09;以及输入输出的重定向&#xff08;dup2()&#xff09;。以下是详细的实现步骤和代码示例&#xff1a; 实现步骤 创建无名管道&#xff1a; 使用pipe()系统调用创建一个无…...

结构型模式--组合模式

概念 组合人模式是结构型设计模式的一种&#xff0c;主要是用于解决代码中出现类像树一样进行组合而出现的组合结构的相关操作问题。使其树中的任意一个节点&#xff08;无论是子节点还是父节点&#xff09;都可以使用同一套接口进行操作。 使用场景 1、如果希望我们对象组合…...

drupal可以自动将测试环境的网页部署到生产环境吗

在 Drupal 中&#xff0c;自动将测试环境的网页部署到生产环境通常是通过设置合适的开发和部署流程来实现的。这种自动化部署过程通常涉及以下几个步骤&#xff1a; 1. 版本控制&#xff08;Git&#xff09; 为了保证测试环境和生产环境的一致性&#xff0c;首先需要使用 Git…...

Android应用app实现AI电话机器人接打电话

Android应用app实现AI电话机器人接打电话 --安卓AI电话机器人 一、前言 【Dialer3.0智能拨号器】Android版手机app&#xff0c;由于采用蓝牙电话的方式来调用手机SIM卡发起呼叫、接听来电&#xff0c;并接收和处理通话的声音&#xff0c;通常我们以“蓝牙电话方案”来称呼它。 …...

【面试宝典】Java中创建线程池的几种方式以及区别

强烈推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站:人工智能 创建线程池有多种方式&#xff0c;主要通过 Java 的 java.util.concurrent 包提供的 Executors 工具类来实现。以下是几…...

【数据结构】哈希表

目录 哈希表 基本思想 基本原理 哈希表工作机制简化描述 关于查找、插入和删除 HashMap 主要成员变量 主要方法 内部实现细节 注意事项 哈希表 哈希表是一种基于哈希函数的数据结构&#xff0c;它通过键值对的形式存储数据&#xff0c;并允许通过键快速查找对应的值…...

MySQL 使用 `WHERE` 子句时 `COUNT(*)`、`COUNT(1)` 和 `COUNT(column)` 的区别解析

文章目录 1. COUNT() 函数的基本作用2. COUNT(*)、COUNT(1) 和 COUNT(column) 的详细对比2.1 COUNT(*) —— 统计所有符合条件的行2.2 COUNT(1) —— 统计所有符合条件的行2.3 COUNT(column) —— 统计某一列非 NULL 的记录数 3. 性能对比3.1 EXPLAIN 分析 4. 哪种方式更好&…...

RabbitMQ系列(一)架构解析

RabbitMQ 架构解析 RabbitMQ 是一个基于 AMQP 协议的开源消息中间件&#xff0c;其核心架构通过多组件协作实现高效、可靠的消息传递。以下是其核心组件与协作流程的详细说明&#xff1a; 一、核心组件与功能 Broker&#xff08;消息代理服务器&#xff09; RabbitMQ 服务端核…...

如何让传统制造企业从0到1实现数字化突破?

随着全球制造业不断向智能化、数字化转型&#xff0c;传统制造企业面临着前所未有的机遇与挑战。数字化转型不仅是技术的革新&#xff0c;更是管理、文化、业务流程等全方位的变革。从零开始&#xff0c;如何带领一家传统制造企业走向数字化突破&#xff0c;是许多企业领导者面…...

基于Spring Boot的二手物品交易平台设计与实现(LW+源码)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

释放 Cursor 的全部潜能:快速生成智能 Cursor Rules

释放 Cursor 的全部潜能&#xff1a;使用 PromptCoder 从 package.json 快速生成智能 Cursor Rules 我们将深入探讨如何利用您项目中的 package.json 文件&#xff0c;轻松生成 Cursor Rules&#xff0c;并通过 PromptCoder 这个强大的工具&#xff0c;快速创建高质量的 curso…...

C#高级:结合Linq的SelectMany方法实现笛卡尔积效果

一、笛卡尔积定义 又称直积&#xff0c;表示为X Y&#xff0c;第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员 二、基础示例 class Program {static void Main(string[] args){try{List<List<string>> input new List<List<string&g…...

【洛谷入门赛】B4018 游戏与共同语言

题意 这里有两个队伍分别叫 A 和 B。 分别给定这两个队伍的胜利数、净胜局、平局数量。 求哪个队更厉害&#xff0c;就输出哪个。 具体比较规则如下&#xff1a; 两队中胜利数高的队伍更厉害。 若胜利数相同&#xff0c;净胜数高的队伍更厉害。 若净胜数仍然相同&#x…...

Python学习总结

客户端与服务端聊天窗口 服务端 导入 wxPython 用于创建图形界面。 socket 用于网络通信&#xff0c;AF_INET 是 IPv4 地址族&#xff0c;SOCK_STREAM 表示流式套接字&#xff08;TCP&#xff09;。 利用wxPython 创建图形界面&#xff0c;并通过 socket 与服务器通信。 主要…...

android系统_模拟ZygoteServer写一个socket通信

目录 一,模拟ZygoteServer 二,Client 代表app 三,输出结果 四,结束语 一,模拟ZygoteServer ZygoteServer&#xff0c;不断的监听来自客户端的请求 package org.study.tiger;import java.io.*; import java.net.*; import java.util.concurrent.*;import java.io.*; impor…...

LangChain教程 - RAG - PDF问答

系列文章索引 LangChain教程 - 系列文章 在现代自然语言处理&#xff08;NLP&#xff09;中&#xff0c;基于文档内容的问答系统变得愈发重要&#xff0c;尤其是当我们需要从大量文档中提取信息时。通过结合文档检索和生成模型&#xff08;如RAG&#xff0c;Retrieval-Augment…...

李代数(Lie Algebras)与Attention:深度学习中的数学之美

李代数与Attention&#xff1a;深度学习中的数学之美 引言 作为一名深度学习研究者&#xff0c;您一定对Transformer模型和其中的注意力机制&#xff08;Attention&#xff09;不陌生。Attention通过查询&#xff08;Query&#xff09;、键&#xff08;Key&#xff09;和值&a…...

docker本地镜像源搭建

最近Deepseek大火后&#xff0c;接到任务就是帮客户装Dify&#xff0c;每次都头大&#xff0c;因为docker源不能用&#xff0c;实在没办法&#xff0c;只好自己搭要给本地源。话不多说具体如下&#xff1a; 1、更改docker的配置文件&#xff0c;添加自己的私库地址&#xff0c…...