ResNet50的猫狗分类训练及预测

这篇具有很好参考价值的文章主要介绍了ResNet50的猫狗分类训练及预测。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

相比于之前写的ResNet18,下面的ResNet50写得更加工程化一点,这还适用与其他分类,就是换一个分类训练只需要修改图片数据的路径即可。

我的代码文件结构

  ResNet50的猫狗分类训练及预测

 

1. 数据处理

  首先已经对数据做好了分类

  ResNet50的猫狗分类训练及预测

 

 

   文件夹结构是这样

  开始划分数据集

  split_data.py

import os
import random
import shutil


def move_file(target_path, save_train_path, save_val_pathm, scale=0.1):

    file_list = os.listdir(target_path)
    random.shuffle(file_list)

    number = int(len(file_list) * scale)
    train_list = file_list[number:]
    val_list = file_list[:number]

    for file in train_list:
        target_file_path = os.path.join(target_path, file)
        save_file_path = os.path.join(save_train_path, file)
        shutil.copyfile(target_file_path, save_file_path)
    for file in val_list:
        target_file_path = os.path.join(target_path, file)
        save_file_path = os.path.join(save_val_pathm, file)
        shutil.copyfile(target_file_path, save_file_path)


def split_classify_data(base_path, save_path, scale=0.1):
    folder_list = os.listdir(base_path)
    for folder in folder_list:
        target_path = os.path.join(base_path, folder)
        save_train_path = os.path.join(save_path, 'train', folder)
        save_val_path = os.path.join(save_path, 'val', folder)
        if not os.path.exists(save_train_path):
            os.makedirs(save_train_path)
        if not os.path.exists(save_val_path):
            os.makedirs(save_val_path)
        move_file(target_path, save_train_path, save_val_path, scale)
        print(folder, 'finish!')


if __name__ == '__main__':
    base_path = r'C:\Users\Administrator.DESKTOP-161KJQD\Desktop\save_dir'
    save_path = r'C:\Users\Administrator.DESKTOP-161KJQD\Desktop\dog_cat'
    # 验证集比例
    scale = 0.1
    split_classify_data(base_path, save_path, scale)

  运行完以上代码的到的文件夹结构

    ResNet50的猫狗分类训练及预测

 

 

   一个训练集数据,一个验证集数据

  

2.数据集的导入

  我这个文件写了一个数据集的导入和一个学习率更新的函数。数据导入是通用的

  tools.py

import os
import time

import cv2
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import torchvision
from torch.autograd.variable import Variable
from torch.utils.tensorboard import SummaryWriter
from torchvision import datasets, transforms
from torch.utils.data import Dataset, DataLoader
from torch.optim.lr_scheduler import ExponentialLR, LambdaLR
from torchvision.models import ResNet50_Weights
from tqdm import tqdm
from classify_cfg import *

mean = MEAN
std = STD


def get_dataset(base_dir='', input_size=160):
    dateset = dict()
    transform_train = transforms.Compose([
        # 分辨率重置为input_size
        transforms.Resize(input_size),
        transforms.RandomRotation(15),
        # 对加载的图像作归一化处理, 并裁剪为[input_sizexinput_sizex3]大小的图像(因为这图片像素不一致直接统一)
        transforms.CenterCrop(input_size),
        transforms.ToTensor(),
        transforms.Normalize(mean=mean, std=std)
    ])

    transform_val = transforms.Compose([
        transforms.Resize(input_size),
        transforms.RandomRotation(15),
        transforms.CenterCrop(input_size),
        transforms.ToTensor(),
        transforms.Normalize(mean=mean, std=std)
    ])
    base_dir_train = os.path.join(base_dir, 'train')
    train_dataset = datasets.ImageFolder(root=base_dir_train, transform=transform_train)
    # print("train_dataset=" + repr(train_dataset[1][0].size()))
    # print("train_dataset.class_to_idx=" + repr(train_dataset.class_to_idx))
    # print(train_dataset.classes)
    classes = train_dataset.classes
    # classes = train_dataset.class_to_idx
    classes_num = len(train_dataset.classes)

    base_dir_val = os.path.join(base_dir, 'val')
    val_dataset = datasets.ImageFolder(root=base_dir_val, transform=transform_val)

    dateset['train'] = train_dataset
    dateset['val'] = val_dataset

    return dateset, classes, classes_num


