首页 > 其他分享 >使用BGE进行意图分类的示例代码

使用BGE进行意图分类的示例代码

时间:2024-04-03 15:46:35浏览次数:14  
标签:loss BGE 示例 模型 labels ids 意图 input self

 

import torch
from torch.utils.data import DataLoader, RandomSampler, TensorDataset
from transformers import BertTokenizer, BertForSequenceClassification, AdamW

bge_model_name = "BAAI/bge-large-zh-v1.5"
bert_model_name = 'bert-base-uncased'

class TextClassifier:
    def __init__(self, model_name=bge_model_name, num_labels=2):
        self.tokenizer = BertTokenizer.from_pretrained(model_name)
        self.model = BertForSequenceClassification.from_pretrained(model_name, num_labels=num_labels)
        self.optimizer = AdamW(self.model.parameters(), lr=2e-5)

    def prepare_data(self, texts, labels, max_length=64):
        input_ids = []
        attention_masks = []
        for text in texts:
            encoded_dict = self.tokenizer.encode_plus(
                text,
                add_special_tokens=True,
                max_length=max_length,
                pad_to_max_length=True,
                return_attention_mask=True,
                return_tensors='pt',
            )
            input_ids.append(encoded_dict['input_ids'])
            attention_masks.append(encoded_dict['attention_mask'])

        input_ids = torch.cat(input_ids, dim=0)
        attention_masks = torch.cat(attention_masks, dim=0)
        labels = torch.tensor(labels)
        return TensorDataset(input_ids, attention_masks, labels)

    def train(self, dataset, epochs=4, batch_size=2):
        dataloader = DataLoader(dataset, sampler=RandomSampler(dataset), batch_size=batch_size)
        for epoch in range(epochs):
            print(f"Epoch {epoch + 1}/{epochs}")
            print('-' * 10)
            total_loss = 0
            self.model.train()
            for step, batch in enumerate(dataloader):
                b_input_ids, b_input_mask, b_labels = batch
                self.model.zero_grad()
                outputs = self.model(b_input_ids, token_type_ids=None, attention_mask=b_input_mask, labels=b_labels)
                loss = outputs.loss
                total_loss += loss.item()
                loss.backward()
                self.optimizer.step()
            avg_train_loss = total_loss / len(dataloader)
            print(f"Average training loss: {avg_train_loss:.2f}")
            # 在每个epoch后评估模型的精度
            test_accuracy = self.evaluate_accuracy(test_dataset, batch_size=batch_size)
            print(f"Test Accuracy after epoch {epoch + 1}: {test_accuracy:.2f}")

    def evaluate_accuracy(self, dataset, batch_size=2):
        dataloader = DataLoader(dataset, sampler=RandomSampler(dataset), batch_size=batch_size)
        correct = 0
        total = 0
        self.model.eval()
        with torch.no_grad():
            for batch in dataloader:
                b_input_ids, b_input_mask, b_labels = batch
                outputs = self.model(b_input_ids, token_type_ids=None, attention_mask=b_input_mask)
                logits = outputs.logits
                predictions = torch.argmax(logits, dim=1)
                total += b_labels.size(0)
                correct += (predictions == b_labels).sum().item()
        return correct / total

    def predict(self, text):
        inputs = self.tokenizer.encode_plus(
            text,
            add_special_tokens=True,
            max_length=64,
            pad_to_max_length=True,
            return_attention_mask=True,
            return_tensors='pt',
        )
        input_ids = inputs['input_ids']
        attention_mask = inputs['attention_mask']
        self.model.eval()
        with torch.no_grad():
            outputs = self.model(input_ids, token_type_ids=None, attention_mask=attention_mask)
            logits = outputs.logits
            predicted_class_id = logits.argmax().item()
        return predicted_class_id

# 使用示例
classifier = TextClassifier()

# 通用知识场景/告警调查场景/调查响应场景/事件智能化处置/威胁建模等
# 分别对应0,1,2,3,4
# 定义训练数据
# 假设的数据集
trained_texts = ["如何配置防火墙产品?", "How to configure firewall product?", "EDR product performance?", "This event is attack successful?", "What is SQL injection?"]
# 通用知识场景/告警调查场景/调查响应场景/事件智能化处置/威胁建模等
# 分别对应0,1,2,3,4
trained_labels = [1, 1, 1, 0, 0]  # 1代表通用场景,0代表其他场景

