想接外包做网站/百度获客平台怎么收费的

想接外包做网站,百度获客平台怎么收费的,富阳住房和城乡建设部网站,网站被百度k是什么意思目录 一、准备阶段 1.导入模块 2.指定使用的是GPU还是CPU 3.加载数据集 二、对数据添加词元和分词 1.根据BERT的预训练,我们要将一个句子的句头添加[CLS]句尾添加[SEP] 2.激活BERT词元分析器 3.填充句子为固定长度 代码解释: 三、数据处理 1.…

目录

一、准备阶段

1.导入模块

2.指定使用的是GPU还是CPU

3.加载数据集

二、对数据添加词元和分词

1.根据BERT的预训练,我们要将一个句子的句头添加[CLS]句尾添加[SEP]

2.激活BERT词元分析器

3.填充句子为固定长度

代码解释:

三、数据处理

1.创建masks掩码矩阵

代码解释:

2.拆分数据集

3.将所有的数据转换为torch张量

4.选择批量大小并创建迭代器

代码解释:

四、BERT模型配置

1.初始化一个不区分大小写的 BERT 配置:

代码解释:

2.这些配置参数的作用:

3.加载模型

4.优化器分组参数

代码解释:

5.训练循环的超参数

代码解释:

五、训练循环

代码解释:

训练图解:

 六、使用测试数据集进行预测和评估

七、使用马修斯相关系数(MCC)评估

2. 代码实现:

1. 测试数据预处理与预测

2.模型预测与结果收集

3.计算MCC

到这里就完美收官咯!!!!! 大家点个赞吧!!!


本章将微调一个BERT模型来预测下游的可接受性判断任务,如果你的电脑还没有配置相关环境的可以去使用 Colaboratory - Colab,里面已经全部帮你配置好啦!而且还可以免费使用GPU。

一、准备阶段

1.导入模块

导入所需的预训练相关模块,包括用于词元化的 BertTokenizer、用于配置 BERT 模型的 BertConfig,还有 Adam 优化器(AdamW),以及序列分类模块(BertFo SequenceClassification):

import torch
import torch.nn as nn
from torch.utils.data import TensorDataset,DataLoader,RandomSampler,SequentialSampler
from sklearn.model_selection import train_test_split
from transformers import BertTokenizer,BertConfig
from transformers import BertForSequenceClassification,get_linear_schedule_with_warmup
# from transformers import AdamW
from torch.optim import AdamW
from tqdm import tqdm,trange
import pandas as pd
import io
import numpy as np
import matplotlib.pyplot as plt# 导入进度条
from tqdm import tqdm,trange
# 导入常用的标注python模块
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

2.指定使用的是GPU还是CPU

使用GPU加速对我们的训练非常又有帮助

device = torch.device("cuda" if torch.cuda.is_avsilable() else "cpu")

3.加载数据集

这里的代码和数据是参考https://github.com/Denis2054/Transformers-for-NLP-2nd-Edition/tree/main/Chapter03

使用git仓库拉取一下就可以得到数据了

df=pd.read_csv("你拉取的数据in_domain_train.tsv的路径",delimiter='\t',header=None,names=['sentence_source','label','label_notes','sentence'])
# 展示数据维度
df.shape  # (8551,4)

随机抽取十个样本数据的看看:

df.sample(10)

 以看到数据集中的数据包含了以下四列(即.tsv文件中四个用制表符分隔的列)。

● 第1列:句子来源(用编号表示)

● 第2列:标注(0=不可接受,1= 可接受)

● 第3列:作者的标注

● 第4列;要分类的句子

二、对数据添加词元和分词

1.根据BERT的预训练,我们要将一个句子的句头添加[CLS]句尾添加[SEP]

代码解释:将数据中的需要分类的句子提取为sentences,循环出每个句子,在每个句子的句头添加[CLS]句尾添加[SEP],将数据中的标签提取为labels

sentences=df.sentence.values
sentences=["[CLS]"+ sentence+"[SEP]" for sentence in sentences]
labels=df.label.values

2.激活BERT词元分析器

这里是初始化一个预训练BERT词元分析器。相比与从头开始训练一个词元分析器相对,节省很多时间和资源。们选择了一个不区分大小写的词元分析器,激活它,并展示对第一个句子词元 化之后的结果:

