网站建设怎么申请空间,网站建设合同 免责声明,产品详情页模板免费下载,如何做英文版网站针对于某个任务#xff0c;自己的训练数据不多#xff0c;先找到一个同类的别人训练好的模型#xff0c;把别人现成的训练好了的模型拿过来#xff0c;换成自己的数据#xff0c;调整一下参数#xff0c;再训练一遍#xff0c;这就是微调#xff08;fine-tune#xff… 针对于某个任务自己的训练数据不多先找到一个同类的别人训练好的模型把别人现成的训练好了的模型拿过来换成自己的数据调整一下参数再训练一遍这就是微调fine-tune。 PyTorch里面提供的经典的网络模型都是官方通过Imagenet的数据集与训练好的数据如果我们的数据训练数据不够这些数据是可以作为基础模型来使用的。(Fine tuning 模型微调) Fine tuning 模型微调的好处 对于数据集本身很小几千张图片的情况从头开始训练具有几千万参数的大型神经网络是不现实的因为越大的模型对数据量的要求越大过拟合无法避免。这时候如果还想用上大型神经网络的超强特征提取能力只能靠微调已经训练好的模型。 可以降低训练成本如果使用导出特征向量的方法进行迁移学习后期的训练成本非常低用 CPU 都完全无压力没有深度学习机器也可以做。 前人花很大精力训练出来的模型在大概率上会比你自己从零开始搭的模型要强悍没有必要重复造轮子。 迁移学习初衷是节省人工标注样本的时间让模型可以通过一个已有的标记数据的领域向未标记数据领域进行迁移从而训练出适用于该领域的模型直接对目标域从头开始学习成本太高我们故而转向运用已有的相关知识来辅助尽快地学习新知识。把统一的概念抽象出来只学习不同的内容。迁移学习按照学习方式可以分为基于样本的迁移基于特征的迁移基于模型的迁移以及基于关系的迁移。 微调应该是迁移学习中的一部分。微调只能说是一个trick一种技术迁移学习是一个更宏大的概念。 Pytorch模型保存、加载与预训练 保存和加载整个模型和参数这种方式会保存整个模型的结构以及参数会占用较大的磁盘空间 通常不采用这种方式 torch.save(model, model.pkl) #保存
model torch.load(model.pkl) # 加载保存和加载模型的参数 优点是速度快占用的磁盘空间少 是最常用的模型保存方法。load_state_dict有一个strict参数该参数默认是True 表示预训练模型的网络结构与自定义的网络结构严格相同包括名字和维度。 如果自定义网络和预训练网络不严格相同时 需要将不属于自定义网络的key去掉 torch.save(model.state_dict(), model_state_dict.pkl)
model model.load_state_dict(torch.load(model_state_dict.pkl))在实际场景中 我们往往需要保存更多的信息如优化器的参数 那么可以通过字典的方式进行存储 # 保存
torch.save({epoch: epochId,state_dict: model.state_dict,best_acc: best_acc,optimizer: optimizer.state_dict()}, checkpoint_path /m- timestamp str(%.4f % best_acc) .pth.tar)
# 加载
def load_model(model, checkpoint, optimizer):model_CKPT torch.load(checkpoint)model.load_state_dict(model_CKPT[state_dict])optimizer.load_state_dict(model_CKPT[optimizer])return model, optimizer加载部分预训练模型 如果我们修改了网络 那么就需要将这部分参数过滤掉(值得注意的是当两个网络的结构相同 但是结构的命名不同时 直接加载会报错。因此需要修改结构的key值) def load_model(model, chinkpoint, optimizer):model_CKPT torch.load(checkpoint)model_dict model.state_dict()pretrained_dict model_CKPT[state_dict]# 将不在model中的参数过滤掉new_dict {k, v for k, v in pretrained_dict.items() if k in model_dict.keys()}model_dict.update(new_dict)model.load_state_dict(model_dict)# 加载优化器参数optimizer.load_state_dict(model_CKPT[optimizer])return model, optimizer冻结网络的部分参数 训练另一部分参数(注意必须同时在优化器中将这些参数过滤掉 否则会报错。因为optimizer里面的参数要求required_grad为Ture) 当输入给模型的数据集形式相似或者相同时常见的是利用现有的经典模型如Residual Network、 GoogleNet等作为backbone来提取特征那么这些经典模型已经训练好的模型参数可以直接拿过来使用。通常情况下 我们希望将这些经典网络模型的参数固定下来 不进行训练只训练后面我们添加的和具体任务相关的网络参数。 新数据集和原始数据集合类似那么直接可以微调一个最后的FC层或者重新指定一个新的分类器 新数据集比较小和原始数据集合差异性比较大那么可以使用从模型的中部开始训练只对最后几层进行fine-tuning 新数据集比较小和原始数据集合差异性比较大如果上面方法还是不行的化那么最好是重新训练只将预训练的模型作为一个新模型初始化的数据 新数据集的大小一定要与原始数据集相同比如CNN中输入的图片大小一定要相同才不会报错 对于不同的层可以设置不同的学习率一般情况下建议对于使用的原始数据做初始化的层设置的学习率要小于一般可设置小于10倍初始化的学习率这样保证对于已经初始化的数据不会扭曲的过快而使用初始化学习率的新层可以快速的收敛。 # 以ResNet网络为例
# 当我们加载ResNet预训练模型之后在ResNet的基础上连接了新的网络模块 ResNet那部分网络参数先冻结不更新
# 只更新新引入网络结构的参数
class Net(torch.nn.Module):def __init__(self, model, pretrained):super(Net, self).__init__()self.resnet model(pretained)for p in self.parameters():p.requires_grad Falseself.conv1 torch.nn.Conv2d(2048, 1024, 1)self.conv2 torch.nn.Conv2d(1024, 1024, 1)参数修改 resnet网络的最后一层对应1000个类别 如果我们自己的数据只有10个类别 那么可以进行如下修改 import torch
import torchvision.models as models
model models.resnet50(pretrainedTrue)
fc_inDim model.fc.in_features
# 修改为10个类别
model.fc torch.nn.Linear(fc_inDim, 10)Pytorch有很多方便易用的包今天要谈的是torchvision包它包括3个子包分别是 torchvison.datasets torchvision.models torchvision.transforms 分别是预定义好的数据集比如MNIST、CIFAR10等、预定义好的经典网络结构比如AlexNet、VGG、ResNet等和预定义好的数据增强方法比如Resize、ToTensor等。这些方法可以直接调用简化我们建模的过程也可以作为我们学习或构建新的模型的参考。