# 假设的测试数据集
test_texts = ["How to configure firewall?", "防火墙的产品配置是如何做?", "Give me as SQL injection attack example?"]
test_labels = [1, 1, 0]

# 准备数据
train_dataset = classifier.prepare_data(trained_texts, trained_labels)
test_dataset = classifier.prepare_data(test_texts, test_labels)

# 训练模型
classifier.train(train_dataset, epochs=20)

# 评估模型
test_accuracy = classifier.evaluate_accuracy(test_dataset)
print(f"Test Accuracy: {test_accuracy:.2f}")

# 预测
test_text = "This is a firewall product, configure ok?"
test_text = "要如何配置防火墙呢?"
prediction = classifier.predict(test_text)
print(f"Predicted class for '{test_text}': {prediction}")

 

算法运行结果:

Epoch 1/20
----------
Average training loss: 1.10
Test Accuracy after epoch 1: 1.00
Epoch 2/20
----------
Average training loss: 0.17
Test Accuracy after epoch 2: 1.00
Epoch 3/20
----------
Average training loss: 0.09
Test Accuracy after epoch 3: 1.00
Epoch 4/20
----------
Average training loss: 0.06
Test Accuracy after epoch 4: 1.00
Epoch 5/20
----------
Average training loss: 0.03
Test Accuracy after epoch 5: 1.00
Epoch 6/20
----------
Average training loss: 0.02
Test Accuracy after epoch 6: 1.00
Epoch 7/20
----------
Average training loss: 0.01
Test Accuracy after epoch 7: 1.00
Epoch 8/20
----------
Average training loss: 0.00
Test Accuracy after epoch 8: 1.00
Epoch 9/20
----------
Average training loss: 0.00
Test Accuracy after epoch 9: 1.00
Epoch 10/20
----------
Average training loss: 0.00
Test Accuracy after epoch 10: 1.00
Epoch 11/20
----------
Average training loss: 0.00
Test Accuracy after epoch 11: 1.00
Epoch 12/20
----------
Average training loss: 0.00
Test Accuracy after epoch 12: 1.00
Epoch 13/20
----------
Average training loss: 0.00
Test Accuracy after epoch 13: 1.00
Epoch 14/20
----------
Average training loss: 0.00
Test Accuracy after epoch 14: 1.00
Epoch 15/20
----------
Average training loss: 0.00
Test Accuracy after epoch 15: 1.00
Epoch 16/20
----------
Average training loss: 0.00
Test Accuracy after epoch 16: 1.00
Epoch 17/20
----------
Average training loss: 0.00
Test Accuracy after epoch 17: 1.00
Epoch 18/20
----------
Average training loss: 0.00
Test Accuracy after epoch 18: 1.00
Epoch 19/20
----------
Average training loss: 0.00
Test Accuracy after epoch 19: 1.00
Epoch 20/20
----------
Average training loss: 0.00
Test Accuracy after epoch 20: 1.00
Test Accuracy: 1.00

  

模型设计:

class TextClassifier:
    def __init__(self, model_name=bge_model_name, num_labels=2):
        self.tokenizer = BertTokenizer.from_pretrained(model_name)
        self.model = BertForSequenceClassification.from_pretrained(model_name, num_labels=num_labels)
        self.optimizer = AdamW(self.model.parameters(), lr=2e-5)

下面是一个简化的模型示意图,描述了其主要组成部分和数据流向:

  [输入文本] --> [BertTokenizer] --> [编码后的输入]        |        v [BertForSequenceClassification] --> [Logits] --> [Softmax] --> [预测概率]        |        v    [损失函数] <-- [真实标签]        |        v   [AdamW优化器] --> [参数更新]    

1. 输入文本:这是模型的输入,可以是一句话或者一段文本。

2. BertTokenizer:这个分词器将输入文本转换为BERT模型能理解的格式,包括将文本分割成单词或子词单元(token),并将它们转换为对应的ID。同时,它还负责添加必要的特殊标记(如[CLS]、[SEP])和生成注意力掩码。

3. 编码后的输入:这是分词器处理后的结果,包括输入ID和注意力掩码,准备好被模型使用。

4. BertForSequenceClassification:这是一个预训练的BERT模型,经过微调用于序列分类任务。它接收编码后的输入,通过BERT模型的多层Transformer结构进行处理,最后通过一个顶层的线性层输出每个类别的logits。

