视频数据数据集处理与加载(Pytorch)

之前说过要用PyTorch的方法重新实现一遍对于UCF101的处理。

#  pytorch 为 c h w   一般常规为 h w c

二 具体目标

按照trainlist(testllist)中的列表去确定要用哪些数据集。
对于每一个视频随机取连续的16帧
每一帧都减去RGB平均值
对于每帧先将大小修改到(182,242)
然后对修改过大小的帧随机截取(160,160)
每次返回视频表示: x[batch_size,16,3,160,160], 标签值: y[batch_size]

三 基本实现思路
鉴于我们现在要处理的数据集既不是PyTorch直接提供的,又不符合最通用的ImageFolder存储格式,我们就乖乖一步步地实现。

跟例程中最大的区别在于我们组要处理的视频,而不是单张图像,那么就把这一步工作放到__getitem__里面去完成。
剩下的变换功能放到transform里面去完成。

具体的步骤如下所示:

首先,定义数据集的类UCF101,这个类要继承dataset这个抽象类,并实现__init__ , __len__以及__getitem__这几个函数

init:完成infolist的读入及处理还有其他的初始化工作。

len:返回数据集大小

getitem:返回单个视频随机连续16帧的读取和返回
其他函数用于支持以上的功能。

然后,实现用于特定图像预处理的功能,并封装成类。

减去RGB的平均值
大小调整成(182,242)
随机截取成(160,160)
转换成Tensor
将它们进行组合成(transform)

transform作为上面UCF101类的参数传入,并得到实例化UCF101得到my_UCF101对象。
最后,将my_UCF101作为torch.utils.data.DataLoader类的形参,并根据需求设置自己是否需要打乱顺序,批大小…

四 完整代码
原理的部分不懂的话还是建议回去看看这篇哇:PyTorch入门学习(七):数据加载与处理
这里就不再赘述,直接上代码了。
from future import print_function, division
import os
import torch
import pandas as pd
from skimage import io, transform
import numpy as np
import random
import torch
import matplotlib.pyplot as plt
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms, utils

Ignore warnings

import warnings
warnings.filterwarnings(“ignore”)
plt.ion() # interactive mode

class ClipSubstractMean(object):
def init(self, b=104, g=117, r=123):
self.means = np.array((r, g, b))

def call(self, sample):
video_x,video_label=sample[‘video_x’],sample[‘video_label’]
new_video_x=video_x - self.means
return {‘video_x’: new_video_x, ‘video_label’: video_label}

class Rescale(object):
“”"Rescale the image in a sample to a given size.

Args:
    output_size (tuple or int): Desired output size. If tuple, output is
        matched to output_size. If int, smaller of image edges is matched
        to output_size keeping aspect ratio the same.
"""

def __init__(self, output_size=(182,242)):
    assert isinstance(output_size, (int, tuple))
    self.output_size = output_size

def __call__(self, sample):
    video_x,video_label=sample['video_x'],sample['video_label']

    h, w = video_x.shape[1],video_x[2]
    if isinstance(self.output_size, int):
        if h > w:
            new_h, new_w = self.output_size * h / w, self.output_size
        else:
            new_h, new_w = self.output_size, self.output_size * w / h
    else:
        new_h, new_w = self.output_size

    new_h, new_w = int(new_h), int(new_w)
    new_video_x=np.zeros((16,new_h,new_w,3))
    for i in range(16):
        image=video_x[i,:,:,:]
        img = transform.resize(image, (new_h, new_w))
        new_video_x[i,:,:,:]=img

    return {'video_x': new_video_x, 'video_label': video_label}

class RandomCrop(object):
“”"Crop randomly the image in a sample.

Args:
    output_size (tuple or int): Desired output size. If int, square crop
        is made.
"""

def __init__(self, output_size=(160,160)):
    assert isinstance(output_size, (int, tuple))
    if isinstance(output_size, int):
        self.output_size = (output_size, output_size)
    else:
        assert len(output_size) == 2
        self.output_size = output_size

