Keras深度学习框架第二十五讲:使用KerasNLP预训练Transformer模型

1、KerasNPL预训练Transformer模型概念

使用KerasNLP来预训练一个Transformer模型涉及多个步骤。由于Keras本身并不直接提供NLP的预训练模型或工具集,我们通常需要结合像TensorFlow Hub、Hugging Face的Transformers库或自定义的Keras层来实现。

以下是一个简化的步骤概述,用于说明如何使用Keras和相关的NLP工具来预训练一个Transformer模型:

  • 环境准备

      - 安装TensorFlow和Keras。- 安装任何你需要的NLP相关库,如Hugging Face的Transformers。
    
  • 数据准备
    - 收集一个大型的无标签文本数据集,用于预训练。
    - 对文本进行预处理,包括分词、填充/截断、创建词汇表等。

  • 定义模型
    - 使用Keras的Sequential API或函数式API定义Transformer模型的架构。
    - 通常,你会需要实现Transformer的编码器层(包括自注意力机制和前馈神经网络)。
    - 你也可以考虑使用现有的Transformer实现作为起点,如Hugging Face的Transformers库中的BERT或GPT模型。

  • 编译和配置模型
    - 编译模型,设置损失函数(对于预训练,可能是掩码语言建模的损失或句子级别的损失)和优化器。
    - 配置模型训练的超参数,如学习率、批大小、训练轮数等。

  • 训练模型
    - 使用准备好的数据集训练模型。这可能需要很长时间,特别是当数据集很大时。
    - 监控训练过程中的损失和任何其他的评估指标。

  • 保存模型
    - 在训练完成后,保存模型的权重和架构。

  • (可选)微调
    - 如果你打算将预训练的Transformer模型用于特定的NLP任务,你可能需要在有标签的数据集上进行微调。

需要注意的是,预训练一个Transformer模型是一个复杂且资源密集的任务,通常需要大量的计算资源(如GPU或TPU)和时间。此外,由于Keras本身并不直接提供NLP的预训练功能,你可能需要深入了解Transformer架构和相关的NLP技术来实现这一目标。

如果你希望快速开始并使用预训练的Transformer模型,考虑使用Hugging Face的Transformers库,它提供了大量预训练的模型和方便的API来加载和使用这些模型。

KerasNLP旨在简化构建最先进的文本处理模型的过程。在本文中,我们将展示如何使用该库的组件来简化从头开始预训练和微调Transformer模型的流程。

  • 设置、任务定义和建立基线。
  • 预训练一个Transformer模型。
  • 在分类任务上微调Transformer模型。

2、KerasNLP预训练Transformer模型的步骤

2.1 设置

安装及导入

!pip install -q --upgrade keras-nlp
!pip install -q --upgrade keras  # Upgrade to Keras 3.
import osos.environ["KERAS_BACKEND"] = "jax"  # or "tensorflow" or "torch"import keras_nlp
import tensorflow as tf
import keras

下载数据集
接下来,我们可以下载两个数据集。

SST-2 是一个文本分类数据集,也是我们的“最终目标”。这个数据集经常被用来作为语言模型的基准测试。
WikiText-103:一个中等规模的英文维基百科精选文章集合,我们将用于预训练。
最后,我们将下载一个WordPiece词汇表,以便在后面的文章中进行子词分词。

# Download pretraining data.
keras.utils.get_file(origin="https://s3.amazonaws.com/research.metamind.io/wikitext/wikitext-103-raw-v1.zip",extract=True,
)
wiki_dir = os.path.expanduser("~/.keras/datasets/wikitext-103-raw/")# Download finetuning data.
keras.utils.get_file(origin="https://dl.fbaipublicfiles.com/glue/data/SST-2.zip",extract=True,
)
sst_dir = os.path.expanduser("~/.keras/datasets/SST-2/")# Download vocabulary data.
vocab_file = keras.utils.get_file(origin="https://storage.googleapis.com/tensorflow/keras-nlp/examples/bert/bert_vocab_uncased.txt",
)

定义参数
接下来,定义一些在训练过程中将使用的超参数。

