参考自:李沐动手学深度学习V2-实战 Kaggle 比赛:图像分类 (CIFAR-10)和代码实现_李沐 动手学深度学习 kaggle-CSDN博客
2.数据集预处理
2.1
def read_csv_data(fname):
with open(fname,'r') as f:
lines = f.readlines()[1:]
#读取文件中每一行数据,获取数据集的标签和对应的图片索引号,需要去除第一行标题名称
tokens = [line.rstrip().split(',') for line in lines]
return dict(((name,label) for name,label in tokens))
labels = read_csv_data(os.path.join(data_dir,'trainLabels.csv'))
print('样本数:',len(labels))
print('类别数:',len(set(labels.values())))
代码解读:
lines = f.readlines()[1:]
lines是列表类型的数据。
tokens = [line.rstrip().split(',') for line in lines]
- 是列表推导式的写法,可以先写函数,再写for循环 需要加[]
- rstrip() 去除字符串末尾的字符(默认是空格)
- split(',') 将字符串以,为分隔符隔开为多个字符串,作为一个列表。举例为['a,b']->['a','b']
- 经过处理后该数据变为了二维列表
return dict(((name,label) for name,label in tokens))
字典样式
os.path.join(data_dir,'trainLabels.csv')
2.2
# 定义一个函数copy_file,用于将源文件复制到指定文件夹下
def copy_file(fname, target_dir):
# 创建目标文件夹,如果目标文件夹已经存在,则不重复创建
os.makedirs(name=target_dir, exist_ok=True)
# 将源文件复制到指定文件夹下
shutil.copy(fname, target_dir)
# 定义一个函数split_copy_train_valid,用于从训练集中拆分一部分图片用作验证集,并将图片复制到指定文件夹下
def split_copy_train_valid(data_dir, labels, split_to_valid_ratio):
# 统计每个类别在训练集中出现的次数,并从大到小排列,获取最少出现的类别数目
split_num = collections.Counter(labels.values()).most_common()[-1][1]
# 计算从训练集中每一类需要选出多少个样本作为验证集
num_valid_per_label = max(1, math.floor(split_num * split_to_valid_ratio))
valid_label_count = {}
for train_file in os.listdir(os.path.join(data_dir, 'train')):
# 获取当前图片的标签
label = labels[train_file.split('.')[0]]
train_file_path = os.path.join(data_dir, 'train', train_file)
absolute_path = os.path.join(data_dir, 'train_valid_test')
# 复制训练集的图片到'train_valid'文件夹下
copy_file(train_file_path, os.path.join(absolute_path, 'train_valid', label))
if label not in valid_label_count or valid_label_count[label] < num_valid_per_label:
# 复制训练集的图片到'valid'文件夹下
copy_file(train_file_path, os.path.join(absolute_path, 'valid', label))
valid_label_count[label] = valid_label_count.get(label, 0) + 1
else:
# 复制训练集的图片到'train'文件夹下
copy_file(train_file_path, os.path.join(absolute_path, 'train', label))
return num_valid_per_label
# 定义一个函数copy_test,用于将测试集的图片复制到指定文件夹下
def copy_test(data_dir):
for test_file in os.listdir(os.path.join(data_dir, 'test')):
# 复制测试集的图片到'test'文件夹下,标签为'unknown'
copy_file(os.path.join(data_dir, 'test', test_file), os.path.join(data_dir, 'train_valid_test', 'test', 'unknown'))
# 定义一个函数copy_cifar10_data,用于执行整个数据处理过程,包括拆分训练集、复制训练集和测试集
def copy_cifar10_data(data_dir, split_to_valid_ratio):
# 读取训练集标签数据
labels = read_csv_data(fname=os.path.join(data_dir, 'trainLabels.csv'))
# 拆分训练集并复制到指定文件夹下
split_copy_train_valid(data_dir, labels, split_to_valid_ratio)
# 复制测试集到指定文件夹下
copy_test(data_dir)
# 定义一个批次大小变量,如果是演示模式,则批次大小为32,否则为128
batch_size = 32 if demo else 128
# 定义训练集与验证集的比例
split_to_valid_ratio = 0.1
# 执行数据处理过程
copy_cifar10_data(data_dir, split_to_valid_ratio)