def __call__(self, sample):
    video_x, video_label = sample['video_x'], sample['video_label']

    h, w = video_x.shape[1],video_x.shape[2]
    new_h, new_w = self.output_size

    top = np.random.randint(0, h - new_h)
    left = np.random.randint(0, w - new_w)
     
    new_video_x=np.zeros((16,new_h,new_w,3))
    for i in range(16):
        image=video_x[i,:,:,:]
        image = image[top: top + new_h,left: left + new_w]
        new_video_x[i,:,:,:]=image

    return {'video_x': new_video_x, 'video_label': video_label}

class ToTensor(object):
“”“Convert ndarrays in sample to Tensors.”""

def __call__(self, sample):
    video_x, video_label = sample['video_x'], sample['video_label']

    # swap color axis because
    # numpy image: batch_size x H x W x C
    # torch image: batch_size x C X H X W
    video_x = video_x.transpose((0, 3, 1, 2))
    video_x=np.array(video_x)
    video_label = [video_label]
    return {'video_x':torch.from_numpy(video_x),'video_label':torch.FloatTensor(video_label)}

class UCF101(Dataset):
“”“UCF101 Landmarks dataset.”""

def __init__(self, info_list, root_dir, transform=None):
    """
    Args:
        info_list (string): Path to the info list file with annotations.
        root_dir (string): Directory with all the video frames.
        transform (callable, optional): Optional transform to be applied
            on a sample.
    """
    self.landmarks_frame = pd.read_csv(info_list,delimiter=' ', header=None)
    self.root_dir = root_dir
    self.transform = transform
        
def __len__(self):
    return len(self.landmarks_frame)

# get (16,240,320,3)
def __getitem__(self, idx):
    video_path = os.path.join(self.root_dir,self.landmarks_frame.iloc[idx, 0])
    video_label=self.landmarks_frame.iloc[idx,1]
    video_x=self.get_single_video_x(video_path)
    sample = {'video_x':video_x, 'video_label':video_label}

    if self.transform:
        sample = self.transform(sample)
    return sample


def get_single_video_x(self,video_path):
    slash_rows=video_path.split('.')
    dir_name=slash_rows[0]
    video_jpgs_path=os.path.join(self.root_dir,dir_name)
    # get the random 16 frame
    data=pd.read_csv(os.path.join(video_jpgs_path,'n_frames'),delimiter=' ',header=None)
    frame_count=data[0][0]
    video_x=np.zeros((16,240,320,3))

    image_start=random.randint(1,frame_count-17)
    image_id=image_start
    for i in range(16):
        s="%05d" % image_id
        image_name='image_'+s+'.jpg'
        image_path=os.path.join(video_jpgs_path,image_name)
        tmp_image = io.imread(image_path)
        video_x[i,:,:,:]=tmp_image
        image_id+=1
    return video_x

if name==‘main’:
#usage
root_list=’/home/hl/Desktop/lovelyqian/CV_Learning/UCF101_jpg/’
info_list=’/home/hl/Desktop/lovelyqian/CV_Learning/UCF101_TrainTestlist/trainlist01.txt’
myUCF101=UCF101(info_list,root_list,transform=transforms.Compose([ClipSubstractMean(),Rescale(),RandomCrop(),ToTensor()]))

dataloader=DataLoader(myUCF101,batch_size=8,shuffle=True,num_workers=8)
for i_batch,sample_batched in enumerate(dataloader):
    print (i_batch,sample_batched['video_x'].size(),sample_batched['video_label'].size())