def update_lr(epoch, epochs):
    """
    假设开始的学习率lr是0.001,训练次数epochs是100
    当epoch<33时是lr * 1
    当33<=epoch<=66 时是lr * 0.5
    当66<epoch时是lr * 0.1
    """
    if epoch == 0 or epochs // 3 > epoch:
        return 1
    elif (epochs // 3 * 2 >= epoch) and (epochs // 3 <= epoch):
        return 0.5
    else:
        return 0.1

 

3.训练模型

  数据集导入好了以后,选择模型,选择优化器等等,然后开始训练。

  mytrain.py

import os
import time

import cv2
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
from torch.autograd.variable import Variable
from torch.utils.tensorboard import SummaryWriter
from torch.utils.data import Dataset, DataLoader
from torch.optim.lr_scheduler import ExponentialLR, LambdaLR
from torchvision.models import ResNet50_Weights
# from tqdm import tqdm
from classify_cfg import *
from tools import get_dataset, update_lr


def train(model, dateset, epochs, batch_size, device, optimizer, scheduler, criterion, save_path):
    train_loader = DataLoader(dateset.get('train'), batch_size=batch_size, shuffle=True)
    val_loader = DataLoader(dateset.get('val'), batch_size=batch_size, shuffle=True)

    # 保存为tensorboard文件
    write = SummaryWriter(save_path)
    # 训练过程写入txt
    f = open(os.path.join(save_path, 'log.txt'), 'w', encoding='utf-8')

    best_acc = 0
    for epoch in range(epochs):
        train_correct = 0.0
        model.train()
        sum_loss = 0.0
        accuracy = -1
        total_num = len(train_loader.dataset)
        # print(total_num, len(train_loader))
        # loop = tqdm(enumerate(train_loader), total=len(train_loader))
        batch_count = 0
        for batch_idx, (data, target) in enumerate(train_loader):
            start_time = time.time()
            data, target = Variable(data).to(device), Variable(target).to(device)
            output = model(data)
            loss = criterion(output, target)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

            print_loss = loss.data.item()
            sum_loss += print_loss
            train_predict = torch.max(output.data, 1)[1]
            if torch.cuda.is_available():
                train_correct += (train_predict.cuda() == target.cuda()).sum()
            else:
                train_correct += (train_predict == target).sum()
            accuracy = (train_correct / total_num) * 100
            # loop.set_description(f'Epoch [{epoch+1}/{epochs}]')
            # loop.set_postfix(loss=loss.item(), acc='{:.3f}'.format(accuracy))
            batch_count += len(data)
            end_time = time.time()
            s = f'Epoch:[{epoch+1}/{epochs}] Batch:[{batch_count}/{total_num}] train_acc: {"{:.2f}".format(accuracy)} ' \
                f'train_loss: {"{:.3f}".format(loss.item())} time: {int((end_time-start_time)*1000)} ms'
            # print(f'Epoch:[{epoch+1}/{epochs}]', f'Batch:[{batch_count}/{total_num}]',
            #       'train_acc:', '{:.2f}'.format(accuracy), 'train_loss:', '{:.3f}'.format(loss.item()),
            #       'time:', f'{int((end_time-start_time)*1000)} ms')
            print(s)
            f.write(s+'\n')

        write.add_scalar('train_acc', accuracy, epoch)
        write.add_scalar('train_loss', loss.item(), epoch)
        # print(optimizer.param_groups[0]['lr'])
        scheduler.step()
        if best_acc < accuracy:
            best_acc = accuracy
            torch.save(model, os.path.join(save_path, 'best.pt'))

        if epoch+1 == epochs:
            torch.save(model, os.path.join(save_path, 'last.pt'))

        # 预测验证集
        # if (epoch+1) % 5 == 0 or epoch+1 == epochs:
        model.eval()
        test_loss = 0.0
        correct = 0.0
        total_num = len(val_loader.dataset)
        # print(total_num, len(val_loader))
        with torch.no_grad():
            for data, target in val_loader:
                data, target = Variable(data).to(device), Variable(target).to(device)
                output = model(data)
                loss = criterion(output, target)
                _, pred = torch.max(output.data, 1)
                if torch.cuda.is_available():
                    correct += torch.sum(pred.cuda() == target.cuda())
                else:
                    correct += torch.sum(pred == target)
                print_loss = loss.data.item()
                test_loss += print_loss
            acc = correct / total_num * 100
            avg_loss = test_loss / len(val_loader)
        s = f"val acc: {'{:.2f}'.format(acc)} val loss: {'{:.3f}'.format(avg_loss)}"
        # print('val acc: ', '{:.2f}'.format(acc), 'val loss: ', '{:.3f}'.format(avg_loss))
        print(s)
        f.write(s+'\n')
        write.add_scalar('val_acc', acc, epoch)
        write.add_scalar('val_loss', avg_loss, epoch)
        # loop.set_postfix(val_loss='{:.3f}'.format(avg_loss), val_acc='{:.3f}'.format(acc))

    f.close()


if __name__ == '__main__':
    device = DEVICE
    epochs = EPOCHS
    batch_size = BATCH_SIZE
    input_size = INPUT_SIZE
    lr = LR
    # ---------------------------训练-------------------------------------
    # 图片的路径
    base_dir = r'C:\Users\Administrator.DESKTOP-161KJQD\Desktop\dog_cat'
    # 保存的路径
    save_path = r'C:\Users\Administrator.DESKTOP-161KJQD\Desktop\dog_cat_save'
    dateset, classes, classes_num = get_dataset(base_dir, input_size=input_size)
    # model = torchvision.models.resnet50(pretrained=True)
    model = torchvision.models.resnet50(weights=ResNet50_Weights.IMAGENET1K_V1)
    num_ftrs = model.fc.in_features
    model.fc = nn.Linear(num_ftrs, classes_num)
    model.to(DEVICE)
    # # 损失函数,交叉熵损失函数
    criteon = nn.CrossEntropyLoss()
    # 选择优化器
    optimizer = optim.SGD(model.parameters(), lr=lr)
    # 学习率更新
    # scheduler = ExponentialLR(optimizer, gamma=0.9)
    scheduler = LambdaLR(optimizer, lr_lambda=lambda epoch: update_lr(epoch, epochs))
    # 开始训练
    train(model, dateset, epochs, batch_size, device, optimizer, scheduler, criteon, save_path)
    # 将label保存起来
    with open(os.path.join(save_path, 'labels.txt'), 'w', encoding='utf-8') as f:
        f.write(f'{classes_num} {classes}')

  训练结束以后,在保存路径下会得到下面的文件

  ResNet50的猫狗分类训练及预测

 

  最好的模型,最后一次的模型,标签的列表,训练的记录和tensorboard记录

  在该路径下执行 tensorboard --logdir=.  

  ResNet50的猫狗分类训练及预测

 

  然后在浏览器打开给出的地址,即可看到数据训练过程的绘图

 4.对图片进行预测

  考虑对于用户来说,用户是在网页或者手机上上传一张图片进行预测,所以这边是采用二进制数据。

  mypredict.py

  

import cv2
import numpy as np
import torch

from classify_cfg import *



def img_process(img_betys, img_size, device):

    img_arry = np.asarray(bytearray(img_betys), dtype='uint8')
    # im0 = cv2.imread(img_betys)
    im0 = cv2.imdecode(img_arry, cv2.IMREAD_COLOR)
    image = cv2.resize(im0, (img_size, img_size))
    image = np.float32(image) / 255.0
    image[:, :, ] -= np.float32(mean)
    image[:, :, ] /= np.float32(std)
    image = image.transpose((2, 0, 1))
    im = torch.from_numpy(image).unsqueeze(0)
    im = im.to(device)
    return im


def predict(model_path, img, device):
    model = torch.load(model_path)
    model.to(device)
    model.eval()
    predicts = model(img)
    # print(predicts)
    _, preds = torch.max(predicts, 1)
    pred = torch.squeeze(preds)
    # print(pred)
    return pred


if __name__ == '__main__':
    mean = MEAN
    std = STD
    device = DEVICE
    classes = ['', '']
    # # 预测
    model_path = r'C:\Users\Administrator.DESKTOP-161KJQD\Desktop\dog_cat_save\best.pt'
    img_path = r'C:\Users\Administrator.DESKTOP-161KJQD\Desktop\save_dir\狗\000000.jpg'
    with open(img_path, 'rb') as f:
        img_betys = f.read()
    img =img_process(img_betys, 160, device)
    # print(img.shape)
    # print(img)
    pred = predict(model_path, img, device)
    print(classes[int(pred)])

 

还有我的配置文件classify_cfg.py

import torch

BATCH_SIZE = 2  # 每批处理的数据
DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')  # 放在cuda或者cpu上训练
EPOCHS = 30  # 训练数据集的轮次
LR = 1e-3       # 学习率
INPUT_SIZE = 160    # 输入图片大小
MEAN = [0.485, 0.456, 0.406]    # 均值
STD = [0.229, 0.224, 0.225]     # 方差

 文章来源地址https://www.toymoban.com/news/detail-411467.html

到了这里,关于ResNet50的猫狗分类训练及预测的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MATLAB卷积神经网络——基于ResNet-50进行图像分类

    一、ResNet50工具箱安装 (1)下载工具箱 https://ww2.mathworks.cn/matlabcentral/fileexchange/64626-deep-learning-toolbox-model-for-resnet-50-network (2)在matlab打开下载的resnet50.mlpkginstall文件 (3)使用下面代码进行测试,出现结果说明安装成功 二、训练猫狗数据集 (1)数据集下载链接:    http

    2024年02月21日
    浏览(40)
  • 基于卷积神经网络VGG的猫狗识别

    !有需要本项目的实验源码的可以私信博主! 摘要: 随着大数据时代的到来,深度学习、数据挖掘、图像处理等已经成为了一个热门研究方向。深度学习是一个复杂的机器学习算法,在语音和图像识别方面取得的效果,远远超过先前相关技术。这也是深度学习在当下备受欢

    2024年02月12日
    浏览(35)
  • 深度学习图像分类实战——pytorch搭建卷积神经网络(AlexNet, LeNet, ResNet50)进行场景图像分类(详细)

    目录 1  一、实验过程 1.1  实验目的 1.2  实验简介 1.3  数据集的介绍 1.4  一、LeNet5网络模型 1.5  二、AlexNet网络模型 1.6  三、ResNet50(残差网络)网络模型  二、实验代码 导入实验所需要的库  参数配置 数据预处理 重新DataSet 加载数据转为DataLoader函数 可视化一批训练

    2024年02月05日
    浏览(48)
  • 计算机视觉的应用8-基于ResNet50对童年数码宝贝的识别与分类

    大家好,我是微学AI,今天给大家介绍一下计算机视觉的应用8-基于ResNet50对童年数码宝贝的识别与分类,想必做完90后的大家都看过数码宝贝吧,里面有好多类型的数码宝贝,今天就给大家简单实现一下,他们的分类任务。 引言 ResNet50模型简介 ResNet50模型原理 ResNet50模型的应

    2024年04月28日
    浏览(30)
  • 基于kaggle数据集的猫狗识别(超详细版本)

    kaggle猫狗识别数据集共包含25000张JPEG数据集照片,其中猫和狗的照片各占12500张。数据集大小经过压缩打包后占543MB。 数据集可以从kaggle官方网站下载,链接如下: 如果嫌官网下载麻烦,也可以从博主之前分享的百度网盘链接中直接获取: 网盘分享—博客链接,点击 在下载

    2024年01月21日
    浏览(64)
  • 度学习pytorch实战六:ResNet50网络图像分类篇自建花数据集图像分类(5类)超详细代码

    1.数据集简介、训练集与测试集划分 2.模型相关知识 3.model.py——定义ResNet50网络模型 4.train.py——加载数据集并训练,训练集计算损失值loss,测试集计算accuracy,保存训练好的网络参数 5.predict.py——利用训练好的网络参数后,用自己找的图像进行分类测试 1.自建数据文件夹

    2024年02月09日
    浏览(28)
  • 基于卷积神经网络的猫狗识别系统的设计与实现

            通过卷积网络实现猫狗图像的识别。首先,在数据集中抽取训练集和测试集;其次,对图像进行预处理和特征提取,对图像数据进行图像增强,将图像从.jpg格式转化为RGB像素网格,再转化为像素张量;再次,搭建卷积神经网络模型;最后,使用模型进行训练,得

    2024年02月11日
    浏览(33)
  • 3D-Resnet-50 医学图像分类(二分类任务)torch代码(精简版)-图像格式为NIFTI

    img_list格式如下 E:...3.nrrd E:...3.nrrd 0 E:...4.nrrd E:...4.nrrd 1 训练代码

    2024年02月12日
    浏览(28)
  • 【人工智能与机器学习】基于卷积神经网络CNN的猫狗识别

    很巧,笔者在几月前的计算机设计大赛作品设计中也采用了猫狗识别,目前已推国赛评选中 但当时所使用的方法与本次作业要求不太一致,又重新做了一遍,下文将以本次作业要求为主,介绍CNN卷积神经网络实现猫狗识别 猫狗识别和狗品种识别是计算机视觉领域中一个重要

    2024年02月13日
    浏览(37)
  • 深度学习(16)--基于经典网络架构resnet训练图像分类模型

    目录 一.项目介绍 二.项目流程详解 2.1.引入所需的工具包 2.2.数据读取和预处理 2.3.加载resnet152模型 2.4.初始化模型 2.5.设置需要更新的参数 2.6.训练模块设置 2.7.再次训练所有层 2.8.测试网络效果 三.完整代码 使用PyTorch工具包调用经典网络架构resnet训练图像分类模型,用于分辨

    2024年02月20日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包