# Preprocessing params.
PRETRAINING_BATCH_SIZE = 128
FINETUNING_BATCH_SIZE = 32
SEQ_LENGTH = 128
MASK_RATE = 0.25
PREDICTIONS_PER_SEQ = 32# Model params.
NUM_LAYERS = 3
MODEL_DIM = 256
INTERMEDIATE_DIM = 512
NUM_HEADS = 4
DROPOUT = 0.1
NORM_EPSILON = 1e-5# Training params.
PRETRAINING_LEARNING_RATE = 5e-4
PRETRAINING_EPOCHS = 8
FINETUNING_LEARNING_RATE = 5e-5
FINETUNING_EPOCHS = 3

2.2 加载数据

使用tf.data来加载我们的数据,这将允许我们定义用于分词和文本预处理的输入管道。

# Load SST-2.
sst_train_ds = tf.data.experimental.CsvDataset(sst_dir + "train.tsv", [tf.string, tf.int32], header=True, field_delim="\t"
).batch(FINETUNING_BATCH_SIZE)
sst_val_ds = tf.data.experimental.CsvDataset(sst_dir + "dev.tsv", [tf.string, tf.int32], header=True, field_delim="\t"
).batch(FINETUNING_BATCH_SIZE)# Load wikitext-103 and filter out short lines.
wiki_train_ds = (tf.data.TextLineDataset(wiki_dir + "wiki.train.raw").filter(lambda x: tf.strings.length(x) > 100).batch(PRETRAINING_BATCH_SIZE)
)
wiki_val_ds = (tf.data.TextLineDataset(wiki_dir + "wiki.valid.raw").filter(lambda x: tf.strings.length(x) > 100).batch(PRETRAINING_BATCH_SIZE)
)# Take a peak at the sst-2 dataset.
print(sst_train_ds.unbatch().batch(4).take(1).get_single_element())
(<tf.Tensor: shape=(4,), dtype=string, numpy=
array([b'hide new secretions from the parental units ',b'contains no wit , only labored gags ',b'that loves its characters and communicates something rather beautiful about human nature ',b'remains utterly satisfied to remain the same throughout '],dtype=object)>, <tf.Tensor: shape=(4,), dtype=int32, numpy=array([0, 0, 1, 0], dtype=int32)>)

程序员可以看到,我们的SST-2数据集包含相对较短的电影评论文本片段。我们的目标是预测这些片段的情感倾向。标签为1表示正面情感,标签为0表示负面情感。

2.3建立基线

作为第一步,我们将建立一个性能良好的基线。其实这一步并不需要KerasNLP,我们只需要使用Keras的核心层就可以了。

我们将训练一个简单的词袋模型,其中我们为每个词汇表中的单词学习一个正面或负面的权重。一个样本的分数仅仅是样本中所有单词的权重之和。

# This layer will turn our input sentence into a list of 1s and 0s the same size
# our vocabulary, indicating whether a word is present in absent.
multi_hot_layer = keras.layers.TextVectorization(max_tokens=4000, output_mode="multi_hot"
)
multi_hot_layer.adapt(sst_train_ds.map(lambda x, y: x))
multi_hot_ds = sst_train_ds.map(lambda x, y: (multi_hot_layer(x), y))
multi_hot_val_ds = sst_val_ds.map(lambda x, y: (multi_hot_layer(x), y))# We then learn a linear regression over that layer, and that's our entire
# baseline model!inputs = keras.Input(shape=(4000,), dtype="int32")
outputs = keras.layers.Dense(1, activation="sigmoid")(inputs)
baseline_model = keras.Model(inputs, outputs)
baseline_model.compile(loss="binary_crossentropy", metrics=["accuracy"])
baseline_model.fit(multi_hot_ds, validation_data=multi_hot_val_ds, epochs=5)

词袋方法可能既快速又出乎意料地强大,尤其是在输入示例包含大量单词时。但对于较短的序列,它可能会达到性能上限。

为了做得更好,我们希望构建一个能够评估上下文中的单词的模型。我们不能再将每个单词视为孤立的存在,而是需要利用输入中整个有序序列所包含的信息。

这就引出了一个问题。SST-2是一个非常小的数据集,没有足够的示例文本来尝试构建一个更大、参数更多的模型来学习序列。我们很快就会开始过拟合并记住训练集,而没有任何提高我们对未见示例的泛化能力。

