《深度学习之PyTorch实战计算机视觉》第9章代码
代码
多模型融合
import torch
import torchvision
from torchvision import transforms, models, datasets
import os
import matplotlib.pyplot as plt
from torch.autograd import Variable
import time
data_dir = "DogsVSCats"
data_transform = {
x:transforms.Compose(
[
transforms.Scale([224,224]), #Scale类将原始图片的大小统一缩放至64×64
transforms.ToTensor(),
transforms.Normalize(
mean=[0.5,0.5,0.5],
std=[0.5,0.5,0.5]
)
]
)
for x in ["train","valid"]
}
image_datasets = {
x:datasets.ImageFolder(
root=os.path.join(data_dir,x), #将输入参数中的两个名字拼接成一个完整的文件路径
transform=data_transform[x]
)
for x in ["train","valid"]
}
dataloader = {
#注意:标签0/1自动根据子目录顺序以及目录名生成
#如:{'cat': 0, 'dog': 1} #{'狗dog': 0, '猫cat': 1}
#如:['cat', 'dog'] #['狗dog', '猫cat']
x:torch.utils.data.DataLoader(
dataset=image_datasets[x],
batch_size=16,
shuffle=True
)
for x in ["train","valid"]
}
X_example, y_example = next(iter(dataloader["train"]))
#print('X_example个数{}'.format(len(X_example))) #X_example个数16 torch.Size([16, 3, 64, 64])
#print('Y_example个数{}'.format(len(Y_example))) #Y_example个数16 torch.Size([16]
#print(index_classes) #{'cat': 0, 'dog': 1} #{'狗dog': 0, '猫cat': 1}
example_classes = image_datasets["train"].classes # 将原始图像的类别保存起来
#print(example_classes) #['cat', 'dog'] #['狗dog', '猫cat']
index_classes = image_datasets["train"].class_to_idx # 显示类别对应的独热编码
model_1 = models.vgg16(pretrained=True)
model_2 = models.resnet50(pretrained=True)
Use_gpu = torch.cuda.is_available()
#Use_gpu = False
for param in model_1.parameters():
param.requires_grad = False
model_1.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)
)
for param in model_2.parameters():
param.requires_grad = False
model_2.fc = torch.nn.Linear(2048,2)
if Use_gpu:
model_1 = model_1.cuda()
model_2 = model_2.cuda()
loss_f_1 = torch.nn.CrossEntropyLoss()
loss_f_2 = torch.nn.CrossEntropyLoss()
optimizer_1 = torch.optim.Adam(model_1.classifier.parameters(),lr=0.00001)
optimizer_2 = torch.optim.Adam(model_2.fc.parameters(),lr=0.00001)
weight_1 = 0.6
weight_2 = 0.4
epoch_n = 5
time_open = time.time()
for epoch in range(epoch_n):
print("Epoch {}/{}".format(epoch+1,epoch_n))
print("*"*20)
for phase in ["train","valid"]:
if phase =="train":
print("Training...")
model_1.train(True)
model_2.train(True)
else:
print("Validing...")
model_1.train(False)
model_2.train(False)
running_loss_1 = 0.0
running_corrects_1 = 0
running_loss_2 = 0.0
running_corrects_2 = 0
blending_running_corrects = 0
for batch, data in enumerate(dataloader[phase],1):
# print("$$$$$$$$$",batch)
# if batch == 10:
# break
X, y = data
if Use_gpu:
X, y = Variable(X.cuda()), Variable(y.cuda())
else:
X, y = Variable(X), Variable(y)
y_pred_1 = model_1(X)
y_pred_2 = model_2(X)
blending_y_pred = y_pred_1*weight_1+y_pred_2*weight_2
_, pred_1 = torch.max(y_pred_1.data,1)
_, pred_2 = torch.max(y_pred_2.data,1)
_, blending_pred = torch.max(blending_y_pred.data,1)
optimizer_1.zero_grad()
optimizer_2.zero_grad()
loss_1 = loss_f_1(y_pred_1, y)
loss_2 = loss_f_2(y_pred_2, y)
if phase == "train":
loss_1.backward()
loss_2.backward()
optimizer_1.step()
optimizer_2.step()
running_loss_1 += loss_1.item()
running_corrects_1 += torch.sum(pred_1 == y.data)
running_loss_2 += loss_2.item()
running_corrects_2 += torch.sum(pred_2 == y.data)
blending_running_corrects += torch.sum(blending_pred == y.data)
if batch%500 == 0 and phase == "train":
print(("Batch {},Model1 Train Loss:{:.4f},Model1 Train ACC:{:.4f}%,Model2 " + \
"Train Loss:{:.4f},Model2 Train ACC:{:.4f}%, " + \
"Blending_Model ACC:{:.4f}%").format(
batch,
running_loss_1/batch,
100.0*running_corrects_1/(16*batch),
running_loss_2/batch,
100.0*running_corrects_2/(16*batch),
100.0*blending_running_corrects/(16*batch)
)
)
epoch_loss_1 = running_loss_1*16/len(image_datasets[phase])
epoch_acc_1 = 100.0*running_corrects_1/len(image_datasets[phase])
epoch_loss_2 = running_loss_2*16/len(image_datasets[phase])
epoch_acc_2 = 100.0*running_corrects_2/len(image_datasets[phase])
epoch_blending_acc = 100.0*blending_running_corrects/len(image_datasets[phase])
print(("Epoch, Model1 Loss:{:.4f}, Model1 ACC:{:.4f}%, Model2 Loss:{:.4f}, Model2 ACC:{:.4f}%,"+\
"Blending_Model ACC:{:.4f}%").format(
epoch_loss_1,
epoch_acc_1,
epoch_loss_2,
epoch_acc_2,
epoch_blending_acc
)
)
time_end = time.time() - time_open
print("程序运行时间:{}分钟...".format(int(time_end/60)))