albert多文本分类,这段代码怎么理解?


os.environ["CUDA_VISIBLE_DEVICES"]='0'


if __name__ == '__main__':
    threshold = 0.5


    state_dict_path = 'output/_ckpt_epoch_30.ckpt'
    device = 'cuda' if torch.cuda.is_available() else 'cpu'

    model = AlbertForSequenceClassification.from_pretrained('albert_large_chinese', num_labels=150)
    state_dict = torch.load(state_dict_path, map_location=torch.device('cpu'))['state_dict']
    new = dict()
    for key, value in state_dict.items():
        key = '.'.join(key.split('.')[1:])
        new[key] = value
    model.load_state_dict(new, strict=False)
    model.eval()
    model = model.to(device)


    tok = BertTokenizer.from_pretrained("albert_large_chinese")
    mlb = joblib.load('mlb.bin').classes_
    mlb_ = joblib.load('mlb.bin')
    index_to_class = dict()
    for i, item in enumerate(mlb):
        index_to_class[i] = item


    np_x_test = np.load('traindata/X_test.npy', allow_pickle=True)
    X_test_input_ids = torch.tensor(np.array([item['input_ids'] for item in np_x_test])).long()
    X_test_attention_mask = torch.tensor(np.array([item['attention_mask'] for item in np_x_test])).long()
    y_test = np.load('traindata/y_test.npy', allow_pickle=True).tolist()
    all_targets = []
    all_results = []

    '''
    统计多标签分类precision、覆盖率cover    
    '''
    precision_numerator=0
    precision_denominator=0

    for index in trange(len(np_x_test)):
        with torch.no_grad():

            ids = X_test_input_ids[index].unsqueeze(0)
            ids = ids.to(device)
            mask = X_test_attention_mask[index].unsqueeze(0)
            mask = mask.to(device)
            result_logits = model(input_ids=ids,attention_mask=mask)[0][0].cpu()

            targets = y_test.todense()[index].tolist()[0]
            result_logits = torch.sigmoid(result_logits).tolist()
            results = [1 if item > threshold else 0 for item in result_logits]

            if len(results) != len(targets):
                print("error predict result info")

            '''
            一条数据的预测标签的数量,以及预测对的个数--》累计
            '''
            tmp_con = [i for i, j in zip(results, targets) if i == j and i == 1]
            precision_numerator=precision_numerator+len(tmp_con)
            precision_denominator=precision_denominator+results.count(1)
            all_targets.append(targets)
            all_results.append(results)

    all_targets = np.array(all_targets, dtype=np.int32)
    all_results = np.array(all_results, dtype=np.int32)
    print('f1', f1_score(all_targets, all_results, average='micro'))
    print('p', precision_score(all_targets, all_results, average='micro'))
    print('r', recall_score(all_targets, all_results, average='micro'))
    print("accuracy score==>",accuracy_score(all_targets, all_results))

    covers = sum([1 if sum(result) > 0 else 0 for result in all_results])
    covers_all = len(all_results)

    print('coverage',covers,covers_all,covers/covers_all)
    print(
        "precision",
        precision_numerator,
        precision_denominator,
        precision_numerator / precision_denominator,
    )

上面的代码怎么理解,需要把一条文本,加载到多分类模型中,然后输出这句话的文本及标签怎么写?

引用chatgpt部分指引作答:
这段代码是一个基于预训练的Albert模型进行多标签文本分类的例子,包含以下主要步骤:

1 加载预训练的Albert模型,设定设备(CPU或GPU)和模型参数。
2 加载tokenizer,用于将文本转化为模型可处理的输入。
3 加载训练好的多标签分类器模型,以及标签(即类别)的索引与名称的映射关系。
4 加载待预测的文本数据和对应的标签数据,逐条进行预测。
5 对每条文本进行预测,得到模型输出的概率向量,再进行阈值判定,得到最终的预测结果。
6 统计预测结果的精度、召回率、覆盖率等评价指标,并输出结果。
如果需要将一条文本加载到多标签分类模型中并输出文本及标签,可以按以下方式编写代码(假设文本为"test text"):

import torch
from transformers import AlbertTokenizer, AlbertForSequenceClassification

# 加载模型
model = AlbertForSequenceClassification.from_pretrained('albert_large_chinese', num_labels=150)
device = 'cuda' if torch.cuda.is_available() else 'cpu'
model.to(device)

# 加载tokenizer
tokenizer = AlbertTokenizer.from_pretrained('albert_large_chinese')

# 加载标签映射关系
index_to_class = {0: "label1", 1: "label2", 2: "label3", ...}