5. Logits:这是模型输出的原始预测值,未经过softmax归一化,因此不直接表示概率。

6. Softmax:这一步通常在需要将logits转换为概率时进行,比如在评估模型性能或进行预测时。Softmax函数确保所有输出类别的概率和为1。

7. 预测概率:这是经过softmax处理后的模型输出,表示模型对每个类别的预测概率。

  • 真实标签:在训练过程中,每个输入样本都有一个对应的真实标签,用于计算损失函数。

9. 损失函数:根据模型的预测结果和真实标签计算损失值,这个值表示模型当前的性能,训练的目标是最小化这个损失。

10. AdamW优化器:这是用于模型训练的优化器,根据损失函数计算得到的梯度来更新模型的参数,以改进模型的预测性能。

整个流程涵盖了从输入文本到预测结果的转换,以及基于真实标签的模型训练过程。  

 

关键代码说明:

0、模型初始化:

self.model = BertForSequenceClassification.from_pretrained(model_name, num_labels=num_labels) 这个代码作用?

这行代码的作用是加载并初始化一个预训练的BERT模型,用于序列分类任务。具体来说,它执行以下操作:

1. 加载预训练模型:BertForSequenceClassification.from_pretrained(model_name) 通过指定的模型名称 model_name(例如 'bert-base-uncased' 或其他BERT模型),从预训练模型的仓库中加载模型。这个方法会自动下载模型的权重和配置(如果本地没有缓存的话),并将其加载到 BertForSequenceClassification 类的实例中。

2. 指定分类任务的标签数量:num_labels=num_labels 参数指定了模型用于序列分类任务的标签数量。例如,如果你的任务是二分类问题,num_labels 应该设置为2。这个参数决定了模型输出层的维度,使得模型的输出可以对应到指定数量的类别上。

BertForSequenceClassification 是Hugging Face的Transformers库中的一个类,专门用于处理序列分类任务,如情感分析、文本分类等。这个类在BERT的基础上添加了一个顶层的线性层,用于根据BERT的输出进行分类。

总之,这行代码通过加载预训练的BERT模型并根据指定的类别数量调整输出层,创建了一个用于序列分类任务的模型实例。这使得我们可以利用BERT强大的语言表示能力来解决具体的分类问题,同时享受到迁移学习带来的优势。

 

 

1、文本编码:

        input_ids = []
        attention_masks = []
        for text in texts:
            encoded_dict = self.tokenizer.encode_plus(
                text,
                add_special_tokens=True,
                max_length=max_length,
                pad_to_max_length=True,
                return_attention_mask=True,
                return_tensors='pt',
            )
            input_ids.append(encoded_dict['input_ids'])
            attention_masks.append(encoded_dict['attention_mask'])    

这段代码是 TextClassifier 类中 prepare_data 方法的一部分,负责将文本数据编码为模型可以理解的格式。具体来说,它执行以下步骤:

1. 初始化列表: 首先,初始化两个空列表 input_ids 和 attention_masks。这两个列表将用于存储所有文本的编码信息和注意力掩码。

2. 遍历文本: 然后,代码遍历传入的 texts 列表,对每个文本进行处理。texts 是一个字符串列表,每个字符串代表一个待分类的文本。

3. 文本编码: 对于每个文本,使用BERT分词器的 encode_plus 方法进行编码。这个方法将文本转换为模型需要的输入格式,包括:

  • 添加特殊标记: 通过 add_special_tokens=True 参数,自动在每个文本前后添加特殊标记(如CLS和SEP),这对于BERT模型理解句子的开始和结束很重要。
  • 最大长度限制: 通过 max_length 参数限制编码后的长度,超出这个长度的部分将被截断,不足的部分将通过填充来达到这个长度。
  • 填充: 通过 pad_to_max_length=True 参数,确保所有文本编码后的长度一致,不足 max_length 的部分会被填充。
  • 返回注意力掩码: 通过 return_attention_mask=True 参数,生成一个掩码来指示哪些部分是真实文本,哪些部分是填充的。这对模型正确处理输入很重要。
  • 返回张量: 通过 return_tensors='pt' 参数,将编码后的数据转换为PyTorch张量(Tensor),以便直接用于模型训练。

