pytorch之模型迁移
参考的书目为《深度学习之pytorch实战计算机视觉》将猫狗大战中写好的VGGNet模型替换为VGG16,ResNet模型,前面首先给出完整的VGGNet模型代码,之后分别给出最另外两个模型的修改位置,并进行标注说明:import torchimport torchvisionfrom torchvision import datasets, transformsimport torch...
·
参考的书目为《深度学习之pytorch实战计算机视觉》
将猫狗大战中写好的VGGNet模型替换为VGG16,ResNet模型,前面首先给出完整的VGGNet模型代码,之后分别给出最另外两个模型的修改位置,并进行标注说明:
import torch
import torchvision
from torchvision import datasets, transforms
import torch.utils.data as da#后面调用时出不来自动提示,故重命名了下
from torch.autograd import Variable
import os
import matplotlib.pyplot as plt
import time
data_dir = "G:\pytorch\DogsVSCats"
data_transform = {
x:transforms.Compose([
transforms.Scale([64, 64]),#放缩至64*64
transforms.ToTensor()#类型转换
])
for x in ["train", "test"]
}
image_datasets = {
x:datasets.ImageFolder(root=os.path.join(data_dir, x),
transform= data_transform[x])
#os.path.join将两个名字拼接成一个完整的文件路径
for x in ["train","test"]
}
dataloader = {
x:da.DataLoader(dataset=image_datasets[x],
batch_size= 16,
shuffle= True)
for x in ["train", "test"]
}
X_example, Y_example = next(iter(dataloader["train"]))
#为减少计算量,在模型中删除了最后三个卷积层和池化层
class Models_VGG(torch.nn.Module):
def __init__(self):
super(Models_VGG, self).__init__()
self.Conv = torch.nn.Sequential(
torch.nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(kernel_size=2, stride=2),
torch.nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(kernel_size=2, stride=2),
torch.nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(kernel_size=2, stride=2),
torch.nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(kernel_size=2, stride=2)
)
#全连接层优化
self.Classes = torch.nn.Sequential(
torch.nn.Linear(4*4*512, 1024),
torch.nn.ReLU(),
torch.nn.Dropout(p = 0.5),
torch.nn.Linear(1024, 1024),
torch.nn.ReLU(),
torch.nn.Dropout(p = 0.5),
torch.nn.Linear(1024, 2)
)
def forward(self, input):
x = self.Conv(input)
x = x.view(-1, 4*4*512)#扁平化处理
x = self.Classes(x)
return x
model = Models_VGG()
use_gpu = torch.cuda.is_available()#判断GPU是否可用
#对模型进行优化
loss_fuction = torch.nn.CrossEntropyLoss()#采用交叉嫡
optimizer = torch.optim.Adam(model.parameters(), lr=0.00001)
if use_gpu:
model = model1.cuda()
epoch_n = 10
time_start = time.time()
for epoch in range(epoch_n):#训练次数
print("Epoch {}/{}".format(epoch, epoch_n-1))
print("-"*20)
for phase in ["train", "test"]:#选择数据集
if phase is "train":
print("Traing...")
model.train(True)
else:
print("Validing...")
model.train(False)
running_loss = 0.0
running_corrects = 0
#下面对数据集中的数据进行训练或验证
for batch, data in enumerate(dataloader[phase], 1):
X, y = data
#如果是GPU
if use_gpu:
X, y = Variable(X.cuda()), Variable(y.cuda())
else:
X, y = Variable(X), Variable(y)
y_pred = model(X)
_,pred = torch.max(y_pred.data, 1)
optimizer.zero_grad()
loss = loss_fuction(y_pred, y)
if phase is "train":
loss.backward()
optimizer.step()
running_loss += loss.data
running_corrects += torch.sum(pred == y.data)
if batch%500 is 0 and phase is "train":
print("Batch {}, Tarin Loss{:.4f}, Train Accur{:.4f}".format(batch, running_loss/batch, 100*running_corrects/(16*batch)))
epoch_loss = running_loss*16/len(image_datasets[phase])
epoch_acc = 100*running_corrects/len(image_datasets[phase])
print("{} Loss:{:.4f} Acc {:.4f}%".format(phase, epoch_loss, epoch_acc))
time_use = time.time() - time_start
print(time_use)
在CPU上运行耗时比较旧,我的电脑是X220 i5-2520m,跑一个epoch用了四十五分钟…
——————————————————————————————
下面是模型迁移代码:
1)迁移到VGG16
#将VGGNet上的模型迁移到VGG16中,下载的模型已经优化好了
model = models.vgg16(pretrained= True)
#冻结卷积神经网络中全连接层之前的网络层次,即梯度不修改
for parma in model.parameters():
parma.requires_grad = False
#调参只需要在全连接层进行
model.classifier = torch.nn.Sequential(
torch.nn.Linear(25088, 4096),
torch.nn.ReLU(),
torch.nn.Dropout(p=0.5),
torch.nn.Linear(4096, 4096),
torch.nn.ReLU(),
torch.nn.Dropout(p=0.5),
torch.nn.Linear(4096, 2)
)
在VGG16中输出的结果是1000个,但猫狗大战这里只需输出2个,所以做了修该。
2)迁移到ResNet中:
#将VGGNet上的模型迁移到ResNet50中,下载的模型已经优化好了
model = models.resnet50(pretrained= True)
#冻结卷积神经网络中全连接层之前的网络层次
for parma in model.parameters():
parma.requires_grad = False
#对全连接层进行调整,只有一行
model.fc = torch.nn.Linear(2048, 2)
输出结果只有两个,所以全连接层是个2
更多推荐




所有评论(0)