CNN(Pytorch版)实现GTA5的自动驾驶——第三节(数据集的及dataloader的实现)

第三方库安装

如果是conda

conda install -c conda-forge imgaug
conda install -c conda-forge albumentations

如果是pip

pip install -U albumentations

数据集下载

因为跑模型需要的数据量很大,自己去做数据集比较费时。我在Kaggle里看到了有人把数据集进行共享,大概有20G的数据。Kaggle链接

但是下载需要操作一番,我本来想下载然后上传百度云之类的,联系了作者说明了意图,他也没回我,所以等他回我的时候我再补百度云的链接吧,这之前还是需要去Kaggle官网下载

数据集的查看

文件下包含多个npy文件

对于每一个npy文件,我们可以用numpy进行加载查看. 以upgraded-balanced-data-v3-1.npy为例
import numpy as np
npy_path = "你的保存数据集的文件/upgraded-balanced-data-v3-1.npy"
nd_arrays = np.load(npy_path, allow_pickle=True)
print(nd_arrays.shape)

输出如下:(135, 2) # 有135行,2列数据

以打开第一行为例

line = nd_arrays[0,:] # 读取第一行的数据集
line_a, line_b = line[0], line[1] # 第一行的第一个数据,第一行的第二个数据
print(line_a.shape)
print(line_b)

输出如下:(270, 480, 3) [1, 0, 0, 0, 0, 0, 0, 0, 0] #说明对于每一行数据,0号索引元素是rgb的图片,1号索引是一个独热码(可以暂时不管)

显示图片

#PIL
img = Image.fromarray(line_a)
#RGB  
img.show()

结果如下:

至此,我们了解了数据形式,我以伪码进行解释

for npy 在所有的npy文件:
    for line 在该npy的行:
        x = line[0]  #即上方的图片
        y = line[1]  #即上方的独热码

再单独解释下为什么有独热码

  • 以猫狗分类为例
    1.我们有一张狗的图片(称为X),还有这张图片对应的标签:狗(称为Y)
    2.我们需要让模型学习:见到一张狗的图片——>反应出来这是狗

  • 以该项目为列
    1.我们有一张当前驾驶的图片(称为X),还有这张图片对应的标签:前进后退等等(称为Y)
    2.当然:现实世界的驾驶行为很复杂,在该项目中,我们只用9个驾驶行为(前进,后退,左转,右转等等),这里每一个驾驶行为对应一个独热码

DataSet的编写

# 解析独热码
encode_dice = {"[0, 0, 0, 0, 0, 0, 0, 0, 1]": 0,
               "[0, 0, 0, 0, 0, 0, 0, 1, 0]": 1,
               "[0, 0, 0, 0, 0, 0, 1, 0, 0]": 2,
               "[0, 0, 0, 0, 0, 1, 0, 0, 0]": 3,
               "[0, 0, 0, 0, 1, 0, 0, 0, 0]": 4,
               "[0, 0, 0, 1, 0, 0, 0, 0, 0]": 5,
               "[0, 0, 1, 0, 0, 0, 0, 0, 0]": 6,
               "[0, 1, 0, 0, 0, 0, 0, 0, 0]": 7,
               "[1, 0, 0, 0, 0, 0, 0, 0, 0]": 8}
# 上一小节定义的conf类
cf = config()
# 实现效果,返回单个npy文件的数据
class MyDataSet(Dataset):
    def __init__(self, npy_file, transform=None, base_path=cf.BASE_PATH, is_train=True):
        # 如果transform为none
        if transform is None:
            transform = A.Compose([ToTensorV2()]) # 使用albumentations库进行数据增强
        self.Base_Path = base_path  # 保存npy文件的根目录
        self.transform = transform 
        self.arrays = np.load(npy_file, allow_pickle=True)  #进行加载数据

    def __len__(self):
        return self.arrays.shape[0]

    def __getitem__(self, index):
        # 要获取index的图像
        need_image = self.arrays[index, 0]
        # 要获取index的y
        need_target = self.arrays[index, 1]
        # 用 albumentations 进行数据增强,会把通道放到前面
        need_image = self.transform(image=need_image)['image']
        # target变成tensor
        need_target = encode_dice.get(str(need_target)) #根据独热码对按键解析
        need_target = torch.tensor(need_target)
        datas = [need_image, need_target] # data的0号元素是驾驶图片,1号元素是驾驶行为
        return datas

loader的编写

def Loaders(npy_file, is_train):
    batch_size = 64 # 一次取多少数据集
    # compose 指 对中括号中的进行pipeline处理
    train_transforms = A.Compose(
        [
            A.Resize(height=cf.HEIGHT, width=cf.HEIGHT),
            A.Normalize(),
            ToTensorV2(),
        ],
    )
    test_transforms = train_transforms
    if is_train:
        train_dataset = MyDataSet(npy_file=npy_file, transform=train_transforms, base_path=cf.BASE_PATH, is_train=True)

        loader = DataLoader(train_dataset,
                                  shuffle=False,
                                  batch_size=batch_size,
                                  num_workers=1,
                                  sampler=None
                                  )
    else:
        test_dataset = MyDataSet(npy_file=npy_file, transform=test_transforms, base_path=cf.BASE_PATH, is_train=False)
        loader = DataLoader(test_dataset,
                                 shuffle=False,
                                 batch_size=batch_size,
                                 num_workers=1
                                 )
    return loader

测试dataset是否可用

mydata = MyDataSet(npy_file='../input/gta-v-self-driving-car/final/final/upgraded-balanced-data-v3-1.npy', is_train=False)
print(mydata)
one_data = mydata[0]
x = one_data[0]
y = one_data[1]
print(x.shape)
print(y)

基于所有npy文件进行划分数据集

from sklearn.model_selection import train_test_split
import random
def split_train_and_test_npy():
    npy_list = os.listdir(cf.BASE_PATH+'data/')
    random.shuffle(npy_list)
    X_train, X_test= train_test_split(npy_list, test_size=cf.train_test_rate,
                                                        random_state=int(time.time()))
    X_train = [os.path.join(cf.BASE_PATH, 'data', i) for i in X_train]
    X_test = [os.path.join(cf.BASE_PATH, 'data', i) for i in X_test]
    print("train size:", len(X_train))
    print("test size:", len(X_test))
    return X_train, X_test
posted @ 2021-12-20 21:59  Adam_lxd  阅读(941)  评论(0编辑  收藏  举报