图像语义分割实践(二)数据增强与读取

图像语义分割实践(二)数据增强与读取

Pytorch数据加载顺序

神经网络模型训练过程需要进行梯度更新,梯度更新可分三种方式。1.批梯度下降(batch gradient descent):一次所有数据批计算,过于复杂,计算缓慢;2.随机梯度下降(stochastic gradient descent):每次读一个数据,数据差异大,导致训练波动太大,收敛性不好;3.最小批量梯度下降(mini-batch gradient descent / SGD gradient descent):随机取一定量数据进行训练,既降低计算量,又能提高训练速度。

使用pytorch对数据进行批次量读取构建,首先了解其加载数据顺序分为以下三个点。

pytorch中加载数据的顺序分为以下三个点:
1."创建一个 dataset 对象"; 并加入 transforms 数据增强方案;
2."创建一个 dataloader 对象";
3."获取数据集的 mini_batch"; 循环 dataloader 对象, 获取训练样本送入模型进行训练;

其中, 
"1.创建一个 dataset 对象", 继承 pytorch 的 torch.utils.data.Dataset; 一般需要含3个主要函数:
    1.__init__:    传入数据, 或者直接加载固化的数据包;
    2.__len__:     返回这个数据集一共有多少个item;
    3.__getitem__:  返回一条训练数据, 并将其转换成tensor;

"2.创建一个 dataloader 对象", 采用 pytorch 的 torch.utils.data.DataLoader 整合成 mini_batch;

"3.获取数据集的 mini_batch"

Pytorch官方示例与实践改造

Pytorch官方示例与实践改造

1.构建dataset对象.png

2.构建dataloader对象.png
3.索引minibatch数据.png

数据加载万能模板

针对自己数据集进行分装,数据列表单元+数据增强单元是我们需要关注的点,所以只要在这两个函数进行改造,其他部分和官方的1.dataset对象,2.dataloader对象,3.mini_batch获取一致。


4.minibatch可视化.png

模板代码示例

######## py内置函数:help-文件架构, dir-代码架构 ########
import torch # 包含基本,加减乘除,张量操作,优化器'torch.optim', 数据索引 'torch.utils.data.DataLoader'
import torch.nn as nn # "类":   包含卷积,池化,激活,损失等 "nn.CrossEntropyLoss()"
import torch.nn.functional as F  # "函数": 包含卷积,池化,激活,损失等 "F.cross_entropy()"
import torchvision # 包含图像算法的基本操作等 torchvision.models; torchvision.datasets;
import torchvision.transforms as T # "类":   包含图像增强方向等 "T.RandomCrop()"
import torchvision.transforms.functional as TF # "函数": 包含图像增强方向等 "TF.center_crop()"
import os
import glob
import math
import numpy as np
import random
from PIL import Image
import PIL
import matplotlib.pyplot as plt


#################### 构建 lines 可略 ####################
class MyLinesGetter(object):
    def __init__(self, FilePath, dtype="seg"):
        self.FilePath = FilePath
        self.dtype = dtype # None="cls", "seg"
    def getter(self):
        self.datalines = []
        with open(self.FilePath, "r") as f:
            lines = f.read().splitlines()
            if self.dtype is 'seg':
                for line in lines:
                    img_dir, seg_dir = line.split(" ")[:2]
                    img_dir = os.path.join("data_flowers", "JPEGImages", img_dir)
                    seg_dir = os.path.join("data_flowers", "SegmentationClassRAW", seg_dir)
                    self.datalines.append([img_dir, seg_dir])
            else:
                raise "wrong dtype! check dtype on ['seg']!"
        return self.datalines

#################### 创建 dataset class ####################
class SegmentDataset(torch.utils.data.Dataset): # 继承
    def __init__(self, dataset, transforms=None):
        self.dataset = dataset
        self.transforms = transforms
    def __len__(self):
        return len(self.dataset)
    def __getitem__(self, idx):
        img_dir, seg_dir = self.dataset[idx]
        img = Image.open(img_dir)
        seg = Image.open(seg_dir)
        if self.transforms is not None:
            data_dict = self.transforms(img, seg)
            img = data_dict['image']
            seg = data_dict["mask"]
        else:
            img = TF.to_tensor(img)
            seg = torch.as_tensor(np.array(seg), dtype=torch.int64)
        return img, seg
    pass

#################### 创建 transforms+Compose 增强方案 ####################
class Resize(object):
    def __init__(self, size):
        self.size = size
    
    def __call__(self, image, target=None, label=None):
        image = TF.resize(image, self.size)
        if target is not None:
            target = TF.resize(target, self.size, interpolation=PIL.Image.BILINEAR) # PIL.Image.BILINEAR
        if label is not None:
            label = label
        return image, target, label
    pass

class ToTensor(object):
    def __call__(self, image, target=None, label=None):
        image = TF.to_tensor(image)
        if target is not None:
            target = torch.as_tensor(np.array(target), dtype=torch.int64)
        return image, target, label
    pass

# 可用 torchvision 里面的 compose, 为方便看过程,因此自己实现一遍
class Compose(object):
    def __init__(self, transforms):
        self.transforms = transforms
    def __call__(self, image, mask=None, label=None):
        for t in self.transforms:
            image, mask, label = t(image, mask, label)
        return {'image':image, 'mask':mask, 'label':label}
    pass

if __name__=="__main__":
    # "1.创建一个 dataset 对象"
    train_dataset = SegmentDataset(MyLinesGetter(FilePath="data_flowers/train.txt", dtype="seg").getter(), 
                                   transforms=Compose([Resize((256,256)), ToTensor(),]))

    # "2.创建一个 dataloader 对象"
    train_data_loader = torch.utils.data.DataLoader(train_dataset, batch_size=8, shuffle=True)

    # "3.获取数据集的 mini_batch"
    for (images, masks) in train_data_loader:
        plt.figure(figsize=(20,20))
        plt.imshow(np.hstack(images.permute(0,2,3,1)))
        plt.show()
        plt.figure(figsize=(20,20))
        plt.imshow(np.hstack(masks))
        plt.show()
        break

参考链接

植物素材库
代码高亮
Pytorch dataset&dataloader
图像语义分割实践

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容