4. 收集编码结果: 将每个文本的 input_ids(编码后的输入ID)和 attention_masks(注意力掩码)分别添加到之前初始化的列表中。

通过这个过程,每个文本被转换成了模型可以处理的格式,包括它的编码ID和对应的注意力掩码,为后续的模型训练和预测准备好了输入数据。

 

 

使用BERT分词器的 encode_plus 方法进行编码,举一个实际例子说明。

假设我们使用BERT分词器对文本 "Hello, BERT!" 进行编码。这里展示的是一个简化的例子,以说明 encode_plus 方法的基本用法和输出。

from transformers import BertTokenizer   # 初始化分词器,这里以 'bert-base-uncased' 为例 tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')   # 待编码的文本 text = "Hello, BERT!"   # 使用encode_plus方法进行编码 encoded_dict = tokenizer.encode_plus(     text,     add_special_tokens=True,  # 添加特殊标记     max_length=10,  # 设定最大长度     pad_to_max_length=True,  # 进行填充     return_attention_mask=True,  # 返回注意力掩码     return_tensors='pt',  # 返回PyTorch张量 )   # 打印编码结果 print("Input IDs:", encoded_dict['input_ids']) print("Attention Mask:", encoded_dict['attention_mask'])  

输出可能如下(具体的ID可能会有所不同,取决于分词器的版本和配置):

Input IDs: tensor([[  101,  7592,  1010, 14324,   999,   102,     0,     0,     0,     0]]) Attention Mask: tensor([[1, 1, 1, 1, 1, 1, 0, 0, 0, 0]])  

这里的输出解释如下:

  • Input IDs: 是文本 "Hello, BERT!" 经过编码后的数字序列。101 和 102 分别是特殊标记 [CLS] 和 [SEP] 的ID,它们分别在编码序列的开始和结束位置添加。7592, 1010, 14324, 999 分别对应 "hello", ",", "bert", "!" 的编码ID。剩余的 0 是因为我们设置了 max_length=10 并启用了填充,所以不足长度的部分被填充了 0。
  • Attention Mask: 是一个与Input IDs相同长度的掩码,用于指示哪些ID是真实文本的一部分(用 1 表示),哪些是填充的部分(用 0 表示)。在这个例子中,前6个位置是真实文本(包括特殊标记),因此对应的是 1,而后4个位置是填充的,因此是 0。

这个例子展示了如何使用BERT分词器的 encode_plus 方法对文本进行编码,以及如何理解编码后的结果。

 

在我们的实际代码中,

如何配置防火墙产品?这几个字对应的编码如下(是不是发现中文的字符是一一对应的ID,包括了标点符号):

[tensor([[ 101, 1963, 862, 6981, 5390, 7344, 4125, 1870, 772, 1501, 8043, 102,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0]])]

 

2、格式化数据:

         input_ids = torch.cat(input_ids, dim=0)
        attention_masks = torch.cat(attention_masks, dim=0)
        labels = torch.tensor(labels)
        return TensorDataset(input_ids, attention_masks, labels)    

这几行代码的作用是将处理过的输入ID、注意力掩码和标签整合成一个PyTorch的 TensorDataset 对象,以便于后续的数据加载和模型训练。具体步骤如下:

1. 合并输入ID 1: torch.cat(input_ids, dim=0) 将之前收集的所有文本的输入ID列表(每个文本的输入ID是一个张量)沿着第一个维度(dim=0)合并成一个大的张量。这样,每一行代表一个文本的输入ID。

2. 合并注意力掩码 (attention_masks): torch.cat(attention_masks, dim=0) 的作用与合并输入ID类似,它将所有文本的注意力掩码沿着第一个维度合并成一个大的张量。每一行代表一个文本的注意力掩码。

3. 转换标签 (labels): torch.tensor(labels) 将标签列表转换成一个PyTorch张量。这个张量包含了每个文本对应的标签,用于训练过程中的监督学习。

4. 创建 TensorDataset: TensorDataset(input_ids, attention_masks, labels) 利用合并后的输入ID张量、注意力掩码张量和标签张量创建一个 TensorDataset 对象。TensorDataset 是PyTorch中的一个便利类,用于将多个张量打包成一个数据集,使得在数据加载器(DataLoader)中使用时能够方便地同时访问所有相关数据。

