CoAtNet实战之对植物幼苗图像进行分类(pytorch)

目录
  • 前言
  • 项目结构
  • 数据集
  • 安装库,并导入需要的库
  • 设置全局参数
  • 数据预处理
  • 数据读取
  • 设置模型
  • 测试

前言

虽然Transformer在CV任务上有非常强的学习建模能力,但是由于缺少了像CNN那样的归纳偏置,所以相比于CNN,Transformer的泛化能力就比较差。因此,如果只有Transformer进行全局信息的建模,在没有预训练(JFT-300M)的情况下,Transformer在性能上很难超过CNN(VOLO在没有预训练的情况下,一定程度上也是因为VOLO的Outlook Attention对特征信息进行了局部感知,相当于引入了归纳偏置)。既然CNN有更强的泛化能力,Transformer具有更强的学习能力,那么,为什么不能将Transformer和CNN进行一个结合呢?

谷歌的最新模型CoAtNet做了卷积 + Transformer的融合,在ImageNet-1K数据集上取得88.56%的成绩。今天我们就用CoAtNet实现植物幼苗的分类。

论文

github复现

项目结构

数据集

数据集选用植物幼苗分类,总共12类。数据集连接如下:

链接 提取码:q060

在工程的根目录新建data文件夹,获取数据集后,将trian和test解压放到data文件夹下面,如下图:

安装库,并导入需要的库

安装完成后,导入到项目中。

import torch.optim as optim
import torch
import torch.nn as nn
import torch.nn.parallel
import torch.utils.data
import torch.utils.data.distributed
import torchvision.transforms as transforms
from dataset.dataset import SeedlingData
from torch.autograd import Variable
from models.coatnet import coatnet_0

设置全局参数

设置使用GPU,设置学习率、BatchSize、epoch等参数

# 设置全局参数
modellr = 1e-4
BATCH_SIZE = 16
EPOCHS = 50
DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

数据预处理

数据处理比较简单,没有做复杂的尝试,有兴趣的可以加入一些处理。

# 数据预处理

transform = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])

])
transform_test = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
])

数据读取

然后我们在dataset文件夹下面新建 init.py和dataset.py,在mydatasets.py文件夹写入下面的代码:

说一下代码的核心逻辑。

第一步 建立字典,定义类别对应的ID,用数字代替类别。

第二步 在__init__里面编写获取图片路径的方法。测试集只有一层路径直接读取,训练集在train文件夹下面是类别文件夹,先获取到类别,再获取到具体的图片路径。然后使用sklearn中切分数据集的方法,按照7:3的比例切分训练集和验证集。

第三步 在__getitem__方法中定义读取单个图片和类别的方法,由于图像中有位深度32位的,所以我在读取图像的时候做了转换。

代码如下:

# coding:utf8
import os
from PIL import Image
from torch.utils import data
from torchvision import transforms as T
from sklearn.model_selection import train_test_split

Labels = {'Black-grass': 0, 'Charlock': 1, 'Cleavers': 2, 'Common Chickweed': 3,
          'Common wheat': 4, 'Fat Hen': 5, 'Loose Silky-bent': 6, 'Maize': 7, 'Scentless Mayweed': 8,
          'Shepherds Purse': 9, 'Small-flowered Cranesbill': 10, 'Sugar beet': 11}

class SeedlingData (data.Dataset):

    def __init__(self, root, transforms=None, train=True, test=False):
        """
        主要目标: 获取所有图片的地址,并根据训练,验证,测试划分数据
        """
        self.test = test
        self.transforms = transforms

        if self.test:
            imgs = [os.path.join(root, img) for img in os.listdir(root)]
            self.imgs = imgs
        else:
            imgs_labels = [os.path.join(root, img) for img in os.listdir(root)]
            imgs = []
            for imglable in imgs_labels:
                for imgname in os.listdir(imglable):
                    imgpath = os.path.join(imglable, imgname)
                    imgs.append(imgpath)
            trainval_files, val_files = train_test_split(imgs, test_size=0.3, random_state=42)
            if train:
                self.imgs = trainval_files
            else:
                self.imgs = val_files

    def __getitem__(self, index):
        """
        一次返回一张图片的数据
        """
        img_path = self.imgs[index]
        img_path=img_path.replace("\\",'/')
        if self.test:
            label = -1
        else:
            labelname = img_path.split('/')[-2]
            label = Labels[labelname]
        data = Image.open(img_path).convert('RGB')
        data = self.transforms(data)
        return data, label

    def __len__(self):
        return len(self.imgs)

然后我们在train.py调用SeedlingData读取数据 ,记着导入刚才写的dataset.py(from mydatasets import SeedlingData)

