《深度学习之PyTorch实战计算机视觉》第9章代码 多模型融合

《深度学习之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)))



  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值