代码讲解:tokenizer是我们初始化的词元分析器,BertTokenizer.from_pretrained('bert-base-uncased')是使用BERT中自带的预训练好的参数,关于BertTokenizer.from_pretrained可以去看我的另外一章博客BertTokenizer.from_pretreined。

        tokenizer_texts是已经每个句子词元分析好的一个迭代器,因为sentences中保存的句子的type为array类型,而tokenize中要传入的是字符串类型,所以这里要强转一下

词元分析后的一条句子为:Tokenize the first sentence: ['[CLS]', 'our', 'friends', 'wo', 'n', "'", 't', 'buy', 'this', 'analysis', ',', 'let', 'alone', 'the', 'next', 'one', 'we', 'propose', '.', '[SEP]']

tokenizer=BertTokenizer.from_pretrained('bert-base-uncased')
tokenizer_texts=[tokenizer.tokenize(str(sent)) for sent in sentences]
print("Tokenize the first sentence: ")
print(tokenizer_texts[0])
# Tokenize the first sentence: 
['[CLS]', 'our', 'friends', 'wo', 'n', "'", 't', 'buy', 'this', 'analysis', ',', 'let', 'alone', 'the', 'next', 'one', 'we', 'propose', '.', '[SEP]']

3.填充句子为固定长度

上面的处理中我们不难想到,每个句子分析后的长度会随句子的大小而改变,而在BERT微调的时候需要保证句子的长度应用,所以我们要将长度不够的句子进行填充,我们将这个最大长度设置为128,对于长度超过128的数据我们将它截断,保证每个句子序列的大小都为128

代码解释:

input_ids:里面保存的是将上面的句子分词后的词元列表转化成对应数字的列表,其中将词元一个个的循环出来后经过tokenizer.convert_tokens_to_ids,它能把分词后的词元转化为整数 ID,从而让深度学习模型能够处理文本数据。在不同的库中,其使用方式可能会有所不同,但核心功能是一致的。

第二个input_ids:保存的是将每个词元序列转化成相同大小后的迭代器,pad_sequences函数的主要作用是将多个序列填充或截断至相同的长度,这在处理序列数据(像文本序列)时十分关键,因为神经网络通常要求输入数据具有统一的形状

from tensorflow.keras.preprocessing.sequence import pad_sequences
MAX_LEN=128
input_ids=[tokenizer.convert_tokens_to_ids(x) for x in tokenizer_texts]
print(input_ids[0])
input_ids=pad_sequences(input_ids,maxlen=MAX_LEN,dtype='long',truncating='post',padding='post')
print(input_ids[0])

三、数据处理

1.创建masks掩码矩阵

如果不知道为什么需要掩码的可以去看看transformers架构

为了防止模型对填充词元进行注意力计算,我们在前面的步骤中对序列进行了填充补齐。但是我们希望防止模型对这些填充 的词元进行注意力计算!首先创建一个空的 attention_masks 列表,用于存储每个序列的注意力掩码。然后, 对于输入序列(input_ids)中的每个序列(seq),我们遍历其中的每个词元。

针对每个词元,我们判断其索引是否大于 0。如果大于 0,则将对应位置的掩码 值设置为1,表示该词元是有效词元。如果等于0,则将对应位置的掩码值设置为0, 表示该词元是填充词元。最终得到的 attention_masks 列表中的每个元素都是一个与对应输入序列长度相同的 列表,其中每个位置的掩码值表示该位置的词元是否有效(1表示有效,0表示填充)。

通过使用注意力掩码,可确保在模型的注意力计算中,只有真实的词元会被考虑, 而填充词元则被忽略。这样可提高计算效率,并减少模型学习无用信息的概率。

代码解释:

attention_masks是保存所有词元掩码的列表,上面我们说到input_ids保存的是将每个词元序列转化成相同大小后的迭代器,我们将里面的每个词元序列遍历为seq,判断seq中的值是否大于0,如果大于0,那么它是有效词元,将他对应的掩码设置为1,反正为0

attention_masks=[]
for seq in input_ids:seq_mask=[float(i>0) for i in seq]attention_masks.append(seq_mask)
print(attention_masks[0])
"""[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.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.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.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.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.0, 0.0, 0.0, 0.0, 0.0]"""

