Pytorch卷积神经网络迁移
浅念念52 人气:0前言
在深度学习训练的过程中,随着网络层数的提升,我们训练的次数,参数都会提高,训练时间相应就会增加,我们今天来了解迁移学习
一、经典的卷积神经网络
在pytorch官网中,我们可以看到许多经典的卷积神经网络。
附官网链接:http://pytorch.org/
这里简单介绍一下经典的卷积神经发展历程
1.首先可以说是卷积神经网络的开山之作Alexnet(12年的夺冠之作)这里简单说一下缺点 卷积核大,步长大,没有填充层,大刀阔斧的提取特征,容易忽略一些重要的特征
2.第二个就是VGG网络,它的卷积核大小是3*3,有一个优点是经过池化层之后,通道数翻倍,可以更多的保留一些特征,这是VGG的一个特点
在接下来的一段时间中,出现了一个问题,我们都知道,深度学习随着训练次数的不断增加,效果应该是越来越好,但是这里出现了一个问题,研究发现随着VGG网络的不断提高,效果却没有原来的好,这时候人们就认为,深度学习是不是只能发展到这里了,这时遇到了一个瓶颈。
3.接下来随着残差网络(Resnet)的提出,解决了上面这个问题,这个网络的优点是保留了原有的特征,假如经过卷积之后提取的特征还没有原图的好,这时候保留原有的特征,就会解决这一问题,下面就是resnet网络模型
这是一些训练对比:
二、迁移学习的目标
首先我们使用迁移学习的目标就是用人家训练好的权重参数,偏置参数,来训练我们的模型。
三、好处
深度学习要训练的数据量是很大的,当我们数据量少时,我们训练的权重参数就不会那么的好,所以这时候我们就可以使用别人训练好的权重参数,偏置参数来使用,会使我们的模型准确率得到提高
四、步骤
迁移学习大致可以分为三步
1.加载模型
2.冻结层数
3.全连接层
五、代码
这里使用的是resnet152
import torch import torchvision as tv import torch.nn as nn import torchvision import torch.nn.functional as F import torchvision.transforms as transforms import torch from torch.utils import data from torch import optim from torch.autograd import Variable model_name='resnet' featuer_extract=True train_on_gpu=torch.cuda.is_available() if not train_on_gpu: print("没有gpu") else : print("是gpu") devic=torch.device("cuda:0" if torch.cuda.is_available() else 'cpu') teature_extract=True def set_paremeter_requires_grad(model,featuer_extract): if featuer_extract: for parm in model.parameters(): parm.requires_grad=False #不做训练 def initialize_model(model_name,num_classes,featuer_extract,use_pretrained=True): model_ft = None input_size = 0 if model_name=="resnet": model_ft=tv.models.resnet152(pretrained=use_pretrained)#下载模型 set_paremeter_requires_grad(model_ft,featuer_extract) #冻结层数 num_ftrs=model_ft.fc.in_features #改动全连接层 model_ft.fc=nn.Sequential(nn.Linear(num_ftrs,num_classes), nn.LogSoftmax(dim=1)) input_size=224 #输入维度 return model_ft,input_size model_ft,iput_size=initialize_model(model_name,10,featuer_extract,use_pretrained=True) model_ft=model_ft.to(devic) params_to_updata=model_ft.parameters() if featuer_extract: params_to_updata=[] for name,param in model_ft.named_parameters(): if param.requires_grad==True: params_to_updata.append(param) print("\t",name) else: for name,param in model_ft.parameters(): if param.requires_grad==True: print("\t",name) opt=optim.Adam(params_to_updata,lr=0.01) loss=nn.NLLLoss() if __name__ == '__main__': transform = transforms.Compose([ # 图像增强 transforms.Resize(1024),#裁剪 transforms.RandomHorizontalFlip(),#随机水平翻转 transforms.RandomCrop(224),#随机裁剪 transforms.ColorJitter(brightness=0.5, contrast=0.5, hue=0.5), #亮度 # 转变为tensor 正则化 transforms.ToTensor(), #转换格式 transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)) # 归一化处理 ]) trainset = tv.datasets.CIFAR10( root=r'E:\桌面\资料\cv3\数据集\cifar-10-batches-py', train=True, download=True, transform=transform ) trainloader = data.DataLoader( trainset, batch_size=8, drop_last=True, shuffle=True, # 乱序 num_workers=4, ) testset = tv.datasets.CIFAR10( root=r'E:\桌面\资料\cv3\数据集\cifar-10-batches-py', train=False, download=True, transform=transform ) testloader = data.DataLoader( testset, batch_size=8, drop_last=True, shuffle=False, num_workers=4 ) for epoch in range(3): running_loss=0 for index,data in enumerate(trainloader,0): inputs, labels = data inputs = inputs.to(devic) labels = labels.to(devic) inputs, labels = Variable(inputs), Variable(labels) opt.zero_grad() h=model_ft(inputs) loss1=loss(h,labels) loss1.backward() opt.step() h+=loss1.item() if index%10==9: avg_loss=loss1/10. running_loss=0 print('avg_loss',avg_loss) if index%100==99 : correct=0 total=0 for data in testloader: images,labels=data outputs=model_ft(Variable(images.cuda())) _,predicted=torch.max(outputs.cpu(),1) total+=labels.size(0) bool_tensor=(predicted==labels) correct+=bool_tensor.sum() print('1000张测试集中的准确率为%d %%'%(100*correct/total))
加载全部内容