总之,这几行代码将编码后的文本数据(包括输入ID和注意力掩码)和对应的标签整合成一个格式化的数据集,为模型的训练和评估准备好了数据。

 

3、模型训练:

            total_loss = 0
            self.model.train()
            for step, batch in enumerate(dataloader):
                b_input_ids, b_input_mask, b_labels = batch
                self.model.zero_grad()
                outputs = self.model(b_input_ids, token_type_ids=None, attention_mask=b_input_mask, labels=b_labels)
                loss = outputs.loss
                total_loss += loss.item()
                loss.backward()
                self.optimizer.step()
            avg_train_loss = total_loss / len(dataloader)
            print(f"Average training loss: {avg_train_loss:.2f}")      

这段代码位于 TextClassifier 类的 train 方法中,它实现了模型的训练过程。具体步骤和作用如下:

1. 初始化总损失 (total_loss = 0): 在训练开始前,将总损失初始化为0。这个变量用于累计一个epoch内所有批次的损失,以便计算平均损失。

2. 设置模型为训练模式 (self.model.train()): 通过调用 train() 方法,将模型设置为训练模式。这对于某些模型组件(如Dropout和BatchNorm)是必要的,因为它们在训练和评估时的行为是不同的。

3. 遍历数据加载器 (for step, batch in enumerate(dataloader)): 使用 enumerate 遍历训练数据加载器(DataLoader)中的所有批次。每个批次包含了一组文本的输入ID、注意力掩码和标签。

4. 准备批次数据: 从每个批次中解包输入ID (b_input_ids)、注意力掩码 (b_input_mask) 和标签 (b_labels)。

5. 梯度归零 (self.model.zero_grad()): 在进行反向传播之前,先将模型参数的梯度清零。这是因为默认情况下梯度是累加的,不清零的话会影响到下一批次的梯度计算。

6. 前向传播: 通过模型进行前向传播,传入输入ID、注意力掩码和标签。这里没有传入 token_type_ids 参数,因为对于单句分类任务通常不需要。模型返回的 outputs 包含了多个输出,其中 outputs.loss 是这个批次的损失。

7. 累计损失 (total_loss += loss.item()): 将当前批次的损失加到总损失上。loss.item() 将损失值从张量转换为Python数值。

  • 反向传播 (loss.backward()): 对损失进行反向传播,计算模型参数的梯度。

9. 优化器步进 (self.optimizer.step()): 调用优化器的 step 方法来更新模型的参数,根据计算出的梯度进行一次参数更新。

10. 计算平均训练损失: 在遍历完所有批次后,计算这个epoch的平均训练损失,即总损失除以批次数量。

11. 打印平均训练损失: 打印出这个epoch的平均训练损失,以便监控训练过程。

总之,这段代码实现了模型的一个训练周期(epoch),包括前向传播、损失计算、反向传播和参数更新,以及监控训练损失的功能。  

 

注意:

 1、       optimizer.zero_grad() ==》这个梯度归零是模型参数归零吗?

不是的。optimizer.zero_grad() 这行代码并不是将模型参数归零,而是将模型参数的梯度归零。在PyTorch中,模型的每个参数都有与之对应的梯度,这个梯度用于在训练过程中通过反向传播算法更新参数值。

在每次训练迭代中,模型的前向传播会计算出损失,然后通过反向传播计算损失函数相对于每个参数的梯度。这些梯度累积存储在参数的 .grad 属性中。如果不手动清零,那么下一次反向传播时计算出的梯度会和前一次的梯度累加起来,导致训练过程出错。

因此,optimizer.zero_grad() 的作用是在每次训练迭代开始前清除累积的梯度,确保每次迭代的梯度计算都是基于最新的前向传播结果,而不是之前迭代的残留梯度。这是正确进行模型训练的重要步骤。

2、outputs = self.model(b_input_ids, token_type_ids=None, attention_mask=b_input_mask, labels=b_labels) 这行代码是什么作用

这行代码是在训练循环中,用于执行模型的前向传播和计算损失的关键步骤。具体来说,它的作用如下:

1. 前向传播:通过将输入数据(b_input_ids 和 b_input_mask)传递给模型 (self.model),执行前向传播过程。这里的 b_input_ids 是批次中每个文本输入的编码形式,b_input_mask 是对应的注意力掩码,用于指示模型哪些位置是实际的输入,哪些位置是填充的。token_type_ids 在这个调用中被设置为 None,这是因为对于单句输入或者不需要区分两个句子的场景,token_type_ids 不是必需的。

