d2l第13章的两个kaggle,以及该章的aug,finetune,cls的dataset处理

本文从dog种类kaggle开始着手,其中包含各种详细说明,并在文章最后附上补充条目。

目录

1.dog_kaggle

1.1图像分类数据集准备

 目的:

1.2图像增广

1.3加载数据集,dataset与dataloader

1.4模型net搭配--迁移学习finetune

1.5训练--学习率下降操作:

1.6预测与输出结果

2.探索--finetune

2.1修改fc

2.2自定义修改与添加xavier初始化参数:

 2.3封锁层的优化参数

2.4直观对比


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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值