# 加载模型参数
state_dict = torch.load('path/to/model.pth', map_location=torch.device('cpu'))['state_dict']
new = dict()
for key, value in state_dict.items():
    key = '.'.join(key.split('.')[1:])
    new[key] = value
model.load_state_dict(new, strict=False)

# 对待预测的文本进行编码
text = "test text"
input_ids = torch.tensor(tokenizer.encode(text)).unsqueeze(0)
input_ids = input_ids.to(device)
attention_mask = torch.ones(input_ids.shape, dtype=torch.long, device=device)

# 进行预测
with torch.no_grad():
    result_logits = model(input_ids=input_ids, attention_mask=attention_mask)[0][0].cpu()
    result_probs = torch.sigmoid(result_logits).tolist()[0]

# 根据阈值判定预测结果,并输出文本及标签
threshold = 0.5
predicted_labels = [index_to_class[i] for i in range(len(result_probs)) if result_probs[i] > threshold]
print("Input text: ", text)
print("Predicted labels: ", predicted_labels)

需要注意的是,标签映射关系需要根据实际情况进行修改,以对应训练时所使用的标签。另外,在加载模型参数时,可能需要根据实际情况进行一些调整,例如更改路径或设备。

这段代码用于执行多文本分类任务,使用了预训练的 Albert 模型,并将其应用于多标签分类任务。代码首先设置了环境变量 "CUDA_VISIBLE_DEVICES",以便在训练时只使用一个可用的 GPU。接着,代码加载预训练好的 Albert 模型,模型的权重加载自 'output/_ckpt_epoch_30.ckpt' 文件,模型结构使用 'albert_large_chinese' 预训练模型。然后,代码计算了模型在测试集上的多标签分类性能指标,包括 F1 分数、准确率、召回率和覆盖率。

要将一条文本加载到多分类模型中并输出文本及其标签,可以按照以下步骤进行:

  1. 使用预训练的分词器对输入文本进行分词,得到输入 ID 和注意力掩码。例如:

    input_text = "这是一个示例文本"
    encoded_input = tok.encode_plus(input_text, add_special_tokens=True, return_tensors='pt', padding='max_length', truncation=True, max_length=512)
    input_ids = encoded_input['input_ids']
    attention_mask = encoded_input['attention_mask']
    
  2. 将输入 ID 和注意力掩码加载到模型中,获得输出结果。例如:

    with torch.no_grad():
        input_ids = input_ids.to(device)
        attention_mask = attention_mask.to(device)
        logits = model(input_ids=input_ids, attention_mask=attention_mask)[0][0].cpu()
    
  3. 使用 Sigmoid 函数处理输出的 logits,然后根据阈值将其转换为二进制标签。例如:

    threshold = 0.5
    logits = torch.sigmoid(logits).tolist()
    predicted_labels = [1 if item > threshold else 0 for item in logits]
    
  4. 将预测的二进制标签转换为对应的类别。例如:

    predicted_classes = [index_to_class[i] for i, value in enumerate(predicted_labels) if value == 1]
    

最后,输出输入文本及其预测的类别:

print("输入文本:", input_text)
print("预测类别:", predicted_classes)