2.拆分数据集

将数据拆分成训练集和验证集,训练集和测试集的比例为9:1

# 拆分训练集和验证集 (90%训练,10%验证)
train_inputs, val_inputs, train_labels, val_labels = train_test_split(input_ids, labels, test_size=0.1, random_state=2025)
train_masks, val_masks, _, _ = train_test_split(attention_masks, labels, test_size=0.1, random_state=2025)  

3.将所有的数据转换为torch张量

微调模型需要使用 torch 张量,所以我们需要将数据转换为 torch 张量:

train_inputs = torch.tensor(train_inputs)validation_inputs = torch.tensor(validation_inputs)txain_labels=torch.tensor(train_labels)validation_labels = torch.tensor(validation_labels)train_masks = torch.tensor(train_masks)validation_masks = torch.tensor(validation_masks)

4.选择批量大小并创建迭代器

如果一股脑地将所有数据都喂进机器,会导致机器因为内存不足而崩溃。所以需 要将数据一批一批地喂给机器。这里将把批量大小(batch size)设置为 32 并创建迭代 器。然后将迭代器与 torch的 DataLoader 相结合,以批量训练大量数据集,以免导致 机器因为内存不足而崩溃:

代码解释:

这里我们选的批量大小(batch_size)为32,使用TensorDataset和DataLoader创建训练数据迭代器,如果对TensorDataset和DataLoader不清楚的可以去看看我的另外一篇博客:TensorData和DataLoader

RandomSampler 是一种随机采样器,从给定的数据集中随机抽取样本,可选择有放回或无放回采样。无放回采样时,从打乱的数据集里抽取样本;有放回采样时,可指定抽取的样本数量 num_samples

batch_size=32
# 训练数据迭代器
train_data=TensorDataset(train_inputs,train_masks,train_labels)
train_sampler=RandomSampler(train_data)
train_dataloader=DataLoader(train_data,sampler=train_sampler,batch_size=batch_size)
# 测试数据迭代器validation_data=TensorDataset(validation_inputs,validation_masks,validation_label)
validation_sampler=RandomSampler(train_data)
validation_dataloader=DataLoader(validation_data,sampler=validation_sampler,batch_size=batch_size)

四、BERT模型配置

1.初始化一个不区分大小写的 BERT 配置:

代码解释:

后面的代码寻妖用到transformers这个包,如果没有的pip安装一下。

configuration是初始化了一个包含BERT预训练模型中所有超参数的配置实例,如果BertConfig中不加任何的参数,那么会生成一个标准的BERT-base配置:

{"hidden_size": 768,          # 每个Transformer层的维度"num_hidden_layers": 12,     # Transformer层数(深度)"num_attention_heads": 12,    # 注意力头的数量"intermediate_size": 3072,   # FeedForward层的中间维度"vocab_size": 30522,         # 词表大小(需与预训练模型一致)"max_position_embeddings": 512, # 最大序列长度...
}

 model:BertModel是根据配置生成一个随机初始化权重的BERT模型,根据传入的配置信息生成。

configuration是一个保存模型内部存储的配置信息副本

try:import transformers
except:print("installing transformers")
from transformers import BertModel,BertConfig
configuration=BertConfig()model=BertModel(config=configuration)
configuration=model.config
print(configuration)
"""
输出为:
BertConfig {"_attn_implementation_autoset": true,"attention_probs_dropout_prob": 0.1,"classifier_dropout": null,"hidden_act": "gelu","hidden_dropout_prob": 0.1,"hidden_size": 768,"initializer_range": 0.02,"intermediate_size": 3072,"layer_norm_eps": 1e-12,"max_position_embeddings": 512,"model_type": "bert","num_attention_heads": 12,"num_hidden_layers": 12,"pad_token_id": 0,"position_embedding_type": "absolute","transformers_version": "4.50.0","type_vocab_size": 2,"use_cache": true,"vocab_size": 30522
}
"""

2.这些配置参数的作用:

"""

attention probs_dropout_prob:对注意力概率应用的 dropout 率,这里设置为

0.1。

● hidden_act;编码器中的非线性激活函数,这里使用 gelu。gelu 是高斯误差线

性单位(Gaussian Eror Linear Units)激活函数的简称,它对输入按幅度加权,

使其成为非线性。

● hidden_dropout_prob:应用于全连接层的 dropout 概率。嵌入、编码器和汇聚

器层中都有全连接。输出不总是对序列内容的良好反映。汇聚隐藏状态的序

第3章 微调BERT 模型

列可改善输出序列。这里设置为0.1。

● hidden_size:编码器层的维度,也是汇聚层的维度,这里设置为768。

● initializer_range:初始化权重矩阵时的标准偏差值,这里设置为0.02。

· intermediate_size:编码器前馈层的维度,这里设置为3072。

● layer_norm_eps:是层规范化层的 epsilon 值,这里设置为le-12。

● max_position_embeddings:模型使用的最大长度,这里设置为512。

● model_type:模型的名称,这里设置为 bert。

● numattention_heads:注意力头数,这里设置为12。

· num_hidden_layers:层数,这里设置为12。

● pad_tokenid:使用0作为填充词元的HD,以避免对填充词元进行训练。

57

 · type_vocab_size:token_type_ids的大小用于标识序列。例如,“the dog[SEP]

 The cat.[SEP]”可用词元 ID [0,0,0,1,1,1]表示。

· vocab_size:模型用于表示 input_ids 的不同词元数量。换句话说,这是模型

可以识别和处理的不同词元或单词的总数。在训练过程中,模型会根据给定

的词表将文本输入转换为对应的词元序列,其中包含的词元数量是

vocab_size。通过使用这个词表,模型能够理解和表示更广泛的语言特征。这

里设置为 30522。

讲解完这些参数后,接下来将加载预训练模型。

"""

3.加载模型

现在开始加载预训练BERT模型

BertForSequenceClassification.from_pretrained 能够让你加载预训练的 BERT 模型权重,并且可以根据需求调整模型以适应特定的序列分类任务。这个方法非常实用,因为借助预训练的权重,模型通常能更快收敛,并且在特定任务上表现更优。第一个参数bert-base-uncased意思是加载BERT的默认权重,如果你有别的模型权重可以填写它的名字或者路径;nums_labels:表示你这个任务中的类别数,我们这个任务的label只有两种,所以这里是2。

DataParallel:DataParallel 是一种数据并行的实现方式,其核心思想是将大规模的数据集分割成若干个较小的数据子集,然后将这些子集分配到不同的计算节点(如 GPU)上,每个节点运行相同的模型副本,但处理不同的数据子集。在每一轮训练结束后,各节点会将计算得到的梯度进行汇总,并更新模型参数。如果不知道分布式计算的可以去看看我的另外一篇博客如何在多个GPU上训练

model=BertForSequenceClassification.from_pretrained("bert-base-uncased",num_labels=2)
model=nn.DataParallel(model)
model.to(device)

4.优化器分组参数

在将为模型的参数初始化优化器。在进行模型微调的过程中,首先需要初始化 预训练模型已学到的参数值。 微调一个预训练模型时,通常会使用之前在大规模数据上训练好的模型作为初始 模型。这些预训练模型已通过大量数据和计算资源进行了训练,学到了很多有用的特 征表示和参数权重。因此,我们希望在微调过程中保留这些已经学到的参数值,而不 是重新随机初始化它们。 所以,程序会使用预训练模型的参数值来初始化优化器,以便在微调过程中更好 地利用这些已经学到的参数。这样可以加快模型收敛速度并提高微调效果;

代码解释:

这段代码是用与为BERT模型的参数设置差异化的权重衰减策略,是训练Transformer模型时的常用技巧

param_optimizer是以字典的方式保存模型中所有可训练参数的名称和值,named_parameters()函数是获取模型中所有的参数名称和值。

no_decay是定义无需权重衰减的参数类型,权重衰减对偏置项bias和归一化层的weight无益,bias可能破坏模型对称性,LayerNorm的weight需保持灵活性,正则化会抑制其适应性。

optimizer_grouped_parametes: 组1:分组设置优化策略,筛选出参数名称中不包含bias和LayerNorm.weight的参数然后将权重衰减率设为0.1。组2:禁止权重衰减的参数,筛选出参数名称中包含bias和LayerNorm.weight的参数将权重衰减率设为0.0