这时,预训练就派上了用场,它允许我们在一个更大的语料库上进行学习,并将我们的知识转移到SST-2任务上。同时,KerasNLP的引入使我们能够轻松地预训练一个特别强大的模型——Transformer。

2.4预训练

为了超越我们的基线模型,我们将利用WikiText103数据集,这是一个比SST-2大得多的无标签维基百科文章集合。

我们将训练一个Transformer模型,这是一个高度表达性的模型,它将学习将输入中的每个单词嵌入为低维向量。由于我们的维基百科数据集没有标签,因此我们将使用一个无监督的训练目标,称为掩码语言建模(Masked Language Modeling,MaskedLM)。

基本上,我们将玩一个大型的“猜缺失单词”游戏。对于每个输入样本,我们将遮盖25%的输入数据,并训练我们的模型来预测我们遮盖的部分。

2.4.1为MaskedLM任务预处理数据

我们为MaskedLM任务进行的文本预处理将分为两个阶段。

  • 将输入文本分词为token id的整数序列。
  • 遮盖输入中的某些位置以进行预测。

为了进行分词,我们可以使用keras_nlp.tokenizers.Tokenizer——KerasNLP中将文本转换为整数token id序列的构建块。

特别是,我们将使用keras_nlp.tokenizers.WordPieceTokenizer进行子词分词。在大文本语料库上训练模型时,子词分词非常流行。基本上,它允许我们的模型从不常见的单词中学习,而不需要包含训练集中每个单词的庞大词汇表。

我们需要做的第二件事是为MaskedLM任务遮盖输入。为此,我们可以使用keras_nlp.layers.MaskedLMMaskGenerator,它将在每个输入中随机选择一组token并遮盖它们。

分词器和遮盖层都可以在tf.data.Dataset.map的调用中使用。我们可以使用tf.data在CPU上高效地预计算每个批次,而我们的GPU或TPU则处理前一个批次的训练。由于我们的遮盖层每次都会选择新的单词进行遮盖,因此每次遍历数据集时,我们都会获得一组全新的标签进行训练。

# Setting sequence_length will trim or pad the token outputs to shape
# (batch_size, SEQ_LENGTH).
tokenizer = keras_nlp.tokenizers.WordPieceTokenizer(vocabulary=vocab_file,sequence_length=SEQ_LENGTH,lowercase=True,strip_accents=True,
)
# Setting mask_selection_length will trim or pad the mask outputs to shape
# (batch_size, PREDICTIONS_PER_SEQ).
masker = keras_nlp.layers.MaskedLMMaskGenerator(vocabulary_size=tokenizer.vocabulary_size(),mask_selection_rate=MASK_RATE,mask_selection_length=PREDICTIONS_PER_SEQ,mask_token_id=tokenizer.token_to_id("[MASK]"),
)def preprocess(inputs):inputs = tokenizer(inputs)outputs = masker(inputs)# Split the masking layer outputs into a (features, labels, and weights)# tuple that we can use with keras.Model.fit().features = {"token_ids": outputs["token_ids"],"mask_positions": outputs["mask_positions"],}labels = outputs["mask_ids"]weights = outputs["mask_weights"]return features, labels, weights# We use prefetch() to pre-compute preprocessed batches on the fly on the CPU.
pretrain_ds = wiki_train_ds.map(preprocess, num_parallel_calls=tf.data.AUTOTUNE
).prefetch(tf.data.AUTOTUNE)
pretrain_val_ds = wiki_val_ds.map(preprocess, num_parallel_calls=tf.data.AUTOTUNE
).prefetch(tf.data.AUTOTUNE)# Preview a single input example.
# The masks will change each time you run the cell.
print(pretrain_val_ds.take(1).get_single_element())

上述部分将我们的数据集整理为一个(features, labels, weights)的元组,可以直接传递给keras.Model.fit()函数进行训练。

我们有两个特征:

  • “token_ids”,其中一些token已经被替换为我们的掩码token id。
  • “mask_positions”,跟踪我们遮盖了哪些token。

我们的标签就是我们遮盖掉的那些token的id。

