街景字符识别—模型训练和验证

目录

  • 1. 构建验证集
  • 2. 模型训练和验证
  • 3. 模型保存和加载
  • 4. 模型调参

1. 构建验证集

在深度学习过程中,可能出现过拟合问题。过拟合指模型误差在训练集上随着训练次数和模型复杂度增加而减少,却在训练集上先减后增。如下所示。
街景字符识别—模型训练和验证_第1张图片
构建验证集能够有效解决过拟合问题,验证集需要尽可能与测试集保持一致,在训练过程中不断验证模型在验证集上的精度,以此控制模型训练。

总结一下:

训练集:模型训练和调整模型参数;
验证集:验证模型精度和调整模型超参数;
测试集:测试模型泛化能力。

如图,构建验证集常用三种方法:
街景字符识别—模型训练和验证_第2张图片

  1. 留出法:把原训练集数据分为两部分,一部分为新的训练集,令一部分为验证集,适用于样本数据量大的情况。

  2. 交叉验证法:将原训练集分为K份,K-1份为新训练集,剩下1份为验证集,循环K次。这种方法能够充分利用样本数据,得到的精度比较可靠。但不适合数据量大的情况。

  3. 自助采样法:通过有放回的采样法得到训练集和验证集,适用于数据量较小的情况。

2. 模型训练和验证

构建训练集和验证集

train_loader = torch.utils.data.DataLoader(
    train_dataset,
    batch_size=10, 
    shuffle=False, 
    num_workers=0, 
)
    
val_loader = torch.utils.data.DataLoader(
    val_dataset,
    batch_size=10, 
    shuffle=False, 
    num_workers=0, 
)

训练和验证,根据最优验证集精度保存模型

model = SVHN_Model1()
criterion = nn.CrossEntropyLoss (size_average=False)
optimizer = torch.optim.Adam(model.parameters(), 0.001)
best_loss = 1000.0
for epoch in range(1):
    print('Epoch: ', epoch)

    train(train_loader, model, criterion, optimizer, epoch)
    val_loss = validate(val_loader, model, criterion)
    
    # 记录下验证集精度
    if val_loss < best_loss:
        best_loss = val_loss
        torch.save(model.state_dict(), './model.pt')

其中每个Epoch的训练代码如下:

def train(train_loader, model, criterion, optimizer, epoch):
    # 切换模型为训练模式
    model.train()

    for i, (input, target) in enumerate(train_loader):
        c0, c1, c2, c3, c4, c5 = model(data[0])
        loss = criterion(c0, data[1][:, 0]) + \
                criterion(c1, data[1][:, 1]) + \
                criterion(c2, data[1][:, 2]) + \
                criterion(c3, data[1][:, 3]) + \
                criterion(c4, data[1][:, 4]) + \
                criterion(c5, data[1][:, 5])
        loss /= 6
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

其中每个Epoch的验证代码如下:

def validate(val_loader, model, criterion):
    # 切换模型为预测模型
    model.eval()
    val_loss = []

    # 不记录模型梯度信息
    with torch.no_grad():
        for i, (input, target) in enumerate(val_loader):
            c0, c1, c2, c3, c4, c5 = model(data[0])
            loss = criterion(c0, data[1][:, 0]) + \
                    criterion(c1, data[1][:, 1]) + \
                    criterion(c2, data[1][:, 2]) + \
                    criterion(c3, data[1][:, 3]) + \
                    criterion(c4, data[1][:, 4]) + \
                    criterion(c5, data[1][:, 5])
            loss /= 6
            val_loss.append(loss.item())
    return np.mean(val_loss)

3. 模型保存和加载

torch.save(model_object.state_dict(), 'model.pt')

model.load_state_dict(torch.load(' model.pt'))

4. 模型调参

深度学习模型精度与模型的复杂度、数据量、正则化、数据扩增等因素直接相关。在不同的情况下,需要进行不同的优化方法。本次赛题可以考虑按以下三个方面进行:

  1. 构建简单CNN模型,跑通训练、验证和预测的流程;
  2. 增加模型复杂度,降低验证集精度;
  3. 在增加模型复杂度的前提下加入数据扩增方法,直至验证集精度不变。

具体调参技巧可以阅读:A Recipe for Training Neural Networks.

本文参考:Datawhale 零基础入门CV赛事-Task4 模型训练与验证.

你可能感兴趣的:(街景字符识别—模型训练和验证)