Datawhale AI 夏令营 催化反应产率预测 Task2

Datawhale AI 夏令营 催化反应产率预测 Task2

转移到云端

之前在本地配置了pytorch+sklearn环境,但是发现在本地运行 Baseline 中
的 RNN 网络速度还是很慢,平均一个 epoch 要耗时 10 分钟左右,对于后续的调参和模型集成上都是极为不利的。

因此,借助于本次 DataWhale 推荐的 魔搭 平台,主要由以下几个优点:

  • 不用担心环境配置问题,之前在本地上需要手动一个一个安装包,还有可能遇到
    环境依赖问题,在云服务器上有配置好的 pytorch 环境
  • GPU 速度快,可以节约大量的时间,新用户可以享受 100 小时的免费 GPU 使用时长
  • 不用听本地电脑运行巨大的噪声,省心省力

魔搭平台的具体使用方法在 DataWhale 中已经详细介绍过了,在此按下不表;

从 Task1 过渡到 Task2, 需要下载 Task2_RNN.ipynb 文件和 vocab_full.txt,分别放置在 Task1 中的 mp/codemp 文件夹下,同时可以在mp 文件夹下新建output 文件夹和 model 文件夹,否则在 Task2_RNN.ipynb 运行中就会因为找不到文件而报错。

然后就可以丝滑的运行 Baseline 哩!

Baseline

Baseline 的代码在 Task2_RNN.ipynb 中,代码中已经详细注释了,可以按照注释中的步骤进行运行。

发现 Baseline 中的代码虽然包含了机器学习过程中较为完整的 模型定义模型训练submit.txt文件生成,但是在模型选择和参数调优
做的不太够。我在 Baseline 上做了一些修改:

  • 将训练数据(即含有特征+标签的数据)划分为训练集和验证集,在训练
    过程中,可以查看模型在验证集上的表现,从而提前发现模型过拟合的情况,从而减少模型训练时间
  • 增加 R 2 R^2 R2 评估指标,可以在训练过程中查看模型在训练集和验证集上的 r2_score

划分训练集和验证集

train函数中作以下修改:

train_size = int(0.8 * len(dataset))
valid_size = len(dataset) - train_size

train_dataset, valid_dataset = torch.utils.data.random_split(dataset, lengths=[train_size, valid_size])
  
train_loader = DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True, collate_fn=collate_fn)
valid_loader = DataLoader(valid_dataset, batch_size=BATCH_SIZE, shuffle=True, collate_fn=collate_fn) 

也就是先计算训练集和验证集的大小,然后使用torch.utils.data.random_split函数将数据集划分成训练集和验证集,最后使用DataLoader函数将训练集和验证集分别封装成DataLoader对象。

进一步可以使用 k k k 折交叉验证的方法,将训练集划分成 k k k 个子集,每次使用 k − 1 k-1 k1 个子集作为训练集,剩余一个子集作为验证集,重复 k k k 次,取平均值作为最终的评估结果。
但是带来的肯定是时间的大幅增加,因此就摆烂了。

然后利用训练好的模型直接在验证集上评估:

with torch.no_grad():
for i, (src, y) in tqdm(enumerate(valid_loader), total=len(valid_loader) // BATCH_SIZE):
    src, y = src.to(device), y.to(device)
    
    output = model(src)
    valid_score += r2_score( y.detach().cpu().numpy(), output.detach().cpu().numpy())
    valid_score_in_a_epoch = valid_score / len(valid_loader)

打印每个 epoch 上的值:

print(f'Epoch: {epoch+1:02} | Train Loss: {loss_in_a_epoch:.3f} | Train Score: {train_score_in_a_epoch} | Valid Score: {valid_score_in_a_epoch}')

顺便调整一下 Baseline 中的代码,尽可能保存好的模型:

if loss_in_a_epoch < best_loss:
    # 在训练循环结束后保存模型
    torch.save(model.state_dict(), f'../model/RNN_H_epoch{epoch}.pth')
    best_loss = loss_in_a_epoch

r2_score 中指标计算

在最开始的单元格中导入 sklearn:

from sklearn.metrics import r2_score

使用 sklearn 中的 r2_score 函数计算:

train_score += r2_score(y.detach().cpu().numpy(), output.detach().cpu().numpy())
train_score_in_a_epoch = train_score / len(train_loader)  
valid_score += r2_score( y.detach().cpu().numpy(), output.detach().cpu().numpy())
valid_score_in_a_epoch = valid_score / len(valid_loader)

关于结果

可能是 RNN 模型本身的问题,多次调整超参数,最好的结果也只有 0.10 左右,最后也不出意外的产生了过拟合;但是使用 LSTM 模型,可以达到
0.25左右的效果,貌似还行。

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值