# 读取数据
dataset_train = SeedlingData('data/train', transforms=transform, train=True)
dataset_test = SeedlingData("data/train", transforms=transform_test, train=False)
# 导入数据
train_loader = torch.utils.data.DataLoader(dataset_train, batch_size=BATCH_SIZE, shuffle=True)
test_loader = torch.utils.data.DataLoader(dataset_test, batch_size=BATCH_SIZE, shuffle=False)

设置模型

  • 设置loss函数为nn.CrossEntropyLoss()。
  • 设置模型为coatnet_0,修改最后一层全连接输出改为12。
  • 优化器设置为adam。
  • 学习率调整策略改为余弦退火
# 实例化模型并且移动到GPU
criterion = nn.CrossEntropyLoss()

model_ft = coatnet_0()
num_ftrs = model_ft.fc.in_features
model_ft.fc = nn.Linear(num_ftrs, 12)
model_ft.to(DEVICE)
# 选择简单暴力的Adam优化器,学习率调低
optimizer = optim.Adam(model_ft.parameters(), lr=modellr)
cosine_schedule = optim.lr_scheduler.CosineAnnealingLR(optimizer=optimizer,T_max=20,eta_min=1e-9)
# 定义训练过程

def train(model, device, train_loader, optimizer, epoch):
    model.train()
    sum_loss = 0
    total_num = len(train_loader.dataset)
    print(total_num, len(train_loader))
    for batch_idx, (data, target) in enumerate(train_loader):
        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
        if (batch_idx + 1) % 10 == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, (batch_idx + 1) * len(data), len(train_loader.dataset),
                       100. * (batch_idx + 1) / len(train_loader), loss.item()))
    ave_loss = sum_loss / len(train_loader)
    print('epoch:{},loss:{}'.format(epoch, ave_loss))

# 验证过程
def val(model, device, test_loader):
    model.eval()
    test_loss = 0
    correct = 0
    total_num = len(test_loader.dataset)
    print(total_num, len(test_loader))
    with torch.no_grad():
        for data, target in test_loader:
            data, target = Variable(data).to(device), Variable(target).to(device)
            output = model(data)
            loss = criterion(output, target)
            _, pred = torch.max(output.data, 1)
            correct += torch.sum(pred == target)
            print_loss = loss.data.item()
            test_loss += print_loss
        correct = correct.data.item()
        acc = correct / total_num
        avgloss = test_loss / len(test_loader)
        print('\nVal set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
            avgloss, correct, len(test_loader.dataset), 100 * acc))

# 训练

for epoch in range(1, EPOCHS + 1):
    train(model_ft, DEVICE, train_loader, optimizer, epoch)
    cosine_schedule.step()
    val(model_ft, DEVICE, test_loader)
torch.save(model_ft, 'model.pth')

测试

测试集存放的目录如下图:

第一步 定义类别,这个类别的顺序和训练时的类别顺序对应,一定不要改变顺序!!!!

classes = ('Black-grass', 'Charlock', 'Cleavers', 'Common Chickweed',
           'Common wheat', 'Fat Hen', 'Loose Silky-bent',
           'Maize', 'Scentless Mayweed', 'Shepherds Purse', 'Small-flowered Cranesbill', 'Sugar beet')

第二步 定义transforms,transforms和验证集的transforms一样即可,别做数据增强。

transform_test = transforms.Compose([
         transforms.Resize((224, 224)),
        transforms.ToTensor(),
        transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
])

第三步 加载model,并将模型放在DEVICE里。

DEVICE = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model = torch.load("model.pth")
model.eval()
model.to(DEVICE)

第四步 读取图片并预测图片的类别,在这里注意,读取图片用PIL库的Image。不要用cv2,transforms不支持。

path = 'data/test/'
testList = os.listdir(path)
for file in testList:
    img = Image.open(path + file)
    img = transform_test(img)
    img.unsqueeze_(0)
    img = Variable(img).to(DEVICE)
    out = model(img)
    # Predict
    _, pred = torch.max(out.data, 1)
    print('Image Name:{},predict:{}'.format(file, classes[pred.data.item()]))

测试完整代码:

import torch.utils.data.distributed
import torchvision.transforms as transforms
from PIL import Image
from torch.autograd import Variable
import os

classes = ('Black-grass', 'Charlock', 'Cleavers', 'Common Chickweed',
           'Common wheat', 'Fat Hen', 'Loose Silky-bent',
           'Maize', 'Scentless Mayweed', 'Shepherds Purse', 'Small-flowered Cranesbill', 'Sugar beet')
transform_test = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
])

DEVICE = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model = torch.load("model.pth")
model.eval()
model.to(DEVICE)