不懂的可以继续提问,如对你有所帮助 望采纳

  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/7436970
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:贝叶斯做文本分类,代码实现数据处理
  • 同时,你还可以查看手册:主成分回归与部分最小二乘法回归的比较 中的内容
  • 除此之外, 这篇博客: 集成学习中的软投票和硬投票机制详解和代码实现中的 总结 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 通过将将神经网络、支持向量机和lightGMB 加入到组合中,软投票的准确率从 88.68% 提高了 0.46% 至 89.14%,新的软投票准确率比最佳个体算法(XG Boost 为 88.38 提高了 0.76% )。添加准确度分数低于 XGBoost 的 Light GMB 将集成性能提高了 0.1%!也就是说集成不是最佳的模型也能够提升软投票的性能。如果是 Kaggle 比赛,那么 0.76% 可能是巨大的,可能会让你在排行榜上飞跃。

    作者:Graham Harrison

    cv=kfold))

    
    会得到一个错误:
    
    ```python
    ValueError: could not broadcast input array from shape (2000,1) into shape (2000)
    

    这个问题很好解决,是因为输出是(2000,1)而输入的要求是(2000),所以我们可以使用np.squeeze将第二个维度删除即可。

  • 您还可以看一下 刘城龙老师的教你快速查找电脑中的文件课程中的 快速按文件内容查找文件的方法小节, 巩固相关知识点




os.environ["CUDA_VISIBLE_DEVICES"]='0' # 设置使用的GPU编号为0,即只使用第一个GPU
 
if __name__ == '__main__': # 如果当前脚本为主程序
    threshold = 0.5 # 设置阈值为0.5,用于二分类
 
    state_dict_path = 'output/_ckpt_epoch_30.ckpt' # 模型参数路径,即训练好的模型的参数文件
    device = 'cuda' if torch.cuda.is_available() else 'cpu' # 如果有GPU可用,则使用GPU,否则使用CPU
 
    # 加载预训练模型,这里使用的是ALBERT模型,num_labels表示分类的类别数
    model = AlbertForSequenceClassification.from_pretrained('albert_large_chinese', num_labels=150)
    # 加载模型参数,map_location=torch.device('cpu')表示将模型参数加载到CPU上
    state_dict = torch.load(state_dict_path, map_location=torch.device('cpu'))['state_dict']
    new = dict()
    for key, value in state_dict.items():
        key = '.'.join(key.split('.')[1:]) # 将key中的"module."去掉
        new[key] = value
    model.load_state_dict(new, strict=False) # 加载模型参数
    model.eval() # 设置模型为评估模式
    model = model.to(device) # 将模型移动到指定设备上
 
    # 加载BertTokenizer和MultiLabelBinarizer
    tok = BertTokenizer.from_pretrained("albert_large_chinese") # 加载BertTokenizer
    mlb = joblib.load('mlb.bin').classes_ # 加载MultiLabelBinarizer
    mlb_ = joblib.load('mlb.bin')
    index_to_class = dict()
    for i, item in enumerate(mlb):
        index_to_class[i] = item
 
    # 加载测试数据
    np_x_test = np.load('traindata/X_test.npy', allow_pickle=True) # 加载测试数据的输入
    X_test_input_ids = torch.tensor(np.array([item['input_ids'] for item in np_x_test])).long() # 将测试数据的输入转换为tensor
    X_test_attention_mask = torch.tensor(np.array([item['attention_mask'] for item in np_x_test])).long() # 将测试数据的attention mask转换为tensor
    y_test = np.load('traindata/y_test.npy', allow_pickle=True).tolist() # 加载测试数据的标签
    all_targets = [] # 存储所有的真实标签
    all_results = [] # 存储所有的预测结果
 
    '''
    统计多标签分类precision、覆盖率cover    
    '''
    precision_numerator=0 # 统计预测正确的标签数量
    precision_denominator=0 # 统计预测的标签数量
 
    # 遍历所有的测试数据
    for index in trange(len(np_x_test)):
        with torch.no_grad(): # 不需要计算梯度
 
            ids = X_test_input_ids[index].unsqueeze(0) # 获取当前测试数据的输入
            ids = ids.to(device) # 将输入移动到指定设备上
            mask = X_test_attention_mask[index].unsqueeze(0) # 获取当前测试数据的attention mask
            mask = mask.to(device) # 将attention mask移动到指定设备上
            result_logits = model(input_ids=ids,attention_mask=mask)[0][0].cpu() # 使用模型进行预测,并将结果移动到CPU上
 
            targets = y_test.todense()[index].tolist()[0] # 获取当前测试数据的真实标签
            result_logits = torch.sigmoid(result_logits).tolist() # 将预测结果进行sigmoid处理,并转换为list
            results = [1 if item > threshold else 0 for item in result_logits] # 根据阈值将预测结果转换为0或1
 
            if len(results) != len(targets):
                print("error predict result info")
 
            '''
            一条数据的预测标签的数量,以及预测对的个数--》累计
            '''
            tmp_con = [i for i, j in zip(results, targets) if i == j and i == 1] # 统计预测正确的标签数量
            precision_numerator=precision_numerator+len(tmp_con) # 累加预测正确的标签数量
            precision_denominator=precision_denominator+results.count(1) # 累加预测的标签数量
            all_targets.append(targets) # 将当前测试数据的真实标签添加到all_targets中
            all_results.append(results) # 将当前测试数据的预测结果添加到all_results中
 
    all_targets = np.array(all_targets, dtype=np.int32) # 将all_targets转换为numpy数组
    all_results = np.array(all_results, dtype=np.int32) # 将all_results转换为numpy数组
    print('f1', f1_score(all_targets, all_results, average='micro')) # 输出f1 score
    print('p', precision_score(all_targets, all_results, average='micro')) # 输出precision
    print('r', recall_score(all_targets, all_results, average='micro')) # 输出recall
    print("accuracy score==>",accuracy_score(all_targets, all_results)) # 输出accuracy score
 
    covers = sum([1 if sum(result) > 0 else 0 for result in all_results]) # 统计覆盖率
    covers_all = len(all_results) # 统计总数
 
    print('coverage',covers,covers_all,covers/covers_all) # 输出覆盖率
    print(
        "precision",
        precision_numerator,
        precision_denominator,
        precision_numerator / precision_denominator,
    ) # 输出precision