2. 计算损失:在这个调用中,还传入了 labels=b_labels,其中 b_labels 是当前批次中每个输入文本对应的标签。当 labels 参数被提供给模型时,除了执行前向传播外,模型还会根据预测结果和真实标签计算损失。这个损失是模型训练过程中需要最小化的目标。

3. 获取输出:调用返回的 outputs 包含了多个输出信息,其中最重要的是损失值(outputs.loss),它表示当前批次的平均损失。如果模型配置为输出其他信息(如分类任务中的 logits),这些信息也可以从 outputs 中获取。

总结来说,这行代码通过执行模型的前向传播来计算每个输入的预测结果,同时基于预测结果和真实标签计算损失,这个损失将用于后续的反向传播和模型参数的更新。这是模型训练过程中的核心步骤之一。

 

4、with torch.no_grad()  作用

with torch.no_grad() 是一个上下文管理器,用于在代码块内部暂时禁用梯度计算。在PyTorch中,这是一种常用的做法,特别是在模型评估(如验证和测试)或进行推理(预测)时,因为在这些场景下我们通常不需要计算梯度。

使用 with torch.no_grad() 的好处包括:

1. 减少内存消耗:由于不需要计算和存储梯度,这可以显著减少内存的使用,使得在资源有限的设备上运行大型模型变得更加可行。

2. 提高计算效率:禁用梯度计算可以减少计算的负担,从而加快模型的推理速度。

示例用法如下:

with torch.no_grad():     # 在这个代码块中,所有的计算都不会跟踪梯度     outputs = model(input_data)     # 可以进行评估或推理操作,而不会影响梯度  

在这个上下文管理器的作用域内,所有的Tensor操作都不会跟踪历史,因此不会计算梯度。这对于评估和推理阶段是非常有用的,因为在这些阶段我们只关心模型的输出,而不需要进行反向传播。

 

5、模型预测:

                 b_input_ids, b_input_mask, b_labels = batch
                outputs = self.model(b_input_ids, token_type_ids=None, attention_mask=b_input_mask)
                logits = outputs.logits
                predictions = torch.argmax(logits, dim=1)
                total += b_labels.size(0)
                correct += (predictions == b_labels).sum().item()       

这段代码是在模型评估或测试阶段使用的,用于计算模型在给定数据批次上的准确率。具体步骤如下:

1. 解包批次数据:b_input_ids, b_input_mask, b_labels = batch 从当前批次中解包出输入ID (b_input_ids)、注意力掩码 (b_input_mask) 和真实标签 (b_labels)。

2. 模型前向传播:outputs = self.model(b_input_ids, token_type_ids=None, attention_mask=b_input_mask) 通过模型进行前向传播,传入输入ID和注意力掩码。这里没有使用 token_type_ids 参数,因为它主要用于处理两个句子的输入(如问答任务),在单句子分类任务中通常不需要。

3. 获取预测结果:logits = outputs.logits 从模型输出中提取logits。Logits是模型最后一层的原始输出,通常需要通过softmax函数转换成概率。

4. 计算预测标签:predictions = torch.argmax(logits, dim=1) 使用 torch.argmax 函数沿着维度1(列)找到logits中的最大值的索引,这些索引即为模型预测的标签。

5. 累计总样本数:total += b_labels.size(0) 更新总样本数,b_labels.size(0) 返回当前批次的样本数。

6. 计算正确预测的数量:correct += (predictions == b_labels).sum().item() 通过比较预测标签和真实标签是否相等,计算出正确预测的数量,并累加到 correct 变量中。(predictions == b_labels) 生成一个布尔张量,表示每个样本是否被正确分类,.sum().item() 将这个布尔张量中的True值(即正确预测)求和,转换为Python的标量。

总之,这段代码通过模型对一批数据进行预测,并计算模型在这批数据上的准确性(即正确预测的样本数占总样本数的比例)。这是评估模型性能的常用方法之一。  

注意:

Logits本身是模型最后一层的输出,通常表示为未经归一化的预测值,它们不是概率分布,因此它们的和不一定为1。要将logits转换为概率分布(即使得各类别的预测概率之和为1),通常会通过softmax函数进行处理。