path = 'data/test/'
testList = os.listdir(path)
for file in testList:
    img = Image.open(path + file)
    img = transform_test(img)
    img.unsqueeze_(0)
    img = Variable(img).to(DEVICE)
    out = model(img)
    # Predict
    _, pred = torch.max(out.data, 1)
    print('Image Name:{},predict:{}'.format(file, classes[pred.data.item()]))

运行结果:

以上就是CoAtNet实战之对植物幼苗图像进行分类(pytorch)的详细内容,更多关于CoAtNet 植物幼苗图像分类的资料请关注我们其它相关文章!

(0)

相关推荐

  • Python深度学习pytorch实现图像分类数据集

    目录 读取数据集 读取小批量 整合所有组件 目前广泛使用的图像分类数据集之一是MNIST数据集.如今,MNIST数据集更像是一个健全的检查,而不是一个基准. 为了提高难度,我们将在接下来的章节中讨论在2017年发布的性质相似但相对复杂的Fashion-MNIST数据集. import torch import torchvision from torch.utils import data from torchvision import transforms from d2l import to

  • 基于PyTorch实现一个简单的CNN图像分类器

    pytorch中文网:https://www.pytorchtutorial.com/ pytorch官方文档:https://pytorch.org/docs/stable/index.html 一. 加载数据 Pytorch的数据加载一般是用torch.utils.data.Dataset与torch.utils.data.Dataloader两个类联合进行.我们需要继承Dataset来定义自己的数据集类,然后在训练时用Dataloader加载自定义的数据集类. 1. 继承Dataset类并

  • Python Pytorch深度学习之图像分类器

    目录 一.简介 二.数据集 三.训练一个图像分类器 1.导入package吧 2.归一化处理+贴标签吧 3.先来康康训练集中的照片吧 4.定义一个神经网络吧 5.定义一个损失函数和优化器吧 6.训练网络吧 7.在测试集上测试一下网络吧 8.分别查看一下训练效果吧 总结 一.简介 通常,当处理图像.文本.语音或视频数据时,可以使用标准Python将数据加载到numpy数组格式,然后将这个数组转换成torch.*Tensor 对于图像,可以用Pillow,OpenCV 对于语音,可以用scipy,l

  • Pytorch 使用CNN图像分类的实现

    需求 在4*4的图片中,比较外围黑色像素点和内圈黑色像素点个数的大小将图片分类 如上图图片外围黑色像素点5个大于内圈黑色像素点1个分为0类反之1类 想法 通过numpy.PIL构造4*4的图像数据集 构造自己的数据集类 读取数据集对数据集选取减少偏斜 cnn设计因为特征少,直接1*1卷积层 或者在4*4外围添加padding成6*6,设计2*2的卷积核得出3*3再接上全连接层 代码 import torch import torchvision import torchvision.transf

  • 使用PyTorch训练一个图像分类器实例

    如下所示: import torch import torchvision import torchvision.transforms as transforms import matplotlib.pyplot as plt import numpy as np print("torch: %s" % torch.__version__) print("tortorchvisionch: %s" % torchvision.__version__) print(&

  • CoAtNet实战之对植物幼苗图像进行分类(pytorch)

    目录 前言 项目结构 数据集 安装库,并导入需要的库 设置全局参数 数据预处理 数据读取 设置模型 测试 前言 虽然Transformer在CV任务上有非常强的学习建模能力,但是由于缺少了像CNN那样的归纳偏置,所以相比于CNN,Transformer的泛化能力就比较差.因此,如果只有Transformer进行全局信息的建模,在没有预训练(JFT-300M)的情况下,Transformer在性能上很难超过CNN(VOLO在没有预训练的情况下,一定程度上也是因为VOLO的Outlook Atten

  • ConvNeXt实战之实现植物幼苗分类

    目录 前言 ConvNeXt残差模块 数据增强Cutout和Mixup 项目结构 数据集 导入模型文件 安装库,并导入需要的库 设置全局参数 数据预处理 设置模型 定义训练和验证函数 测试 第一种写法 第二种写法 前言 ConvNeXts 完全由标准 ConvNet 模块构建,在准确性和可扩展性方面与 Transformer 竞争,实现 87.8% ImageNet top-1 准确率,在 COCO 检测和 ADE20K 分割方面优于 Swin Transformers,同时保持标准 ConvN

  • pytorch绘制并显示loss曲线和acc曲线,LeNet5识别图像准确率

    我用的是Anaconda3 ,用spyder编写pytorch的代码,在Anaconda3中新建了一个pytorch的虚拟环境(虚拟环境的名字就叫pytorch). 以下内容仅供参考哦~~ 1.首先打开Anaconda Prompt,然后输入activate pytorch,进入pytorch. 2.输入pip install tensorboardX,安装完成后,输入python,用from tensorboardX import SummaryWriter检验是否安装成功.如下图所示: 3.

  • 基于Matlab LBP实现植物叶片识别功能

    目录 一.LBP简介 1.1 课题的提出与研究意义 1.2 国内外相关研究情况 1.3 论文的主要研究工作 1.4 论文结构 二.部分源代码 三.运行结果 一.LBP简介 第一章 引言 植物在我们的身边随处可见,它们从产生发展进化到现在,其间经历了漫长的岁月.地球上的植物种类繁多.数量浩瀚,它们是生物圈的重要组成部分,在维持整个生物界的平衡方面发挥着巨大的作用:它们同时也是构成人类生存环境的重要组成部分,是人类社会延续和发展不可或缺的重要因素.由于植物对于地球和人类都具有如此重要的意义,对它们的

  • 详解在OpenCV中实现的图像标注技术

    目录 目录 图像注解 对图片注释的需求 图像注解的类型 分类法 物体检测 语义分割 用OpenCV实现图像注解 包围盒方法 KNN方法进行分割 结论 参考文献 图像标注在计算机视觉中很重要,计算机视觉是一种技术,它允许计算机从数字图像或视频中获得高水平的理解力,并以人类的方式观察和解释视觉信息.注释,通常被称为图片标签,是大多数计算机视觉模型发展中的一个关键阶段.本文将重点讨论在OpenCV的帮助下创建这些注释.以下是将要涉及的主题. 目录 图像注解 对图像注释的需求 图像注解的类型 用Open

  • Pytorch如何把Tensor转化成图像可视化

    目录 Pytorch把Tensor转化成图像可视化 pytorch标准化的Tensor转图像问题 总结 Pytorch把Tensor转化成图像可视化 在调试程序的时候经常想把tensor可视化成来看看,可以这样操作: from torchvision import transforms unloader = transforms.ToPILImage() image = original_tensor.cpu().clone()  # clone the tensor image = image

  • Tensorflow 训练自己的数据集将数据直接导入到内存

    制作自己的训练集 下图是我们数据的存放格式,在data目录下有验证集与测试集分别对应iris_test, iris_train 为了向伟大的MNIST致敬,我们采用的数据名称格式和MNIST类似 classification_index.jpg 图像的index都是5的整数倍是因为我们选择测试集的原则是每5个样本,选择一个样本作为测试集,其余的作为训练集和验证集 生成这样数据的过程相对简单,如果有需要python代码的,可以给我发邮件,或者在我的github下载 至此,我们的训练集,测试集,验证

  • Keras搭建自编码器操作

    简介: 传统机器学习任务任务很大程度上依赖于好的特征工程,但是特征工程往往耗时耗力,在视频.语音和视频中提取到有效特征就更难了,工程师必须在这些领域有非常深入的理解,并且需要使用专业算法提取这些数据的特征.深度学习则可以解决人工难以提取有效特征的问题,大大缓解机器学习模型对特征工程的依赖. 深度学习在早期一度被认为是一种无监督的特征学习过程,模仿人脑对特征逐层抽象的过程.这其中两点很重要:一是无监督学习:二是逐层训练.例如在图像识别问题中,假定我们有许多汽车图片,要如何利用计算机进行识别任务呢?

  • pytorch 搭建神经网路的实现

    目录 1 数据 (1)导入数据 (2)数据集可视化 (3)为自己制作的数据集创建类 (4)数据集批处理 (5)数据预处理 2 神经网络 (1)定义神经网络类 (3)模型参数 3 最优化模型参数 (1)超参数 (2)损失函数 (3)优化方法 4 模型的训练与测试 (1)训练循环与测试循环 (2)禁用梯度跟踪 5 模型的保存.导入与GPU加速 (1)模型的保存与导入 (2)GPU加速 总结 1 数据 (1)导入数据 我们以Fashion-MNIST数据集为例,介绍一下关于pytorch的数据集导入.

  • opencv基于Haar人脸检测和眼睛检测

    在这里,我们将进行人脸检测.最初,该算法需要大量正图像(面部图像)和负图像(无面部图像)来训练分类器.然后,我们需要从中提取特征.为此,使用下图所示的Haar功能.它们就像我们的卷积核.每个特征都是通过从黑色矩形下的像素总和中减去白色矩形下的像素总和而获得的单个值. 现在,每个内核的所有可能大小和位置都用于计算许多功能.(试想一下它需要多少计算?即使是一个24x24的窗口也会产生超过160000个特征).对于每个特征计算,我们需要找到白色和黑色矩形下的像素总和.为了解决这个问题,他们引入了整体形

随机推荐