猫狗大战——VGG
首先修改参数,获得以下几个模型
模型一、
model_vgg_new.classifier._modules['3'] = nn.Linear(4096, 128)
model_vgg_new.classifier._modules['6'] = nn.Linear(128, 2)
model_vgg_new.classifier._modules['7'] = torch.nn.LogSoftmax(dim = 1)
| acc | |
|---|---|
| training | 0.4467 |
| testing | 0.4165 |


模型二、
model_vgg_new.classifier._modules['3'] = nn.Linear(4096, 1024)
model_vgg_new.classifier._modules['6'] = nn.Linear(1024, 2)
model_vgg_new.classifier._modules['7'] = torch.nn.LogSoftmax(dim = 1)
| acc | |
|---|---|
| training | 0.4833 |
| testing | 0.5850 |


模型三、
model_vgg_new.classifier._modules['3'] = nn.Linear(4096, 4096)
model_vgg_new.classifier._modules['6'] = nn.Linear(4096, 2)
model_vgg_new.classifier._modules['7'] = torch.nn.LogSoftmax(dim = 1)
| acc | |
|---|---|
| training | 0.6528 |
| testing | 0.9225 |


模型四、
model_vgg_new.classifier._modules['0'] = nn.Linear(25088, 8192)
model_vgg_new.classifier._modules['3'] = nn.Linear(8192, 8192)
model_vgg_new.classifier._modules['6'] = nn.Linear(8192, 2)
model_vgg_new.classifier._modules['7'] = torch.nn.LogSoftmax(dim = 1)
| acc | |
|---|---|
| training | 0.5567 |
| testing | 0.6465 |


模型五、
model_vgg_new.classifier._modules['6'] = nn.Linear(4096, 4096)
model_vgg_new.classifier._modules['7'] = nn.ReLU(inplace=True)
model_vgg_new.classifier._modules['8'] = nn.Dropout(p=0.5, inplace=False)
model_vgg_new.classifier._modules['9'] = nn.Linear(4096, 2)
model_vgg_new.classifier._modules['10'] = torch.nn.LogSoftmax(dim = 1)
| acc | |
|---|---|
| training | 0.5172 |
| testing | 0.5175 |


选取表现最好的模型三,开始训练及测试竞赛数据。
首先将竞赛数据上传至谷歌云盘,然后在Colab中装载谷歌云盘。

