由于我们只需要最后一层提供两个概率,即图像的概率是否为cat,我们可以重新定义最后一层中的输出特征数。
- model.fc = nn.Linear(num_ftrs, 2)
这是我们模型的新架构。
我们现在要做的就是训练模型的最后一层,我们将能够使用我们重新定位的vgg16来预测图像是否是猫,而且数据和训练时间都非常少。
数据的大小很小,数据相似性也很低
考虑来自(https://www.kaggle.com/kvinicki/canine-coccidiosis),这个数据集包含了犬异孢球虫和犬异孢球虫卵囊的图像和标签,异孢球虫卵囊是一种球虫寄生虫,可感染狗的肠道。它是由萨格勒布兽医学院创建的。它包含了两种寄生虫的341张图片。
这个数据集很小,而且不是Imagenet中的一个类别。在这种情况下,我们保留预先训练好的模型架构,冻结较低的层并保留它们的权重,并训练较低的层更新它们的权重以适应我们的问题。
- count = 0
- for child in model.children():
- count+=1
- print(count)
Out: 10
ResNet18共有10层。让我们冻结前6层。
- count = 0
- for child in model.children():
- count+=1
- if count < 7:
- for param in child.parameters():
- param.requires_grad = False
现在我们已经冻结了前6层,让我们重新定义最终输出层,只给出2个输出,而不是1000。
- model.fc = nn.Linear(num_ftrs, 2)
这是更新的架构。
现在,训练这个机器学习模型,更新最后4层的权重。
数据集的大小很大,但数据相似性非常低
考虑这个来自kaggle,皮肤癌MNIST的数据集:HAM10000
其具有超过10015个皮肤镜图像,属于7种不同类别。这不是我们在Imagenet中可以找到的那种数据。
这就是我们只保留模型架构而不保留来自预训练模型的任何权重的地方。让我们重新定义输出层,将项目分类为7个类别。
- model.fc = nn.Linear(num_ftrs, 7)
这个模型需要几个小时才能在没有GPU的机器上进行训练,但是如果你运行足够的时代,你仍然会得到很好的结果,而不必定义你自己的模型架构。
数据大小很大,数据相似性很高
考虑来自kaggle 的鲜花数据集(https://www.kaggle.com/alxmamaev/flowers-recognition)。它包含4242个花卉图像。图片分为五类:洋甘菊,郁金香,玫瑰,向日葵,蒲公英。每个类大约有800张照片。
这是应用迁移学习的理想情况。我们保留了预训练模型的体系结构和每一层的权重,并训练模型更新权重以匹配我们的特定问题。
- model.fc = nn.Linear(num_ftrs, 5)
- best_model_wts = copy.deepcopy(model.state_dict())
我们从预训练的模型中复制权重并初始化我们的模型。我们使用训练和测试阶段来更新这些权重。
- for epoch in range(num_epochs):
-
- print(‘Epoch {}/{}’.format(epoch, num_epochs — 1))
- print(‘-’ * 10)
- for phase in [‘train’, ‘test’]:
-
- if phase == 'train':
- scheduler.step()
- model.train()
- else:
- model.eval()
- running_loss = 0.0
- running_corrects = 0
- for inputs, labels in dataloaders[phase]:
-
- inputs = inputs.to(device)
- labels = labels.to(device)
- optimizer.zero_grad()
- with torch.set_grad_enabled(phase == ‘train’):
-
- outputs = model(inputs)
- _, preds = torch.max(outputs, 1)
- loss = criterion(outputs, labels)
-
- if phase == ‘train’:
- loss.backward()
- optimizer.step()
- running_loss += loss.item() * inputs.size(0)
- running_corrects += torch.sum(preds == labels.data)
-
- epoch_loss = running_loss / dataset_sizes[phase]
- epoch_acc = running_corrects.double() / dataset_sizes[phase]
- print(‘{} Loss: {:.4f} Acc: {:.4f}’.format(
- phase, epoch_loss, epoch_acc))
-
- if phase == ‘test’ and epoch_acc > best_acc:
- best_acc = epoch_acc
- best_model_wts = copy.deepcopy(model.state_dict())
- print(‘Best val Acc: {:4f}’.format(best_acc))
- model.load_state_dict(best_model_wts)
这种机器学习模式也需要几个小时的训练,但即使只有一个训练epoch ,也会产生出色的效果。
(编辑:晋中站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|