param_optimizer=list(model.named_parameters())no_decay=['bias','LayerNorm.weight']
optimizer_grouped_parametes=[{'params':[p for n,p in param_optimizer if not any(nd in n for nd in no_decay)],'weight_decay_rate':0.1},{"params":[p for n,p in param_optimizer if any(nd in n for nd in no_decay)],'weight_decay_rate':0.0}
]

5.训练循环的超参数

训练循环中的超参数非常重要,尽管它们看起来可能无害。例如,Adam 优化器 会激活权重衰减并经历一个预热阶段。学习率(lr)和预热率(warnup)应该在优化阶段的早期设置为一个非常小的值,在一 定迭代次数后逐渐增加。这样可以避免出现过大的梯度和超调问题,以更好地优化模 型目标。

代码解释:

使用AdamW优化器,将模型的参数传入,并设置初始学习率为2e-5

定义一个函数calculate_accuracy来度量准确率,用于测试结果与标注进行比较,向函数中传入预测结果的概率分布和真实标签,pred_flat是查找这个概率分布中的最大概率的索引,flatten是将数组一维化,labels_flat是真实结果的一维化。最后,计算预测结果展平后的数组中与展平后的标签数组相等的元素数量占标签数组长度的比例,并将这个比例作为结果返回。

optimizer=AdamW(optimizer_grouped_parametes,lr=2e-5)
def calculate_accuracy(preds, labels):"""计算准确率的优化版本"""preds = np.argmax(preds, axis=1).flatten()labels = labels.flatten()return np.sum(preds == labels) / len(labels)

五、训练循环

我们的训练循环将遵循标准的学习过程。轮数(epochs)设置为 4,并将绘制损失和 准确率的度量值。训练循环使用 dataloader 来加载和训练批量。我们将对训练过程进 行度量和评估。 首先初始化 train_loss_set(用于存储损失和准确率的数值,以便后续绘图)。然后 开始训练每一轮,并运行标准的训练循环,

代码解释:

这段代码实现了BERT模型的完整训练和验证流程,包含以下核心步骤:

  1. 初始化训练记录容器
  2. 循环训练多个epoch
  3. 每个epoch包含训练阶段和验证阶段
  4. 记录并输出训练指标

train_loss_history:  储存每个epoch的平均训练损失

val_accuracy_history:存储每个epoch的验证集准确率

代码太多了,大家在代码中看注释吧,这里主要说一下训练步骤

1.初始化记录容器

2.设置外层epoch(循环次数)循环

3.设置model为训练模式

4.将数据挨个前向传播和反向传播更新参数

5.计算平均训练损失

6.将model设置为评估阶段并进行评估

7.计算平均验证准确率

8.打印训练信息

train_loss_history = []  # 存储每个epoch的平均训练损失
val_accuracy_history = []  # 存储每个epoch的验证集准确率for epoch_i in trange(epochs, desc="Epoch"):# ========== 训练阶段 ==========model.train()  # 设置模型为训练模式total_train_loss = 0  # 初始化累计损失for batch in train_dataloader:# 数据转移到GPUb_input_ids, b_input_mask, b_labels = tuple(t.to(device) for t in batch)# 梯度清零model.zero_grad()# 前向传播outputs = model(b_input_ids,attention_mask=b_input_mask,labels=b_labels)# 多GPU处理:取平均损失loss = outputs.loss.mean()# 反向传播loss.backward()"""在深度学习训练时,梯度可能会变得非常大,这会导致训练不稳定,甚至引发梯度爆炸的问题。torch.nn.utils.clip_grad_norm_ 函数通过对梯度的范数进行裁剪,避免梯度变得过大,从而让训练过程更加稳定。"""torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)  # 梯度裁剪# 参数更新optimizer.step()scheduler.step()total_train_loss += loss.item()# 记录平均训练损失avg_train_loss = total_train_loss / len(train_dataloader)train_loss_history.append(avg_train_loss)  # 记录历史损失# ========== 验证阶段 ==========model.eval()total_eval_accuracy = 0model.eval()  # 设置模型为评估模式total_eval_accuracy = 0  # 初始化累计准确率with torch.no_grad():  # 禁用梯度计算for batch in val_dataloader:b_input_ids, b_input_mask, b_labels = tuple(t.to(device) for t in         batch)# 前向传播outputs = model(b_input_ids, attention_mask=b_input_mask)# .logits是将model中还没有经过激活函数的值提取出来,因为验证不需要激活# 这样节省了显存,.detach将张量从计算图中分离,​断开梯度追踪。因为验证阶段不需要计算梯度,这一步可以节省内存并避免不必要的计算。# .cpu():如果张量在GPU上(例如通过.to('cuda')加载),这一步会将其移动到CPU内存中。NumPy无法直接处理GPU上的张量,必须转移到CPU。logits = outputs.logits.detach().cpu().numpy()label_ids = b_labels.to('cpu').numpy()total_eval_accuracy += calculate_accuracy(logits, label_ids)avg_val_accuracy = total_eval_accuracy / len(val_dataloader)val_accuracy_history.append(avg_val_accuracy)# 打印训练信息print(f"\nEpoch {epoch_i + 1}/{epochs}")print(f"Train loss: {avg_train_loss:.4f}")print(f"Validation Accuracy: {avg_val_accuracy:.4f}")