加载数据及处理
import numpy as np
import matplotlib.pyplot as plt
import os
import torch
import torch.nn as nn
import torchvision
from torchvision import models,transforms,datasets
import time
import json# 判断是否存在GPU设备
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print('Using gpu: %s ' % torch.cuda.is_available())
# 解压文件
! unzip ./drive/MyDrive/cat_dog.zip
# 数据处理
normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])vgg_format = transforms.Compose([transforms.CenterCrop(224),transforms.ToTensor(),normalize,])data_dir = './cat_dog'dsets = {x: datasets.ImageFolder(os.path.join(data_dir, x), vgg_format)for x in ['train', 'val', 'test']}dset_sizes = {x: len(dsets[x]) for x in ['train', 'val', 'test']}
dset_classes = dsets['train'].classesloader_train = torch.utils.data.DataLoader(dsets['train'], batch_size=64, shuffle=True, num_workers=6)
loader_valid = torch.utils.data.DataLoader(dsets['val'], batch_size=5, shuffle=False, num_workers=6)
loader_test = torch.utils.data.DataLoader(dsets['test'], batch_size=5, shuffle=False, num_workers=6)
加载模型及修改模型参数
!wget https://s3.amazonaws.com/deep-learning-models/image-models/imagenet_class_index.jsonmodel_vgg = models.vgg16(pretrained=True)
print(model_vgg)model_vgg_new = model_vgg;for param in model_vgg_new.parameters():param.requires_grad = False
model_vgg_new.classifier._modules['6'] = nn.Linear(4096, 2)
model_vgg_new.classifier._modules['7'] = torch.nn.LogSoftmax(dim = 1)model_vgg_new = model_vgg_new.to(device)print(model_vgg_new.classifier)
训练模型
'''
第一步:创建损失函数和优化器损失函数 NLLLoss() 的 输入 是一个对数概率向量和一个目标标签.
它不会为我们计算对数概率,适合最后一层是log_softmax()的网络.
'''
criterion = nn.NLLLoss()# 学习率
lr = 0.001# 随机梯度下降
optimizer_vgg = torch.optim.SGD(model_vgg_new.classifier[6].parameters(),lr = lr)'''
第二步:训练模型
'''def train_model(model,dataloader,size,epochs=1,optimizer=None):model.train()max_acc = 0for epoch in range(epochs):running_loss = 0.0running_corrects = 0count = 0for inputs,classes in dataloader:inputs = inputs.to(device)classes = classes.to(device)outputs = model(inputs)loss = criterion(outputs,classes) optimizer = optimizeroptimizer.zero_grad()loss.backward()optimizer.step()_,preds = torch.max(outputs.data,1)# statisticsrunning_loss += loss.data.item()running_corrects += torch.sum(preds == classes.data)count += len(inputs)#print('Training: No. ', count, ' process ... total: ', size)epoch_loss = running_loss / sizeepoch_acc = running_corrects.data.item() / sizeprint('Loss: {:.4f} Acc: {:.4f}'.format(epoch_loss, epoch_acc))if epoch_acc > max_acc:max_acc = epoch_accpath = './drive/MyDrive/models' + str(epoch+1) + '' + str(epoch_acc) + '' + '.pth'torch.save(model, path)# 第三步:测试模型
def test_model(model,dataloader,size):model.eval()predictions = np.zeros(size)all_classes = np.zeros(size)all_proba = np.zeros((size,2))i = 0running_loss = 0.0running_corrects = 0for inputs,classes in dataloader:inputs = inputs.to(device)classes = classes.to(device)outputs = model(inputs)loss = criterion(outputs,classes) _,preds = torch.max(outputs.data,1)# statisticsrunning_loss += loss.data.item()running_corrects += torch.sum(preds == classes.data)predictions[i:i+len(classes)] = preds.to('cpu').numpy()all_classes[i:i+len(classes)] = classes.to('cpu').numpy()all_proba[i:i+len(classes),:] = outputs.data.to('cpu').numpy()i += len(classes)print('Testing: No. ', i, ' process ... total: ', size) epoch_loss = running_loss / sizeepoch_acc = running_corrects.data.item() / sizeprint('Loss: {:.4f} Acc: {:.4f}'.format(epoch_loss, epoch_acc))return predictions, all_proba, all_classes# 模型训练
train_model(model_vgg_new,loader_train,size=dset_sizes['train'], epochs=10, optimizer=optimizer_vgg)
# 模型测试
predictions, all_proba, all_classes = test_model(model_vgg_new,loader_valid,size=dset_sizes['val'])
如下为保存下的模型

测试函数
import numpy as np
import matplotlib.pyplot as plt
import os
import torch
import torch.nn as nn
import torchvision
from torchvision import models,transforms,datasets
import time
import json# 判断是否存在GPU设备
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print('Using gpu: %s ' % torch.cuda.is_available())! unzip ./drive/MyDrive/cat_dog.zipnormalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])vgg_format = transforms.Compose([transforms.CenterCrop(224),transforms.ToTensor(),normalize,])data_dir = './cat_dog/test'dsets = {'test': datasets.ImageFolder(data_dir, vgg_format)}
dset_sizes = {x: len(dsets[x]) for x in ['test']}
loader_test = torch.utils.data.DataLoader(dsets['test'], batch_size=1, shuffle=False, num_workers=0)model_vgg_new = torch.load('./drive/MyDrive/models80.97755.pth')
model_vgg_new = model_vgg_new.to(device)
def test(model,dataloader,size):model.eval()predictions = np.zeros(size)i = 0all_preds = {}for inputs,classes in dataloader:inputs = inputs.to(device)outputs = model(inputs) _,preds = torch.max(outputs.data,1)# statisticskey = dsets['test'].imgs[i][0]print(key)all_preds[key] = preds[0]i += 1print('Testing: No. ', i, ' process ... total: ', size)with open("./drive/MyDrive/models/result.csv", 'a+') as f:for i in range(2000):f.write("{},{}\n".format(i, all_preds["./cat_dog/test/TT/"+str(i)+".jpg"]))test(model_vgg_new,loader_test,size=dset_sizes['test'])
将结果提交至研习社,得到分数

在几个模型调试中,通过修改连接层的参数和深度,可以发现,原始的VGG模型已经是很好的状态了,若要优化原有的模型,需要花费更多的精力去调试。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