整个代码不管是在逻辑清晰度还是代码行数上都比之前的改进了很多,所以还是要多多学习大佬的框架,当然能自己实现一遍也是被有韵味的啦。

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: PyTorch是一个开源的机器学习库,内置丰富的函数和工具包用于数据集加载数据处理、模型构建、训练和评估。数据集是机器学习模型的重要组成部分,PyTorch提供了多种方法用于加载数据集,包括内置的函数和可定制的方法,让用户可以根据自己的需求和数据集特性来选择适合的方式。 内置函数 PyTorch提供了内置的函数用于加载常见的数据集,如MNIST、CIFAR-10、ImageNet等。这些函数通常包括下载数据集、转换为Tensor格式、划分为训练集和测试集等步骤,使用简单方便,适合快速上手使用。 可定制方法 如果内置函数不能满足需求,PyTorch也提供了许多可定制的方法。最常用的是Dataset和DataLoader类。Dataset类是抽象类,用户需要继承这个类并实现getitem和len方法来定义自己的数据集。DataLoader类用于生成一个迭代器,用户可以设置批量大小、并行加载、随机采样等参数。 除此之外,PyTorch还提供了其它一些用于数据集处理的工具,如transforms模块、Sampler类、collate_fn函数等,可以用于数据增强、数据集分块和数据集拼接等场景。 总结 PyTorch提供了内置函数和可定制方法用于加载数据集,用户可以根据自己的需求和数据集特性来选择适合的方式。使用内置函数可以快速上手,使用可定制方法可以更加灵活和高效。对于多样化的数据集PyTorch还提供了多个处理工具,可以用于数据增强、数据集分块和数据集拼接等场景。 ### 回答2: PyTorch是一种基于Python的开源机器学习库,它可以用于构建各种机器学习模型。在PyTorch中,数据集加载是一个非常重要的部分,因为机器学习模型需要大量的数据来进行训练。 在PyTorch中,数据集加载可以通过DataLoader类来实现。DataLoader是一个Python迭代器,它可以加载大量的数据集,并将其分成小批量进行训练。这样可以避免一次性将整个数据集加载到内存中,从而节省内存空间。 首先,我们需要将数据集加载到内存或磁盘中,并将其转换为PyTorch数据集类的对象。PyTorch提供了两种数据集类:Dataset和IterableDataset。其中,Dataset类是一种基于索引的数据集类,它可以通过索引来访问数据集中的每个数据样本;而IterableDataset是一种基于迭代器的数据集类,它可以像Python中的迭代器一样使用。 然后,我们可以使用DataLoader类来加载数据集。DataLoader类有很多参数,包括batch_size(表示每个小批量包含的样本数)、shuffle(表示是否随机打乱数据集顺序)、num_workers(表示使用多少个工作线程来加载数据集)等。 在使用DataLoader类加载数据集时,我们可以通过for循环来迭代数据集中的每个小批量,并将其传递给机器学习模型进行训练。 总之,PyTorch数据集加载是非常灵活和易于使用的。通过使用DataLoader类和PyTorch提供的数据集类,我们可以轻松地加载处理大量的数据集,并将其用于训练各种机器学习模型。 ### 回答3: Pytorch是一个使用Python作为开发语言的深度学习框架,提供了非常强大的数据加载和预处理工具。在Pytorch中,数据集加载主要通过两个类来实现,分别是Dataset和DataLoader。Dataset类负责加载处理数据集,而DataLoader类则负责将处理后的数据安装指定的batch_size分批加载到内存中,避免了内存不足的问题。 Dataset类是一个抽象类,需要根据具体的数据集来实现其中的方法。一般而言,Dataset类中需要实现__len__()方法和__getitem__()方法,分别用来获取数据集的长度和获取具体的数据样本。 DataLoader类则负责对数据集进行batch处理,这样可以充分利用系统的存储和计算资源,提高了模型的训练速度。在使用DataLoader时,需要指定batch_size、shuffle和num_workers等参数,其中num_workers可以指定使用多少个进程来装载数据,从而进一步提高了数据装载的效率。 在数据集加载过程中,可以使用Pytorch提供的transforms模块来进行数据的预处理,如改变图像尺寸、随机翻转、归一化等操作,从而增加模型的泛化能力和准确性。 总之,Pytorch数据集加载和预处理方面提供了非常强大的工具,只需要实现一些简单的代码,就能轻松地完成数据加载和预处理,从而为模型的训练和测试提供了坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值