使用pytorch实现基于VGG 19预训练模型的鲜花识别分类器

代码征途
• 阅读 5511

项目说明

本文使用的数据集是网络开源的鲜花数据集,并且基于VGG19的预训练模型通过迁移学习重新训练鲜花数据由此构建一个鲜花识别分类器

数据集

可以在此处找到有关花朵数据集的信息。数据集为102个花类的每一个都包含一个单独的文件夹。每朵花都标记为一个数字,每个编号的目录都包含许多.jpg文件。

实验环境

prtorch库

PIL库

如果想使用GPU训练的话请使用英伟达的显卡并安装好CUDA

如果用GPU的话我在自己电脑上使用GPU只使用了91分钟(我的GPU是1050)

倒入库并检测是否有可用GPU

%matplotlib inline

%config InlineBackend.figure_format = 'retina'

import time

import json

import copy

import matplotlib.pyplot as plt

import seaborn as sns

import numpy as np

import PIL

from PIL import Image

from collections import OrderedDict

import torch

from torch import nn, optim

from torch.optim import lr_scheduler

from torch.autograd import Variable

import torchvision

from torchvision import datasets, models, transforms

from torch.utils.data.sampler import SubsetRandomSampler

import torch.nn as nn

import torch.nn.functional as F

import os

# check if GPU is available

train_on_gpu = torch.cuda.is_available()

if not train_on_gpu:

    print('Bummer!  Training on CPU ...')

else:

    print('You are good to go!  Training on GPU ...')

有GPU就启用

    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

定义数据集位置

data_dir = 'F:\资料\项目\image_classifier_pytorch-master\\flower_data'

train_dir = 'flower_data/train'

valid_dir = 'flower_data/valid'

导入数据集并对数据进行处理

# Define your transforms for the training and testing sets

data_transforms = {

    'train': transforms.Compose([

        transforms.RandomRotation(30),

        transforms.RandomResizedCrop(224),

        transforms.RandomHorizontalFlip(),

        transforms.ToTensor(),

        transforms.Normalize([0.485, 0.456, 0.406],

                             [0.229, 0.224, 0.225])

    ]),

    'valid': transforms.Compose([

        transforms.Resize(256),

        transforms.CenterCrop(224),

        transforms.ToTensor(),

        transforms.Normalize([0.485, 0.456, 0.406],

                             [0.229, 0.224, 0.225])

    ])

}

# Load the datasets with ImageFolder

image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),

                                          data_transforms[x])

                  for x in ['train', 'valid']}

# Using the image datasets and the trainforms, define the dataloaders

batch_size = 64

dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=batch_size,

                                             shuffle=True, num_workers=4)

              for x in ['train', 'valid']}

class_names = image_datasets['train'].classes

dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'valid']}

class_names = image_datasets['train'].classes

# Label mapping

with open('F:\资料\项目\image_classifier_pytorch-master\cat_to_name.json', 'r') as f:

    cat_to_name = json.load(f)

查看数据情况

# Run this to test the data loader

images, labels = next(iter(dataloaders['train']))

images.size()

# # Run this to test your data loader

images, labels = next(iter(dataloaders['train']))

rand_idx = np.random.randint(len(images))

# print(rand_idx)

print("label: {}, class: {}, name: {}".format(labels[rand_idx].item(),

                                               class_names[labels[rand_idx].item()],

                                               cat_to_name[class_names[labels[rand_idx].item()]]))

定义模型

model_name = 'densenet' #vgg

if model_name == 'densenet':

    model = models.densenet161(pretrained=True)

    num_in_features = 2208

    print(model)

elif model_name == 'vgg':

    model = models.vgg19(pretrained=True)

    num_in_features = 25088

    print(model.classifier)

else:

    print("Unknown model, please choose 'densenet' or 'vgg'")

# Create classifier

for param in model.parameters():

    param.requires_grad = False

def build_classifier(num_in_features, hidden_layers, num_out_features):

    classifier = nn.Sequential()

    if hidden_layers == None:

        classifier.add_module('fc0', nn.Linear(num_in_features, 102))

    else:

        layer_sizes = zip(hidden_layers[:-1], hidden_layers[1:])

        classifier.add_module('fc0', nn.Linear(num_in_features, hidden_layers[0]))

        classifier.add_module('relu0', nn.ReLU())