由于不是所有序列的掩码数量都相同,我们还保留了一个sample_weight张量,通过给填充的标签零权重,来从我们的损失函数中移除它们。

2.4.2创建Transformer编码器

KerasNLP提供了所有构建块,可以快速构建一个Transformer编码器。

我们使用keras_nlp.layers.TokenAndPositionEmbedding首先将输入token id进行嵌入。这个层同时学习两种嵌入——一种是句子中单词的嵌入,另一种是句子中整数位置的嵌入。输出嵌入就是两者的和。

然后我们可以添加一系列的keras_nlp.layers.TransformerEncoder层。这些层是Transformer模型的核心,使用注意力机制来关注输入句子的不同部分,接着是一个多层感知机块。

这个模型的输出是每个输入token id的编码向量。与我们用作基线的词袋模型不同,这个模型在嵌入每个token时会考虑到它出现的上下文。

inputs = keras.Input(shape=(SEQ_LENGTH,), dtype="int32")# Embed our tokens with a positional embedding.
embedding_layer = keras_nlp.layers.TokenAndPositionEmbedding(vocabulary_size=tokenizer.vocabulary_size(),sequence_length=SEQ_LENGTH,embedding_dim=MODEL_DIM,
)
outputs = embedding_layer(inputs)# Apply layer normalization and dropout to the embedding.
outputs = keras.layers.LayerNormalization(epsilon=NORM_EPSILON)(outputs)
outputs = keras.layers.Dropout(rate=DROPOUT)(outputs)# Add a number of encoder blocks
for i in range(NUM_LAYERS):outputs = keras_nlp.layers.TransformerEncoder(intermediate_dim=INTERMEDIATE_DIM,num_heads=NUM_HEADS,dropout=DROPOUT,layer_norm_epsilon=NORM_EPSILON,)(outputs)encoder_model = keras.Model(inputs, outputs)
encoder_model.summary()
2.4.3预训练Transformer

你可以把encoder_model看作是一个模块化的单元,这是我们对下游任务真正感兴趣的部分。然而,我们仍然需要设置编码器以在MaskedLM任务上进行训练;为此,我们将添加一个keras_nlp.layers.MaskedLMHead层。

这个层将接收两个输入:一个是token的编码,另一个是我们在原始输入中遮盖的位置。它将收集我们遮盖的token编码,并将它们转换回对整个词汇表的预测。

有了这些,我们就可以编译并开始预训练了。如果你在一个Colab环境中运行这个,请注意这可能需要大约一个小时。训练Transformer是出了名的计算密集型,所以即使是这个相对较小的Transformer也需要一些时间。

# Create the pretraining model by attaching a masked language model head.
inputs = {"token_ids": keras.Input(shape=(SEQ_LENGTH,), dtype="int32", name="token_ids"),"mask_positions": keras.Input(shape=(PREDICTIONS_PER_SEQ,), dtype="int32", name="mask_positions"),
}# Encode the tokens.
encoded_tokens = encoder_model(inputs["token_ids"])# Predict an output word for each masked input token.
# We use the input token embedding to project from our encoded vectors to
# vocabulary logits, which has been shown to improve training efficiency.
outputs = keras_nlp.layers.MaskedLMHead(token_embedding=embedding_layer.token_embedding,activation="softmax",
)(encoded_tokens, mask_positions=inputs["mask_positions"])# Define and compile our pretraining model.
pretraining_model = keras.Model(inputs, outputs)
pretraining_model.compile(loss="sparse_categorical_crossentropy",optimizer=keras.optimizers.AdamW(PRETRAINING_LEARNING_RATE),weighted_metrics=["sparse_categorical_accuracy"],jit_compile=True,
)# Pretrain the model on our wiki text dataset.
pretraining_model.fit(pretrain_ds,validation_data=pretrain_val_ds,epochs=PRETRAINING_EPOCHS,
)# Save this base model for further finetuning.
encoder_model.save("encoder_model.keras")

2.5微调

预训练之后,我们现在可以在SST-2数据集上微调我们的模型。我们可以利用我们构建的编码器在上下文中预测单词的能力,以提高我们在下游任务上的性能。

2.5.1分类任务的数据预处理

