python深度学习图像处理CSV文件分类标签图片到各个文件夹
最近在学习沐神的深度学习课程,由于一直用的C++,python快忘光了,下面是用python处理CSV数据分类文件夹,主要代码参考李沐的深度学习代码
以一个树叶分类的数据集作例子,数据集在这儿下载简单讲解一下怎样用python将数据分类存入相应文件夹
我们下载的数据集为下图形式。images中为训练集和测试集图片,其他分别有test,train,和一个提交的模板三个csv文件
images长这样处理后会是这种,每一类的图片放在一个文件夹中
导入库
import os import math import shutil import collections import torch import torchvision
读取csv文件
读取train.csv
将文件位置存储在
data_dir = '/home/aries/d2l-zh/pytorch/classify-leaves' fname = os.path.join(data_dir, 'train.csv')
采用with打开文件
with open(fname, 'r') as f: lines = f.readlines()[1:] #从1开始,,去掉跳过文件头行 (列名)
line的内容如下
lines中有图片的地址和对应的标签。
我们将lines中每一个数据集去掉空格,并分开每个,列表存入,最后放在一个字典中返回(字典最后可以根据图片地址找到相应的标签)
下面是整个的代码
def read_csv_train(fname): """读取 `fname` 来给标签字典返回一个文件名。""" with open(fname, 'r') as f: # 跳过文件头行 (列名) lines = f.readlines()[1:] tokens = [l.rstrip().split(',') for l in lines] #去掉空格,并分开每个训练图片,列表存入 return dict(((name, label) for name, label in tokens)) #字典返回返回
labels = read_csv_train(os.path.join(data_dir, 'train.csv'))
labels的内容如下读取test.csv
同train一样with读取csv文件,但是test的内容和train不一样,里面没有标签,如下
fname = os.path.join(data_dir, 'test.csv') with open(fname, 'r') as f: # 跳过文件头行 (列名) lines = f.readlines()[1:]
所以建立read_csv_test函数是只需要返回列表就行了
def read_csv_test(fname): with open(fname, 'r') as f: # 跳过文件头行 (列名) lines = f.readlines()[1:] tokens = [l.rstrip().split(',') for l in lines] return tokens
test_data = read_csv_test(os.path.join(data_dir, 'test.csv'))
test_data内容如下:
读取并分类图片文件分为测试集、训练集、验证集、和train_valid
train_valid这里面包含分开的训练集和验证集(就是最开始训练集),最后参数调好了,用这个训练
假设验证集的个数为10%
valid_ratio = 0.1
下面先把整个程序贴上
reorg_train_valid(data_dir, labels, test_data, valid_ratio)
def copyfile(filename, target_dir): """将文件复制到目标目录。""" os.makedirs(target_dir, exist_ok=True) #exist_ok:是否在目录存在时触发异常。如果exist_ok为False(默认值), #则在目标目录已存在 的情况下触发FileExistsError异常; #如果exist_ok为True,则在目标目录已存在的情况下不会触发FileExistsError异常。 shutil.copy(filename, target_dir)#复制文件内容 #@save def reorg_train_valid(data_dir, labels, test_data, valid_ratio): # 训练数据集中示例最少的类别中的示例数 n = collections.Counter(labels.values()).most_common()[-1][1]#[-1] 是最少的类别,如果[0]是最大的类别; #最后的[1]则是返回值,如果是[0] 则返回个数 # 验证集中每个类别的示例数 n_valid_per_label = max(1, math.floor(n * valid_ratio)) label_count = {} for train_file in os.listdir(os.path.join(data_dir, 'images')): fname = os.path.join(data_dir, 'images/', train_file) if ['images/' + train_file] in test_data: #如果图片地址在测试集的列表中 copyfile( fname, os.path.join(data_dir, 'train_valid_test', 'test', 'unknown'))#将测试集也一一复制过来#测试集不知道标签,即为unknow else : #if labels.__contains__('images/' + train_file)如果图片的地址在训练集的字典中 label = labels['images/' + train_file]#取文件名,处理后的值作为labels的索引,即key值 copyfile( fname, os.path.join(data_dir, 'train_valid_test', 'train_valid', label))#复制到train_valid中, if label not in label_count or label_count[label] < n_valid_per_label: copyfile( fname, os.path.join(data_dir, 'train_valid_test', 'valid', label))#复制到交叉验证集的文件中 label_count[label] = label_count.get(label, 0) + 1#字典中get返回指定Key的值,如果key不存在则返回后面的参数,即0 else: copyfile( fname, os.path.join(data_dir, 'train_valid_test', 'train', label))#复制到train中 return n_valid_per_label
通过执行上面的程序我们就可以得到相应的分类好的文件夹train_valid_test
其中包含以下4个文件夹
train中每个标签的相应图片已经分好了(验证集valid,train_valid_test也一样)
文章代码参考李沐的深度学习的代码