本文从dog种类kaggle开始着手,其中包含各种详细说明,并在文章最后附上补充条目。
目录
1.dog_kaggle
1.1图像分类数据集准备
在kaggle中,下载得到的文件是这个样的:(当然这个train_valid_test是后面建的)其中这个csv文件里面有两列信息,第一列是图片名称,第二列是该图片对应的label。第一列中的图片随机的分布在test和train这两个文件夹中。

目的:
在图像分类dataset中,最简单的加载方法就是建立一个文件夹,其中有若干个以label命名的文件夹,每个label文件夹中包含着都是该label的图片。那么目的有了,让我们来实现:
首先,读取上述的csv文件,并生成一个dict(pic_name,pic_label),这里注意,dict生成字典里面的key必须是不可更改的数据结构,像list就不行,这里两个都是str,故可以。
data_dir = '/CV/xhr/kaggle_cifar10_tiny/kaggle_cifar10_tiny'
def read_csv_labels(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_labels(os.path.join(data_dir, 'trainLabels.csv'))
print('# 训练样本 :', len(labels))
print('# 类别 :', len(set(labels.values())))
'''
训练样本: 1000
类别数量: 120
'''
再分别创建三个文件夹,进行对原图片复制的操作。
首先先定义一个复制文件的函数:
def copyfile(filename, target_dir):
os.makedirs(target_dir, exist_ok=True)
shutil.copy(filename, target_dir)
函数解析:exist_ok=True表示若要创建的目录已经存在,则不会报错直接返回,若设置为False,则会返回FileExistsError。
shutil是一个包,里面的.copy函数是将文件从原路径filename复制到目标路径target_dir。注意,在此移动函数中,原文件是到具体的某一张图片,目标路径targer_dir可以指向某一个文件夹,这样前面不同的filename都会挪到同一个文件夹中。

再定义重头戏:创建并挪图片!
def reorg_train_valid(data_dir, labels, valid_ratio):
n = collections.Counter(labels.values()).most_common()[-1][1]
n_valid_per_label = max(1, math.floor(n * valid_ratio))
label_count = {}
for train_file in os.listdir(os.path.join(data_dir, 'train')):
label = labels[train_file.split('.')[0]] # 得到每个图片名(除后缀),
# 然后通过labels字典里面key索引
# 这个label是图片的种类标签
fname = os.path.join(data_dir, 'train', train_file)
copyfile(fname, os.path.join(data_dir, 'train_valid_test',
'train_valid', label))
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
else:
copyfile(fname, os.path.join(data_dir, 'train_valid_test',
'train', label))
return n_valid_per_label
1.其中collections.Counter用于计算元素在一个可迭代对象中出现的次数,并返回一个Counter对象,键是元素,值是元素出现的次数。
2.most_common()方法返回一个列表,其中列表里面包含(value,num)的元组,分别记录出现的value是什么,出现了多少次,由最多到最低排列。
3.[-1][1]则返回的是出现次数最少的value对应的最少次数。
在此做了一个demo:
import collections
labels = {'a': 1, 'b': 2, 'c': 1, 'd': 3, 'e': 1, 'f': 2} # 示例字典
print(labels['a'])
# 统计每个元素出现的次数,并返回出现次数最少的元素的出现次数
n = collections.Counter(labels.values())
print(n)
n1 = collections.Counter(labels.values()).most_common()
print(n1)
n2 = collections.Counter(labels.values()).most_common()[-1][1]
print(n2)
'''
1
Counter({1: 3, 2: 2, 3: 1})
[(1, 3), (2, 2), (3, 1)]
1
'''
4.这里返回最少出现的种类的出现频次n,是在设定验证集占训练集比值r后,验证集为每个类别拆分出max([nr],1)张图像.
5.其中,[nr]是向下取整,如果是1.6则取1
6.这个循环中,os.listdir(path)是返回该路径下所有的文件名字,在这里train_file是train文件下所有图片的名字
7.label返回的是每个train_file(train文件中的一张图片)的类别名字(labels字典里面对应key的value),这里labels传入的是前面生成的dict(pic_name,pic_label),这里通过索引字典的key

最低0.47元/天 解锁文章
2461

被折叠的 条评论
为什么被折叠?