对于微调任务的数据预处理比预训练的MaskedLM任务简单得多。我们只需要对输入句子进行分词,就可以开始训练了!

具体来说,对于SST-2这样的情感分类任务,我们可能需要执行以下步骤来准备数据:

  • 分词:使用与预训练时相同的分词器对文本进行分词,并转换为token IDs。

  • 填充和截断:由于模型期望接收固定长度的输入,我们需要将文本填充或截断到模型接受的长度。

  • 标签编码:将情感标签转换为数字形式,以便模型可以处理它们作为目标变量。

  • 划分数据集:将数据集划分为训练集、验证集(可选)和测试集。

  • 构建输入:将分词后的文本(token IDs)和对应的标签组合成训练所需的格式(例如,使用tf.data API构建输入管道)。

  • (可选)添加样本权重:如果数据集不平衡,我们可以考虑使用样本权重来平衡不同类别的贡献。

完成这些步骤后,我们就可以将预处理后的数据输入到预训练好的Transformer编码器中进行微调了。微调过程将调整模型的所有权重(或其中的一部分,如只调整顶部几层),以优化在SST-2数据集上的性能。

def preprocess(sentences, labels):return tokenizer(sentences), labels# We use prefetch() to pre-compute preprocessed batches on the fly on our CPU.
finetune_ds = sst_train_ds.map(preprocess, num_parallel_calls=tf.data.AUTOTUNE
).prefetch(tf.data.AUTOTUNE)
finetune_val_ds = sst_val_ds.map(preprocess, num_parallel_calls=tf.data.AUTOTUNE
).prefetch(tf.data.AUTOTUNE)# Preview a single input example.
print(finetune_val_ds.take(1).get_single_element())
2.5.2微调Transformer

要从编码后的token输出转换为分类预测,我们需要给我们的Transformer模型再添加一个“头”。在这里,我们可以简单地实现它。我们将编码后的token合并在一起(池化),并使用一个单独的密集层(全连接层)进行预测。

# Reload the encoder model from disk so we can restart fine-tuning from scratch.
encoder_model = keras.models.load_model("encoder_model.keras", compile=False)# Take as input the tokenized input.
inputs = keras.Input(shape=(SEQ_LENGTH,), dtype="int32")# Encode and pool the tokens.
encoded_tokens = encoder_model(inputs)
pooled_tokens = keras.layers.GlobalAveragePooling1D()(encoded_tokens[0])# Predict an output label.
outputs = keras.layers.Dense(1, activation="sigmoid")(pooled_tokens)# Define and compile our fine-tuning model.
finetuning_model = keras.Model(inputs, outputs)
finetuning_model.compile(loss="binary_crossentropy",optimizer=keras.optimizers.AdamW(FINETUNING_LEARNING_RATE),metrics=["accuracy"],
)# Finetune the model for the SST-2 task.
finetuning_model.fit(finetune_ds,validation_data=finetune_val_ds,epochs=FINETUNING_EPOCHS,
)

预训练已经将我们的性能提升到了84%,但这对于Transformer模型来说还远未达到上限。在预训练过程中,你可能已经注意到验证性能仍在稳步提高。我们的模型仍然远远没有训练充分。通过增加训练轮次、训练一个更大的Transformer模型,以及在更多的未标记文本上进行训练,都可以继续显著提高性能。

KerasNLP的关键目标之一是提供NLP模型构建的模块化方法。在这里,我们展示了构建Transformer模型的一种方法,但KerasNLP支持越来越多用于文本预处理和模型构建的组件。我们希望它能让您更容易地针对自然语言问题尝试不同的解决方案。

3、总结

本文的讨论主要涉及了Transformer模型的预训练和微调过程,以及如何使用KerasNLP库来构建和实验NLP模型。首先,提到了预训练Transformer模型对于提高下游任务性能的重要性,包括通过MaskedLM任务进行预训练。随后,介绍了在预训练之后,如何对Transformer模型进行微调以适应特定的分类任务(如SST-2情感分类),并强调了数据预处理的重要性。此外,还提到了预训练模型的性能可能远未达到上限,可以通过增加训练轮次、扩大模型规模以及在更多未标记文本上进行训练来进一步提高性能。最后,强调了KerasNLP库在NLP模型构建中的模块化方法,它支持各种用于文本预处理和模型构建的组件,使得实验和尝试不同的解决方案变得更加容易。整个讨论展示了Transformer模型在NLP任务中的强大潜力和灵活性,以及使用KerasNLP库进行NLP模型开发的优势。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Thingsboard规则链:Message Type Filter节点详解