function(){ //XM返佣 http://www.kaifx.cn/broker/xm.html

        classifier.add_module('drop0', nn.Dropout(.6))

        classifier.add_module('relu1', nn.ReLU())

        classifier.add_module('drop1', nn.Dropout(.5))

        for i, (h1, h2) in enumerate(layer_sizes):

            classifier.add_module('fc'+str(i+1), nn.Linear(h1, h2))

            classifier.add_module('relu'+str(i+1), nn.ReLU())

            classifier.add_module('drop'+str(i+1), nn.Dropout(.5))

        classifier.add_module('output', nn.Linear(hidden_layers[-1], num_out_features))

    return classifier

hidden_layers = None#[4096, 1024, 256][512, 256, 128]

classifier = build_classifier(num_in_features, hidden_layers, 102)

print(classifier)

 # Only train the classifier parameters, feature parameters are frozen

if model_name == 'densenet':

    model.classifier = classifier

    criterion = nn.CrossEntropyLoss()

    optimizer = optim.Adadelta(model.parameters()) # Adadelta #weight optim.Adam(model.parameters(), lr=0.001, momentum=0.9)

    #optimizer_conv = optim.SGD(model.parameters(), lr=0.0001, weight_decay=0.001, momentum=0.9)

    sched = optim.lr_scheduler.StepLR(optimizer, step_size=4)

elif model_name == 'vgg':

    model.classifier = classifier

    criterion = nn.NLLLoss()

    optimizer = optim.Adam(model.classifier.parameters(), lr=0.0001)

    sched = lr_scheduler.StepLR(optimizer, step_size=4, gamma=0.1)

else:

    pass

def train_model(model, criterion, optimizer, sched, num_epochs=5):

    since = time.time()

    best_model_wts = copy.deepcopy(model.state_dict())

    best_acc = 0.0

    for epoch in range(num_epochs):

        print('Epoch {}/{}'.format(epoch+1, num_epochs))

        print('-' * 10)

        # Each epoch has a training and validation phase

        for phase in ['train', 'valid']:

            if phase == 'train':

                model.train()  # Set model to training mode

            else:

                model.eval()   # Set model to evaluate mode

            running_loss = 0.0

            running_corrects = 0

            # Iterate over data.

            for inputs, labels in dataloaders[phase]:

                inputs = inputs.to(device)

                labels = labels.to(device)

                # zero the parameter gradients

                optimizer.zero_grad()

                # forward

                # track history if only in train

                with torch.set_grad_enabled(phase == 'train'):

                    outputs = model(inputs)

                    _, preds = torch.max(outputs, 1)

                    loss = criterion(outputs, labels)

                    # backward + optimize only if in training phase

                    if phase == 'train':

                        #sched.step()

                        loss.backward()

                        optimizer.step()

                # statistics

                running_loss += loss.item() * inputs.size(0)

                running_corrects += torch.sum(preds == labels.data)

            epoch_loss = running_loss / dataset_sizes[phase]

            epoch_acc = running_corrects.double() / dataset_sizes[phase]

            print('{} Loss: {:.4f} Acc: {:.4f}'.format(

                phase, epoch_loss, epoch_acc))

            # deep copy the model

            if phase == 'valid' and epoch_acc > best_acc:

                best_acc = epoch_acc

                best_model_wts = copy.deepcopy(model.state_dict())

        print()

    time_elapsed = time.time() - since

    print('Training complete in {:.0f}m {:.0f}s'.format(

        time_elapsed // 60, time_elapsed % 60))

    print('Best val Acc: {:4f}'.format(best_acc))

    #load best model weights

    model.load_state_dict(best_model_wts)

    return model

开始训练

epochs = 30

model.to(device)

model = train_model(model, criterion, optimizer, sched, epochs)

点赞
收藏
评论区
推荐文章
什么是fine-tuning?
什么是finetuning?在实践中,由于数据集不够大,很少有人从头开始训练网络。常见的做法是使用预训练的网络(例如在ImageNet上训练的分类1000类的网络)来重新finetuning(也叫微调),或者当做特征提取器。以下是常见的两类迁移学习场景:1卷积网络当做特征提取器。使用在ImageNet上预训练的网络,去掉最后的全连接层,剩余
Stella981 Stella981
3年前
Python之TensorFlow的(案例)验证码识别
  一、这里的案例相对比较简单,主要就是通过学习验证码的识别来认识深度学习中我们一般在工作中,需要处理的东西会存在哪些东西。  二、因为我没有数据集,没有关系,这里自己写了一个数据集,来做测试,为了方便我把这个数据集,写成了\.tfrecords格式的文件。  三、生成数据集  1)生成验证码图片生成验证码训练集
数据堂 数据堂
1年前
大模型数据集:突破边界,探索未来
一、引言随着人工智能技术的快速发展,大型预训练模型如GPT4、BERT等在自然语言处理领域取得了显著的成功。这些大模型背后的关键之一是庞大的数据集,为模型提供了丰富的知识和信息。本文将探讨大模型数据集的突破边界以及未来发展趋势。二、大模型数据集的突破边界数
数据堂 数据堂
1年前
大模型数据集:构建、挑战与未来发展
一、引言随着深度学习技术的迅速发展,大型预训练模型如GPT4、BERT等在自然语言处理领域取得了显著的成果。这些大模型的表现得益于其背后庞大的数据集,这些数据集为模型提供了丰富的知识和信息。本文将探讨大模型数据集的构建、面临的挑战以及未来的发展趋势。二、大
数据堂 数据堂
1年前
大模型数据集:探索新维度,引领AI变革
一、引言在人工智能(AI)的快速发展中,大型预训练模型如GPT、BERT等已经取得了令人瞩目的成果。这些大模型的背后,离不开规模庞大、质量优良的数据集的支撑。本文将从不同的角度来探讨大模型数据集的新维度,以及它们如何引领AI的变革。二、大模型数据集的新维度
数据堂 数据堂
1年前
语音数据集:AI语音技术的基石
一、引言在人工智能领域,语音技术正逐渐成为研究的热点之一。语音数据集作为AI语音技术的基石,对于模型的训练和应用至关重要。本文将深入探讨语音数据集的重要性、构建方法、挑战以及未来的发展趋势。二、语音数据集的重要性语音识别:语音数据集是实现语音识别的关键。通
高耸入云 高耸入云
1年前
如何做Bert模型的fine-tuning?近屿智能OJAC带你一探究竟
📖更多AI资讯请👉🏾选择合适的预训练模型:从预训练的BERT模型开始,例如Google提供的BERTbase或BERTlarge。这些模型已经在大量文本数据上进行过预训练了,我们如何对BERT模型进行finetuning呢?准备和预处理数据:集针对特
马尚 马尚
1年前
使用Python进行简单的图像分类
图像分类是深度学习中的一个常见任务,它可以将图像分到预定义的类别中。本文将介绍如何使用Python和PyTorch库进行简单的图像分类任务。1.准备数据集首先,我们需要准备一个图像数据集,其中包含不同类别的图像。你可以使用自己的数据集,也可以使用公开的数据
数据堂 数据堂
1个月前
数据上新 | 全新高质量训练数据集重磅发布
数据堂全新发布多语种大模型预训练数据集、多模态大模型数据集、语音识别与计算机视觉训练数据集,全面助力企业打造更高精度、更强泛化能力的AI模型,轻松应对全球用户多样化的语言与应用场景需求,为智能升级提供坚实数据支撑。
数据堂 数据堂
1年前
大模型数据集:构建、挑战与未来趋势
一、引言随着深度学习技术的快速发展,大型预训练模型如GPT4、BERT等在各个领域取得了显著的成功。这些大模型背后的关键之一是庞大的数据集,为模型提供了丰富的知识和信息。本文将探讨大模型数据集的构建、面临的挑战以及未来发展趋势。二、大模型数据集的构建收集数