日志2024.1.4/5(train_text.py)

def train(save_path='model_states'):
    if not os.path.exists(save_path):
        os.mkdir(save_path)
    model = BIC(hidden_dim=hidden_dim, num_layers=num_layers, des_dim=768, sta_dim=768,
                twe_dim=768, num_dim=6, cat_dim=3,
                num_heads=4, fixed_size=fixed_size,
                graph_mode='rgcn', semantic_mode='cat',
                dropout=dropout).to(device)
    optimizer = torch.optim.RAdam(model.parameters(), lr=lr, weight_decay=weight_decay)
    loss_fn = torch.nn.CrossEntropyLoss()
    best_model = model.state_dict()
    best_acc = 0
    no_up = 0
    epoch = 0
    while True:
        train_one_epoch(model, optimizer, loss_fn)
        acc, f1, pre, rec = evaluate(model, val_loader)
        if acc > best_acc:
            no_up = 0
            best_acc = acc
            best_model = model.state_dict()
        else:
            no_up += 1
        if no_up == no_up_limit:
            break
        print('epoch {}, no up: {}, best acc: {}'.format(epoch, no_up, best_acc))
        epoch += 1
    model.load_state_dict(best_model)
    acc, f1, pre, rec = evaluate(model, test_loader)
    print('training done.')
    print('acc {:.2f} f1 {:.2f} pre {:.2f} rec {:.2f}'.format(acc, f1, pre, rec))
    torch.save(best_model, '{}/{:.2f}_{:.2f}_{:.2f}_{:.2f}.model'.format(save_path, acc, f1, pre, rec))
  1. 检查是否存在目录 save_path,如果不存在,则创建该目录。这个目录将用于保存训练过程中性能最好的模型。
  2. 创建了一个 BIC 模型的实例,并将其移动到设备(GPU 或 CPU)上。这个模型的架构由一系列超参数定义,包括隐藏层维度、交互层的数量、输入维度等。
  3. 创建了一个优化器 optimizer(这里使用了 RAdam 优化器)和一个损失函数 loss_fn(这里使用了交叉熵损失)。这些都是训练过程中必要的组件。
  4. 初始化了一些变量,包括 best_model 用于保存性能最好的模型的状态字典,best_acc 用于保存性能最好的准确度,no_up 用于计算没有提高准确度的轮数,epoch 用于迭代的轮数。
  5. while循环是整个训练过程的主要循环。在每个 epoch 中,调用 train_one_epoch 函数进行一轮训练,然后使用验证数据集评估模型性能。如果当前准确度比之前的最佳准确度要好,就更新 best_acc 和 best_model;否则,增加 no_up 计数器。如果 no_up 达到预定的上限 no_up_limit,则跳出循环。(best_model = model.state_dict()的目的是保存当前模型的状态字典,以便在训练过程中找到性能最佳的模型状态。)
  6. 在训练结束后,将模型的状态加载为性能最好的模型状态,以便后续的测试和保存。
  7. 在训练结束后,使用测试数据集评估最终模型的性能。
  8. 打印训练完成的消息,包括最终的准确度、F1 分数、精确度和召回率。
  9. 将性能最佳的模型保存到文件中,文件名包含了准确度、F1 分数、精确度和召回率的信息。
def train_one_epoch(model, optimizer, loss_fn):
    model.train()
    for batch in tqdm(train_loader, ncols=0):
        optimizer.zero_grad()
        batch_label = batch.y.to(device)[:batch.batch_size]
        out = forward_one_batch(batch, model)
        loss = loss_fn(out, batch_label)
        loss.backward()
        optimizer.step()
  1. model.train() 是 PyTorch 中用于将模型设置为训练模式的方法。
  2. 循环遍历了训练数据加载器中的每个批次。
  3. 在每个批次开始时,我们需要将优化器的梯度归零,以防止梯度在多个批次之间累积。
  4. 从批次中提取标签,并使用 forward_one_batch 函数获取模型的输出。forward_one_batch 函数的作用是将输入批次传递给模型,获取模型的预测输出。
  5. 使用损失函数计算模型预测输出与真实标签之间的损失。
  6. 执行反向传播以计算梯度,然后使用优化器来更新模型的参数。
def forward_one_batch(batch, model):
    size = batch.batch_size
    batch_edge_index = batch.edge_index.to(device)
    batch_edge_type = batch.edge_type.to(device)
    batch_tweet = tweet[batch.x].to(device)
    batch_description = description[batch.x].to(device)
    batch_numerical = numerical[batch.x].to(device)
    batch_categorical = categorical[batch.x].to(device)
    batch_status = status[batch.x[:size]]
    text, padding_mask = get_batch_text(batch_status)
    text, padding_mask = text.to(device), padding_mask.to(device)
    return model(text, padding_mask,
                 batch_edge_index, batch_edge_type,
                 batch_tweet, batch_description,
                 batch_numerical, batch_categorical, size)
  1. 获取当前批次的大小,即批次中样本的数量。
  2. 将批次中的各种数据(如边的索引、边的类型、tweet 数据、description 数据、数值特征、分类特征)移动到指定的设备(GPU 或 CPU)上。
  3. 根据批次中的状态数据获取文本数据和相应的填充掩码。get_batch_text 函数的作用是对状态数据进行处理,使其符合模型的输入要求,并返回文本数据和填充掩码。
  4. 将处理过的各种数据传递给模型进行前向传播。
@torch.no_grad()
def evaluate(model, loader):
    model.eval()
    all_truth = []
    all_preds = []
    for batch in loader:
        all_truth.append(batch.y[:batch.batch_size])
        out = forward_one_batch(batch, model)
        all_preds.append(out.argmax(dim=-1).to('cpu'))
    all_truth = torch.cat(all_truth, dim=0).numpy()
    all_preds = torch.cat(all_preds, dim=0).numpy()
    return [accuracy_score(all_truth, all_preds) * 100,
            f1_score(all_truth, all_preds) * 100,
            precision_score(all_truth, all_preds) * 100,
            recall_score(all_truth, all_preds) * 100]
  1. 使用 model.eval() 将模型设置为评估模式。
  2. 两个列表将用于存储整个数据集的真实标签和模型的预测标签。
  3. 从批次中提取真实标签,并使用 forward_one_batch 函数获取模型的输出。这里使用 .argmax(dim=-1) 获取模型预测的类别。
  4. 将存储真实标签和预测标签的列表转换为 NumPy 数组,以便后续使用 sklearn 库计算评估指标。
  5. 使用 sklearn 库计算准确度、F1 分数、精确度和召回率等评估指标,并将结果以列表形式返回。
  • 16
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值