一、Message Type Filter节点概述 二、具体作用 三、使用教程 四、源码浅析 五、应用场景与案例 智能家居自动化 工业设备监控 智慧城市基础设施管理 六、结语 在物联网&#xff08;IoT&#xff09;领域&#xff0c;数据处理与自动化流程的实现是构建智能系统的关键。作…

创新实训2024.05.28日志:记忆化机制、基于MTPE与CoT技术的混合LLM对话机制

1. 带有记忆的会话 1.1. 查询会话历史记录 在利用大模型自身能力进行对话与解答时&#xff0c;最好对用户当前会话的历史记录进行还原&#xff0c;大模型能够更好地联系上下文进行解答。 在langchain chat chat的chat函数中&#xff0c;通过实现langchain框架提供的ChatMemo…

【设计模式】创建型-工厂方法模式

前言 工厂方法模式是一种经典的创建型设计模式&#xff0c;它提供了一种灵活的方式来创建对象实例。通过本文&#xff0c;我们将深入探讨工厂方法模式的概念、结构和应用。 一、什么是工厂方法模式 工厂方法模式是一种创建型设计模式&#xff0c;旨在解决对象的创建过程和客…

Spring MVC的请求流程

Spring MVC&#xff08;Model-View-Controller&#xff09;是一种基于Java的实现了MVC设计模式的轻量级Web框架。它通过一套注解&#xff0c;可以快速地搭建一个可扩展、易维护的Web应用程序。下面是Spring MVC处理请求的基本流程&#xff1a; 用户发起请求&#xff1a;用户通过…

Parquet使用指南:一个超越CSV、提升数据处理效率的存储格式

前言 在大数据时代&#xff0c;数据存储和处理的效率越来越重要。同时&#xff0c;我们在工作中处理的数据也越来越多&#xff0c;从excel格式到csv格式&#xff0c;从文件文档传输到直接从数据库提取&#xff0c;数据单位也从K到M再到G。 当数据量达到了G以上&#xff0c;几…

ROS | 自动导航

保存&加载地图&#xff1a; image:地图文件 resolution:地图分辨率&#xff08;珊格地图&#xff09; origin&#xff1a;地图左下标 第三个参数是偏转角度 加载创建好的yaml文件&#xff1a; 年轻人第一次导航&#xff1a; 全局规划器&#xff1a; 代价地图设置参数&#…

K-means聚类模型入门介绍

K-means聚类是一种无监督学习方法&#xff0c;广泛应用于数据挖掘、机器学习和模式识别等领域&#xff0c;用于将数据集划分为K个簇&#xff08;cluster&#xff09;&#xff0c;其中每个簇的数据具有相似的特征。其基本思想是通过迭代寻找使簇内点间距离平方和最小的簇划分方式…

纯命令行登录dlut-lingshui并实现断网重连

1 写在前面 本文章改写自《shell脚本登录dlut-lingshui并设置开机连网和断网重连》&#xff0c;旨在利用其脚本解决无图形界面情况下的校园网登录以及断网重连问题。本文仅作使用脚本的示范而不分析原理&#xff0c;若对脚本细节感兴趣可以查阅原文。 2 操作步骤 2.1 修改代…

【华为OD机试-C卷D卷-200分】运输时间(C++/Java/Python)

【华为OD机试】-(A卷+B卷+C卷+D卷)-2024真题合集目录 【华为OD机试】-(C卷+D卷)-2024最新真题目录 题目描述 M(1 ≤ M ≤ 20)辆车需要在一条不能超车的单行道到达终点,起点到终点的距离为 N(1 ≤ N ≤ 400)。速度快的车追上前车后,只能以前车的速度继续行驶,求最后一…

K8S-pod资源 探针