Softmax函数作用于logits上,按如下方式计算每个类别的概率:

softmax(��)=���∑����softmax(zi​)=∑j​ezj​ezi​​

其中,��zi​ 是logits向量中第 �i 个元素的值,分母是对所有logits元素应用指数函数后的值的总和。这样处理后,每个元素的值都被压缩到了(0, 1)区间内,且所有元素的值之和为1,从而可以被解释为概率分布。

 

标签:loss,BGE,示例,模型,labels,ids,意图,input,self
From: https://www.cnblogs.com/bonelee/p/18112823

相关文章

  • 基于Node.js和ws库搭建WebSocket服务并实现消息互通的简单示例
    环境要求:Node.js环境安装npm(Node.js的包管理器)步骤:安装Node.js:如果你还没有安装Node.js,请从Node.js官网下载并安装。创建项目:创建一个新的目录作为项目文件夹,并在该目录下初始化一个新的Node.js项目。        mkdirmy-websocket-server        cdmy......
  • R语言 基于人口的医师配置公平性洛伦兹曲线的代码和示例
    文章目录前言一、洛伦兹曲线介绍二、基于人口的医师配置洛伦兹曲线    1.创建模拟数据    2.绘制洛伦兹曲线总结前言洛伦兹曲线(LorenzCurve)是一种用于描述资源分配公平性的图形表示方法,可用于评价卫生技术人员的分布公平性。洛伦兹曲线可以......
  • R语言 基于人口的医师配置公平性基尼系数计算代码和示例
    文章目录前言一、基尼系数原理介绍二、基于人口的医师配置基尼系数计算步骤    1.自定义建立基尼系数计算函数     2.运用基尼系数计算函数进行计算    3.使用模拟数据进行示例......
  • 第十一篇【传奇开心果系列】Python自动化办公库技术点案例示例:深度解读Python自动化操
    传奇开心果博文系列系列博文目录Python自动化办公库技术点案例示例系列博文目录前言一、重要作用二、Python操作PDF文件转Word文档介绍三、提高效率示例代码四、保持一致性示例代码五、精确度与质量控制示例代码六、适应复杂需求示例代码七、可扩展性与与集成性示例代码......
  • vue3+ant-design-vue - 最新实现“侧边动态导航栏+面包屑导航“功能,vue3+ant后台管理
    效果图在vue3+antdesignvue后台管理系统中,详细完成菜单导航+面包屑动态联动功能效果,支持缓存功能、配置简洁、自动跟随route路由进行变化、自动匹配菜单和面包屑导航的文字等,超详细实用的示例demo全部源代码。提供详细示例源代码,新手小白直接复制稍微改下配置就能用了,快......
  • vue2 +element-ui图片上传示例
    这里使用了一个没有用的裁剪插件,需要先下载它[email protected]然后在main.js引入:importVueCropperfrom'vue-cropper'Vue.use(VueCropper)1、html部分:<template><el-formref="form":model="form"label-width="1.2rem&qu......
  • ES6 reduce方法:示例与详解、应用场景
    还是大剑师兰特:曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas,webgl,echarts等技术开发,欢迎加底部微信(gis-dajianshi),一起交流。No.内容链接1Openlayers【入门教程】-......
  • CCF CSP模拟真题解答示例
    CCFCSP(CertifiedSoftwareProfessional)是中国计算机学会主办的软件能力认证考试,旨在评估参赛者在计算机科学和软件工程方面的基本知识和实践能力。请注意,以下解答仅作为示例,并非针对实际真题的准确答案。实际考试中的题目和答案可能会有所不同,因此建议参考官方发布的真题......
  • 大屏可视化项目示例--基于Vue3+vite2+echart+mock+axios+dataV
    图例: 项目环境:Vite、Echarts、Npm、Node、axios、mock、vue3、dataV。项目地址:IofTV-Screen-Vue3:......
  • 身份证实名认证接口会返回什么?javascript身份核验接口示例
    身份证实名认证接口是通过核验身份证号、姓名、证件头像等一系列的要素信息进行用户身份验证,那么,身份证实名认证接口一般在核验完成后会返回什么参数信息呢?下面翔云API小编为大家答疑解惑!一般情况下,身份核验只会返回一致或者不一致的结果,不一致的情况下会返回那些参数不一致,以翔......