dnn分类鸢尾花 pytorch_使用Pytorch进行图像分类,AI challenger 农作物病害分类竞赛源码解读...

本文介绍了如何使用PyTorch实现鸢尾花数据集的DNN分类,并详细展示了数据预处理的步骤,包括数据划分、自定义数据增强函数。还提供了多种图像增强方法的代码实现,如翻转、裁剪、旋转等,以提高模型的泛化能力。
摘要由CSDN通过智能技术生成

1.首先对给的数据进行划分,类型为每个类单独放在一个文件夹中

import json

import shutil

import os

from glob import glob

from tqdm import tqdm

# 此文件的作用是创建每个类的文件夹,以及根据给出来的Json中已经做好的分类,对数据进行对号入座划分。

# 加载json文件得出一个字典,然后根据Key值来提取每个文件到相应的文件夹中,(注意去除了不合理数据)

try:

for i in range(0,59):

os.mkdir("./data/train/" + str(i))

except:

pass

file_train = json.load(open("./data/temp/labels/AgriculturalDisease_train_annotations.json","r",encoding="utf-8"))

file_val = json.load(open("./data/temp/labels/AgriculturalDisease_validation_annotations.json","r",encoding="utf-8"))

file_list = file_train + file_val

for file in tqdm(file_list):

filename = file["image_id"]

origin_path = "./data/temp/images/" + filename

ids = file["disease_class"]

if ids == 44:

continue

if ids == 45:

continue

if ids > 45:

ids = ids -2

save_path = "./data/train/" + str(ids) + "/"

shutil.copy(origin_path,save_path)

2.获取增强数据集类的定义

1.采用自定义获取增强数据类,此Dataset类中重新定义了对数据进行数据增强的多种方式,不仅限于pytorch中自带的增强方式。

首先附上自定义的数据增强的函数代码:

方式一,以重新定义重载方法类的方式定义多种增强方式,在dataset类中的get_item方法中的compose中加入自定义的方法,即可调用。

# 数据增强的多种方式,使用自定义的方法。调用只需在dataloader.py文件中的get_item函数中调用类自身参数

# transforms,transforms中集合了compose,compose中列出详细所使用的增强方式。

from __future__ import division

import cv2

import numpy as np

from numpy import random

import math

from sklearn.utils import shuffle

# 常用的增强方式几乎都在这里,只需在compose中列出类名即可

__all__ = ['Compose','RandomHflip', 'RandomUpperCrop', 'Resize', 'UpperCrop', 'RandomBottomCrop',

"RandomErasing",'BottomCrop', 'Normalize', 'RandomSwapChannels', 'RandomRotate',

'RandomHShift',"CenterCrop","RandomVflip",'ExpandBorder', 'RandomResizedCrop',

'RandomDownCrop', 'DownCrop', 'ResizedCrop',"FixRandomRotate"]

# 组合

# “随机翻转”,“随机顶部切割”,“调整大小”,“上切割”,“随机底部切割”、

# “随机擦除”,“底部切割”,“正则化”,“随机交换频道”,“随机旋转”,

# “随机HShift”,“中央切割”,“随机Vflip”,“扩展边界”,“随机调整切割”,

# “随机下降”,“下降切割”, “调整切割”,“固定随机化”。

# 每个增强方式类需要调用普通方法描述如下:

def rotate_nobound(image, angle, center=None, scale=1.):

(h, w) = image.shape[:2]

# if the center is None, initialize it as the center of

# the image

if center is None:

center = (w // 2, h // 2)

# perform the rotation

M = cv2.getRotationMatrix2D(center, angle, scale)

rotated = cv2.warpAffine(image, M, (w, h))

return rotated

def scale_down(src_size, size):

w, h = size

sw, sh = src_size

if sh < h:

w, h = float(w * sh) / h, sh

if sw < w:

w, h = sw, float(h * sw) / w

return int(w), int(h)

def fixed_crop(src, x0, y0, w, h, size=None):

out = src[y0:y0 + h, x0:x0 + w]

if size is not None and (w, h) != size:

out = cv2.resize(out, (size[0], size[1]), interpolation=cv2.INTER_CUBIC)

return out

# 固定随机旋转

class FixRandomRotate(object):

def __init__(self, angles=[0,90,180,270], bound=False):

self.angles = angles

self.bound = bound

def __call__(self,img):

do_rotate = random.randint(0, 4)

angle=self.angles[do_rotate]

if self.bound:

img = rotate_bound(img, angle)

else:

img = rotate_nobound(img, angle)

return img

def center_crop(src, size):

h, w = src.shape[0:2]

new_w, new_h = scale_down((w, h), size)

x0 = int((w - new_w) / 2)

y0 = int((h - new_h) / 2)

out = fixed_crop(src, x0, y0, new_w, new_h, size)

return out

def bottom_crop(src, size):

h, w = src.shape[0:2]

new_w, new_h = scale_down((w, h), size)

x0 = int((w - new_w) / 2)

y0 = int((h - new_h) * 0.75)

out = fixed_crop(src, x0, y0, new_w, new_h, size)

return out

def rotate_bound(image, angle):

# grab the dimensions of the image and then determine the

# center

h, w = image.shape[:2]

(cX, cY) = (w // 2, h // 2)

M = cv2.getRotationMatrix2D((cX, cY), angle, 1.0)

cos = np.abs(M[0, 0])

sin = np.abs(M[0, 1])

# compute the new bounding dimensions of the image

nW = int((h * sin) + (w * cos))

nH = int((h * cos) + (w * sin))

# adjust the rotation matrix to take into account translation

M[0, 2] += (nW / 2) - cX

M[1, 2] += (nH / 2) - cY

rotated = cv2.warpAffine(image, M, (nW, nH))

return rotated

# 常用增强方式,以类的方式体现:

# 将多个transform组合起来使用

crop切割 filp旋转

class Compose(object):

def __init__(self, transforms):

self.transforms = transforms

def __call__(self, img):

for t in self.transforms:

img = t(img)

return img

class RandomRotate(object):

def __init__(self, angles, bound=False):

self.angles = angles

self.bound = bound

def __call__(self,img):

do_rotate = random.randint(0, 2)

if do_rotate:

angle = np.random.uniform(self.angles[0], self.angles[1])

if self.bound:

img = rotate_bound(img, angle)

else:

img = rotate_nobound(img, angle)

return img

class RandomBrightness(object):

def __init__(self, delta=10):

assert delta >= 0

assert delta <= 255

self.delta = delta

def __call__(self, image):

if random.randint(2):

delta = random.uniform(-self.delta, self.delta)

image = (image + delta).clip(0.0, 255.0)

# print('RandomBrightness,delta ',delta)

return image

class RandomContrast(object):

def __init__(self, lower=0.9, upper=1.05):

self.lower = lower

self.upper = upper

assert self.upper >= self.lower, "contrast upper must be >= lower."

assert self.lower >= 0, "contrast lower must be non-negative."

# expects float image

def __call__(self, image):

if random.randint(2):

alpha = random.uniform(self.lower, self.upper)

# print('contrast:', alpha)

image = (image * alpha).clip(0.0,255.0)

return image

class RandomSaturation(object):

def __init__(self, lower=0.8, upper=1.2):

self.lower = lower

self.upper = upper

assert self.upper >= self.lower, "contrast upper must be >= lower."

assert self.lower >= 0, "contrast lower must be non-negative."

def __call__(self, image):

if random.randint(2):

alpha = random.uniform(self.lower, self.upper)

image[:, :, 1] *= alpha

# print('RandomSaturation,alpha',alpha)

return image

class RandomHue(object):

def __init__(self, delta=18.0):

assert delta >= 0.0 and delta <= 360.0

self.delta = delta

def __call__(self, image):

if random.randint(2):

alpha = random.uniform(-self.delta, self.delta)

image[:, :, 0] += alpha

image[:, :, 0][image[:, :, 0] > 360.0] -= 360.0

image[:, :, 0][image[:, :, 0] < 0.0] += 360.0

# print('RandomHue,alpha:', alpha)

return image

class ConvertColor(object):

def __init__(self, current='BGR', transform='HSV'):

self.transform = transform

self.current = current

def __call__(self, image):

if self.current == 'BGR' and self.transform == 'HSV':

image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

elif self.current == 'HSV' and self.transform == 'BGR':

image = cv2.cvtColor(image, cv2.COLOR_HSV2BGR)

else:

raise NotImplementedError

return image

class RandomSwapChannels(object):

def __call__(self, img):

if np.random.randint(2):

order = np.random.permutation(3)

return img[:,:,order]

return img

class RandomCrop(object):

def __init__(self, size):

self.size = size

def __call__(self, image):

h, w, _ = image.shape

new_w, new_h = scale_down((w, h), self.size)

if w == new_w:

x0 = 0

else:

x0 = random.randint(0, w - new_w)

if h == new_h:

y0 = 0

else:

y0 = r

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值