一.pod资源限制&#xff1a; 对pod资源限制原因&#xff1a;高并发占用所有的cpu资源、内存资源、会造成雪崩 当定义 Pod 时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是 CPU 和内存大小&#xff0c;以及其他类型的资源。 方式&#xff1a; 对pod做…

UML-系统架构师(二)

1、UML&#xff08;Unified Modeling Language&#xff09;是面向对象设计的建设工具&#xff0c;独立于任何具体程序设计语言&#xff0c;以下&#xff08;&#xff09;不属于UML中的模型。 A用例图 B协作图 C活动图 DPAD图 解析&#xff1a; UML一共14种图 结构图&…

【蓝桥杯——物联网设计与开发】拓展模块2 - 电位器模块

一、电位器模块 &#xff08;1&#xff09;资源介绍 &#x1f505;原理图 蓝桥杯物联网竞赛实训平台提供了一个拓展接口 CN2&#xff0c;所有拓展模块均可直接安装在 Lora 终端上使用&#xff1b; 图1 拓展接口 电位器模块电路原理图如下所示&#xff1a; 图2 …

python数据分析——apply 2

参考资料&#xff1a;活用pandas库 1、向量化函数 使用apply时&#xff0c;可以按行或按列应用函数。如果想应用自定义的函数&#xff0c;必须重写它&#xff0c;因为整列或整行传递到了函数的第一个参数中。可以利用向量化函数和装饰器对所有函数进行向量化。对代码进行向量化…

Flutter 中的 CompositedTransformTarget 小部件:全面指南

Flutter 中的 CompositedTransformTarget 小部件&#xff1a;全面指南 在Flutter的动画和高级布局系统中&#xff0c;CompositedTransformTarget是一个与CompositedTransformFollower配合使用的组件&#xff0c;用于创建硬件加速的跟随动画和视差效果。这种类型的动画通常用于…

再论任何图≌自己这一几何最最起码常识推翻平面公理

黄小宁 有了解析几何使人类对直线和射线的认识有革命性的飞跃。几何学有史2300年来一直认定起点和射出的方向都相同的射线必重合&#xff0c;任两异射线必有全等关系&#xff1b;解析几何使我发现这是2300年肉眼直观错觉。 h定理&#xff08;参考文献中的定理&#xff09;&am…

台式机安装ubuntu过程

1.单系统参考 20231210-超详细Ubuntu20.04单系统安装_台式机安装ubuntu系统-CSDN博客 2.双系统参考 双系统启动效果_哔哩哔哩_bilibili 安装前一定要先清空电脑的硬盘数据&#xff0c;不然可能会出现以下图片异常 意思估计是分区被占用了&#xff0c;出现这个问题 &#xff0…

安全基础二

一、插件漏洞 统计使用了哪些插件这些插件有版本更新嘛检测这些插件是否存在已知漏洞 二、权限提升和持久化 SSRF&#xff08;Server-Side Request Forgery&#xff0c;服务器端请求伪造&#xff09; 想象一下&#xff0c;你是一个公司的内部员工&#xff08;服务器&#x…

知攻善防应急响应靶机训练-Web2

前言&#xff1a; 本次应急响应靶机采用的是知攻善防实验室的Web-2应急响应靶机 靶机下载地址为&#xff1a; https://pan.quark.cn/s/4b6dffd0c51a 相关账户密码 用户:administrator 密码:Zgsfqq.com 解题过程&#xff1a; 一、攻击者的IP地址&#xff08;两个&#xff09;…

防火墙基础基础篇:NAT转发功能之——Easy IP方式详解

防火墙基础基础篇&#xff1a;NAT转发功能之——Easy IP方式详解 1. 概念 Easy IP 是一种简化版的动态NAPT&#xff08;Network Address and Port Translation&#xff09;技术。在Easy IP中&#xff0c;我们只使用一个公网IP地址&#xff0c;无需建立公有IP地址池。这个公网…

2024 年科技裁员综合清单

推荐阅读&#xff1a; 独立国家的共同财富 美国千禧一代的收入低于父辈 创造大量就业机会却毁掉了财富 这四件事是创造国家财富的关键 全球财富报告证实联盟自始至终无能 美国人已陷入无休止债务循环中&#xff0c;这正在耗尽他们的财务生命 2024 年&#xff0c;科技行业…