训练图解:

graph TDA[开始训练] --> B[设置训练模式]B --> C[遍历训练数据]C --> D[数据转GPU]D --> E[梯度清零]E --> F[前向传播]F --> G[计算损失]G --> H[反向传播]H --> I[梯度裁剪]I --> J[参数更新]J --> K[学习率更新]K --> CC --> L[计算平均损失]L --> M[验证模式]M --> N[遍历验证数据]N --> O[前向传播]O --> P[计算准确率]P --> Q[计算平均准确率]Q --> R[记录结果]R --> S[打印信息]S --> T[完成epoch?]T --是--> U[结束训练]T --否--> B

 六、使用测试数据集进行预测和评估

们使用了in_domain_traintsv 数据集训练 BERT下游模型。现在我们将使用基 于留出法!分出的测试数据集 outof_domain_dev.v 文件进行预测。我们的目标是预 测句子在语法上是否正确。 以下代码展示了测试数据准备过程:

# 加载测试数据
test_df = pd.read_csv("out_of_domain_dev.tsv", delimiter='\t', header=None,names=['sentence_source', 'label', 'label_notes', 'sentence'])# 预处理测试数据
test_input_ids, test_attention_masks, test_labels = preprocess_data(test_df, tokenizer, max_len=128)# 创建预测DataLoader
prediction_dataset = TensorDataset(test_input_ids, test_attention_masks, test_labels)
prediction_dataloader = DataLoader(prediction_dataset, sampler=SequentialSampler(prediction_dataset),batch_size=batch_size)# 初始化存储
predictions = []
true_labels = []model.eval()
for batch in prediction_dataloader:batch = tuple(t.to(device) for t in batch)b_input_ids, b_input_mask, b_labels = batchwith torch.no_grad():outputs = model(b_input_ids, attention_mask=b_input_mask)logits = outputs.logits.detach().cpu().numpy()label_ids = b_labels.cpu().numpy()predictions.append(logits)true_labels.append(label_ids)# 计算准确率
flat_predictions = np.concatenate(predictions, axis=0)
flat_predictions = np.argmax(flat_predictions, axis=1)
flat_true_labels = np.concatenate(true_labels, axis=0)accuracy = np.sum(flat_predictions == flat_true_labels) / len(flat_true_labels)
print(f"Test Accuracy: {accuracy:.4f}")

七、使用马修斯相关系数(MCC)评估

​1、MCC的核心原理与优势

马修斯相关系数(Matthews Correlation Coefficient, MCC)是一种综合评估二分类模型性能的指标,尤其适用于类别不平衡数据集。其优势包括:

  1. 全面性:同时考虑真阳性(TP)、真阴性(TN)、假阳性(FP)、假阴性(FN)。、
  2. 鲁棒性:在类别分布不均衡时仍能准确反映模型性能(例如医学诊断中的罕见病检测)。
  3. 可解释性:取值范围为[-1, 1],1表示完美预测,0表示随机猜测,-1表示完全错误。

计算公式:

2. 代码实现:

1. 测试数据预处理与预测
# 加载测试数据(示例路径需替换为实际路径)
test_df = pd.read_csv("out_of_domain_dev.tsv", delimiter='\t', header=None,names=['sentence_source', 'label', 'label_notes', 'sentence'])# 预处理(复用preprocess_data函数)
test_input_ids, test_attention_masks, test_labels = preprocess_data(test_df, tokenizer, max_len=128)# 创建DataLoader
prediction_dataset = TensorDataset(test_input_ids, test_attention_masks, test_labels)
prediction_dataloader = DataLoader(prediction_dataset, sampler=SequentialSampler(prediction_dataset), batch_size=batch_size)
2.模型预测与结果收集

 

# 初始化存储
predictions = []
true_labels = []model.eval()
for batch in prediction_dataloader:batch = tuple(t.to(device) for t in batch)b_input_ids, b_input_mask, b_labels = batchwith torch.no_grad():outputs = model(b_input_ids, attention_mask=b_input_mask)logits = outputs.logits.detach().cpu().numpy()label_ids = b_labels.cpu().numpy()predictions.append(logits)true_labels.append(label_ids)# 合并结果
flat_predictions = np.concatenate(predictions, axis=0)
flat_predictions = np.argmax(flat_predictions, axis=1)  # 将logits转为类别(0/1)
flat_true_labels = np.concatenate(true_labels, axis=0)
3.计算MCC
from sklearn.metrics import matthews_corrcoefmcc = matthews_corrcoef(flat_true_labels, flat_predictions)
print(f"Test MCC: {mcc:.4f}")

到这里就完美收官咯!!!!! 大家点个赞吧!!!

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

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

相关文章

10组时尚复古美学自然冷色调肖像电影照片调色Lightroom预设 De La Mer – Nautical Lightroom Presets

De La Mer 预设系列包含 10 种真实的调色预设,适用于肖像、时尚和美术。为您的肖像摄影带来电影美学和个性! De La Mer 预设非常适合专业人士和业余爱好者,可在桌面或移动设备上使用,为您的摄影项目提供轻松的工作流程。这套包括…

机器学习的一百个概念(4)下采样

