CNN(Pytorch版)实现GTA5的自动驾驶——第三节(数据集的及dataloader的实现)
目录
第三方库安装
- albumentations 用于数据增强的库 官方文档地址
安装:
如果是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