软工第三周作业-猫狗大战

一.原有代码

1.1导入相关的包

 

1.2数据标准化

 

1.3加载训练集和测试集

 

 

 

1.4创建VGG模型

 

 

 

 

 

1.5训练模型(训练集)


'''
第一步:创建损失函数和优化器
​
损失函数 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()
    
    for epoch in range(epochs):
        running_loss = 0.0
        running_corrects = 0
        count = 0
        for inputs,classes in dataloader:
            inputs = inputs.to(device)
            classes = classes.to(device)
            outputs = model(inputs)
            loss = criterion(outputs,classes)           
            optimizer = optimizer
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            _,preds = torch.max(outputs.data,1)
​
            # statistics
​
•            running_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 / size
•        epoch_acc = running_corrects.data.item() / size
•        print('Loss: {:.4f} Acc: {:.4f}'.format(
•                     epoch_loss, epoch_acc))
•        
•        
​
# 模型训练
​
train_model(model_vgg_new,loader_train,size=dset_sizes['train'], epochs=1, 
            optimizer=optimizer_vgg)

 

1.6测试模型(测试集)

 

 

 

二.AI研习社测试

2.1导入相关的包

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

2.2加载数据集

 

2.3划分数据集

这里分别在train和val文件夹下面新建cats和dogs子文件夹,然后分别把猫狗的照片放在里面,然后在test文件夹下面新建img文件夹,方便后面的datasets.ImageFolder()的正常使用。

%%shell
​
for filename in `ls ./drive/MyDrive/cat_dog/train`
​
do
​
  if [ ${filename: 0:3} == "cat" ] 
​
  then
​
   mkdir -p ./drive/MyDrive/cat_dog/train/cats
​
   mv -i ./drive/MyDrive/cat_dog/train/$filename ./drive/MyDrive/cat_dog/train/cats/$filename
​
  fi
​
done
​
​
​
for filename in `ls ./drive/MyDrive/cat_dog/train`
​
do
​
  if [ ${filename: 0:3} == "dog" ] 
​
  then
​
   mkdir -p ./drive/MyDrive/cat_dog/train/dogs
​
   mv -i ./drive/MyDrive/cat_dog/train/$filename ./drive/MyDrive/cat_dog/train/dogs/$filename
​
  fi
​
done
​
​
​
for filename in `ls ./drive/MyDrive/cat_dog/val`
​
do
​
  if [ ${filename: 0:3} == "cat" ] 
​
  then
​
   mkdir -p ./drive/MyDrive/cat_dog/val/cats
​
   mv -i ./drive/MyDrive/cat_dog/val/$filename ./drive/MyDrive/cat_dog/val/cats/$filename
​
  fi
​
done
​
​
​
for filename in `ls ./drive/MyDrive/cat_dog/val`
​
do
​
  if [ ${filename: 0:3} == "dog" ] 
​
  then
​
   mkdir -p ./drive/MyDrive/cat_dog/val/dogs
​
   mv -i ./drive/MyDrive/cat_dog/val/$filename ./drive/MyDrive/cat_dog/val/dogs/$filename
​
  fi
​
done
​
​
​
for filename in `ls ./drive/MyDrive/cat_dog/test`
​
do
​
  mkdir -p ./drive/MyDrive/cat_dog/test/img
​
  mv -i ./drive/MyDrive/cat_dog/test/$filename ./drive/MyDrive/cat_dog/test/img/$filename
​
done
 

结果:

 

2.4数据标准化及图像处理

#数据标准化
normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) 
​
#图像预处理成224*224*3大小
vgg_format = transforms.Compose([
                transforms.CenterCrop(224),
                transforms.ToTensor(),
                normalize,
            ])
​
data_dir = './drive/MyDrive/cat_dog'
dsets = {x: datasets.ImageFolder(os.path.join(data_dir, x), vgg_format)
         for x in ['train', 'val']}
​
dset_sizes = {x: len(dsets[x]) for x in ['train', 'val']}
dset_classes = dsets['train'].classes
​
​
# 通过下面代码可以查看 dsets 的一些属性
print(dsets['val'].classes)
print(dsets['val'].class_to_idx)
print(dsets['val'].imgs[:5])
print('dset_sizes: ', dset_sizes)

 

2.6加载训练集和测试集,创建模型

#加载训练集和测试集
loader_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)
​
#创建模型
model_vgg = models.vgg16(pretrained=True)
model_vgg = model_vgg.to(device)
​
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)

 

2.7开始训练并保存模型

'''
第一步:创建损失函数和优化器
​
损失函数 NLLLoss() 的 输入 是一个对数概率向量和一个目标标签. 
它不会为我们计算对数概率,适合最后一层是log_softmax()的网络. 
'''
criterion = nn.NLLLoss()
​
# 学习率
lr = 0.0001
​
# 随机梯度下降
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()
    
    for epoch in range(epochs):
        running_loss = 0.0
        running_corrects = 0
        count = 0
        for inputs,classes in dataloader:
            inputs = inputs.to(device)
            classes = classes.to(device)
            outputs = model(inputs)
            loss = criterion(outputs,classes)           
            optimizer = optimizer
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            _,preds = torch.max(outputs.data,1)
            # statistics
            running_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 / size
        epoch_acc = running_corrects.data.item() / size
        print('epoch: ', epoch)
        print('Loss: {:.8f} Acc: {:.8f}'.format(
                     epoch_loss, epoch_acc))
        # 测试准确率大于0.966时保存模型
        if epoch_acc > 0.96600000:
          torch.save(model, './drive/MyDrive/model/model_' + str(epoch_acc)[2:] + '_' + str(epoch) + '.pth')        
        
# 模型训练
train_model(model_vgg_new,loader_train,size=dset_sizes['train'], epochs=10, 
            optimizer=optimizer_vgg)

最后结果:

 

可以看到10轮训练完之后,预测的准确率达到了96.8%,这个结果比较可信。

最后保存下来有三个模型准确率比较高。

2.8处理未分类的数据集test,并将结果提交到AI研习社

data_dir = './drive/MyDrive/cat_dog/test'
​
dsets = {'test': datasets.ImageFolder(data_dir, vgg_format)}
​
dset_sizes = len(dsets['test'])
​
​
​
loader_test = torch.utils.data.DataLoader(dsets['test'], batch_size=1, num_workers=6)
​
​
#从上述保存下来的模型中选择准确率最高的模型对未分类的数据进行测试
model_vgg_new = torch.load('./drive/MyDrive/model/model_9804_60.pth');
​
model_vgg_new = model_vgg_new.to(device)
​
​
​
import csv
​
def test_model(model,dataloader,size):
​
  model.eval()
​
  predictions = np.zeros(size)
​
  i = 0
​
  for inputs,classes in dataloader:
​
           inputs = inputs.to(device)
​
           classes = classes.to(device)
​
•   outputs = model(inputs)     
​
•    _,preds = torch.max(outputs.data,1)
​
•    \# statistics
​
•    predictions[int(dsets['test'].imgs[i][0][33:-4])] = preds.to('cpu').numpy()
​
•    i += 1
​
•    print('Testing: No. ', i, ' process ... total: ', size)  
​
  csvFile = open("./drive/MyDrive/cat_dog_result/result.csv", "w")
​
  writer = csv.writer(csvFile)
​
  for i in range(dset_sizes):
​
   writer.writerow([i, predictions[i]])#把预测的数据写进CSV文件里面 ,0代表猫,1代表狗
​
  print("Save successfully!!!")
​
  return predictions
​
 
​
predictions = test_model(model_vgg_new,loader_test,size=dset_sizes)

保存下来的csv文件:

 

 

研习社结果:

 

三.实验分析

1.最后结果的准确率为96.85%左右,准确率并不是很高,我们小组刚开始的时候进行了100轮的训练,训练到后面的时候,准确率达到了98%左右,但是发现colab这个平台训练久了容易掉线,所以我们把训练轮数调到了10轮左右,最后成功显示了结果。

2.另外,训练中学习率不能过小,过小的话损失值曲线收敛的很慢,在有限的epochs中不能训练出很好地结果。学习率如果过大开始时loss下降得快,但后面会产生无法拟合的现象。因此学习率应该选取合适的值不应该过大或过小。 3.进一步改进需要采用更好的模型,如使用其他深度学习网络,增加网络深度,或者是选择别的优化器可能会产生更好的效果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值