前言 本文隶属于专栏《机器学习的一百个概念》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见[《机器学习的一百个概念》 ima 知识库 知识库广场搜索&…

数据安全系列4:密码技术的应用-接口调用的身份识别

传送门 数据安全系列1:开篇 数据安全系列2:单向散列函数概念 数据安全系列3:密码技术概述 什么是认证? 一谈到认证,多数人的反应可能就是"用户认证" 。就是应用系统如何识别用户的身份,直接…

STL之map和set

1. 关联式容器 vector、list、deque、 forward_list(C11)等,这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面存储的是元素本身。 关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是结…

Vue3 其它API Teleport 传送门

Vue3 其它API Teleport 传送门 在定义一个模态框时,父组件的filter属性会影响子组件的position属性,导致模态框定位错误使用Teleport解决这个问题把模态框代码传送到body标签下

《Python Web网站部署应知应会》No4:基于Flask的调用AI大模型的高性能博客网站的设计思路和实战(上)

基于Flask的调用AI大模型的高性能博客网站的设计思路和实战(上) 摘要 本文详细探讨了一个基于Flask框架的高性能博客系统的设计与实现,该系统集成了本地AI大模型生成内容的功能。我们重点关注如何在高并发、高负载状态下保持系统的高性能和…

力扣刷题-热题100题-第27题(c++、python)

21. 合并两个有序链表 - 力扣(LeetCode)https://leetcode.cn/problems/merge-two-sorted-lists/description/?envTypestudy-plan-v2&envIdtop-100-liked 常规法 创建一个新链表,遍历list1与list2,将新链表指向list1与list2…

AI加Python的文本数据情感分析流程效果展示与代码实现

本文所使用数据来自于梯田景区评价数据。 一、数据预处理 数据清洗 去除重复值、空值及无关字符(如表情符号、特殊符号等)。 提取中文文本,过滤非中文字符。 统一文本格式(如全角转半角、繁体转简体)。 中文分词与去停用词 使用 jieba 分词工具进行分词。 加载自定义词…

Microi吾码界面设计引擎之基础组件用法大全【内置组件篇·上】

🎀🎀🎀 microi-pageengine 界面引擎系列 🎀🎀🎀 一、Microi吾码:一款高效、灵活的低代码开发开源框架【低代码框架】 二、Vue3项目快速集成界面引擎 三、Vue3 界面设计插件 microi-pageengine …

【多线程】单例模式和阻塞队列

目录 一.单例模式 1. 饿汉模式 2. 懒汉模式 二.阻塞队列 1. 阻塞队列的概念 2. BlockingQueue接口 3.生产者-消费者模型 4.模拟生产者-消费者模型 一.单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,其核心思想是确保…

Vuex状态管理

Vuex Vuex是一个专为Vue.js应用程序开发的状态管理模式。它采用集中式管理应用的所有组件状态,并以相应的规则保证状态以一种可预测的方式发生变化。(类似于在前端的数据库,这里的数据存储在内存当中) 一、安装并配置 在项目的…

从代码学习深度学习 - 使用块的网络(VGG)PyTorch版

文章目录 前言一、VGG网络简介1.1 VGG的核心特点1.2 VGG的典型结构1.3 优点与局限性1.4 本文的实现目标二、搭建VGG网络2.1 数据准备2.2 定义VGG块2.3 构建VGG网络2.4 辅助工具2.4.1 计时器和累加器2.4.2 准确率计算2.4.3 可视化工具2.5 训练模型2.6 运行实验总结前言 深度学习…

Baklib激活企业知识管理新动能

Baklib核心技术架构解析 Baklib的底层架构以模块化设计为核心,融合知识中台的核心理念,通过分布式存储引擎与智能语义分析系统构建三层技术体系。数据层采用多源异构数据接入协议,支持文档、音视频、代码片段等非结构化数据的实时解析与分类…

C之(16)scan-build与clang-tidy使用

C之(16)scan-build与clang-tidy使用 Author: Once Day Date: 2025年3月29日 一位热衷于Linux学习和开发的菜鸟,试图谱写一场冒险之旅,也许终点只是一场白日梦… 漫漫长路,有人对你微笑过嘛… 全系列文章可参考专栏: Linux实践记录_Once_da…

在 Vue 项目中快速集成 Vant 组件库

目录 引言一、找到 src 下的App.js 写入代码。二、安装Vant三、解决 polyfill 问题四、查看依赖五、配置webpack六、引入 Vant七、在组件中使用 Vant八、在浏览器中查看样式总结 引言 在开发移动端 Vue 项目时,选择一个高效、轻量且功能丰富的组件库是提升开发效率…

(二)GEE基础学习初探及案例详解【20250330】

Google Earth Engine(GEE)是由谷歌公司开发的众多应用之一。借助谷歌公司超强的服务器运算能力以及与NASA的合作关系,GEE平台将Landsat、MODIS、Sentinel等可以公开获取的遥感图像数据存储在谷歌的磁盘阵列中,使得GEE用户可以方便的提取、调用和分析海量…

妙用《甄嬛传》中的选妃来记忆概率论中的乘法公式

强烈推荐最近在看的不错的B站概率论课程 《概率统计》正课,零废话,超精讲!【孔祥仁】 《概率统计》正课,零废话,超精讲!【孔祥仁】_哔哩哔哩_bilibili 其中概率论中的乘法公式,老师用了《甄嬛传…

蓝桥杯备考---->并查集之 Lake Counting

这道题就统计有多少个连通块就行了 这时候我们又需要把二维转成一维了,也就是把每一个格子都给一个编号 当我们合并连通块的时候,其实是只需要四个方向的 因为我们是从上往下遍历的,我们遍历到某个位置的时候,它已经和上面部分…

Vue3 项目通过 docxtemplater 插件动态渲染 .docx 文档(带图片)预览,并导出

Vue3 项目通过 docxtemplater 插件动态渲染 .docx 文档(带图片)预览,并导出 预览安装插件示例代码项目目录结构截图实际效果截图 动态渲染 .docx 文档(带图片),预览、导出安装插件docx 模板文件内容完整代码…

养老更安心!智绅科技“智慧”养老系统,智在何处?

在老龄化趋势不断加剧的当下,养老问题成为全社会关注的焦点。 人们对于养老服务的需求日益增长,不仅期望能够得到基本的生活照料,更渴望在安全、舒适、便捷的环境中安享晚年。 智绅科技的“智慧”养老系统应运而生,凭借其独特的…