以猫狗分类, 讲述深度学习的分类算法.
Cat and Dog
第 1 部分, 数据集, 包括:
下载数据集: 使用 Kaggle API 下载数据集;
预处理数据集: 将数据集划分为训练和测试两部分;
展示数据集: 使用 Pillow 绘制多幅图片的组合;
下载
数据集: https://www.kaggle.com/c/dogs-vs-cats/data
Data
使用 Kaggle API 进行下载, GitHub https://github.com/Kaggle/kaggle-api , 命令如下:
kaggle competitions download -c dogs-vs-cats
Kaggle API
下载数据集:
Download
训练集: 25000 张图片, 12500 张猫, 12500 张狗;
测试集: 12500 张图片, 没有区分类别;
关于 Kaggle API 的配置:
登录账号, 在 My Account 页面的 API 项目中, 点击
Create New API Token
, 下载 kaggle.JSON,JSON 中包含 username 和 key.
kaggle.JSON
将 kaggle.JSON 放置入. kaggle 文件夹, 如果不存在, 则需要创建文件夹.
修改 kaggle.JSON 为可读权限, 即 chmod 600 .kaggle/kaggle.JSON.
安装 Kaggle API, 即 pip install kaggle.
执行下载命令, 如 kaggle competitions download -c dogs-vs-cats.
预处理
将 1000 张猫和 1000 张狗作为训练集, 将 400 张猫和 400 张狗作为测试集.
第一步: 将数据集读入内存, 区分猫和狗两部分.
- def list_dataset(dataset_dir):
- """
- 将训练数据集读入内存, 分为猫和狗两部分
- """
- paths_list, names_list = traverse_dir_files(dataset_dir)
- cats_dict, dogs_dict = dict(), dict()
- for path, name in zip(paths_list, names_list):
- [clz, num, _] = name.split('.')
- num = int(num)
- if clz == 'cat':
- cats_dict[num] = path
- elif clz == 'dog':
- dogs_dict[num] = path
- else:
- continue
- # print('cat: {}, dog: {}'.format(len(cats_dict.keys()), len(dogs_dict.keys())))
- return cats_dict, dogs_dict
第二步: 复制数据集, 将若干张猫或狗, 复制到新的文件夹.
- def copy_files(target_folder, clz_name, n_start, n_end):
- cats_dict, dogs_dict = list_dataset(O_DATASET_DIR)
- new_train = os.path.join(DATASET_DIR, 'train')
- new_test = os.path.join(DATASET_DIR, 'test')
- mkdir_if_not_exist(DATASET_DIR)
- mkdir_if_not_exist(new_train)
- mkdir_if_not_exist(new_test)
- # 测试数据
- # target_folder = 'train'
- # clz_name = 'cat'
- # n_start = 0
- # n_end = 10
- for i in range(n_start, n_end):
- data_dict = cats_dict if clz_name == 'cat' else dogs_dict
- folder = new_train if target_folder == 'train' else new_test
- shutil.copy(data_dict[i], folder)
- print("[完成] 目标文件夹: {}, 类别: {}, 起止: {} ~ {}".format(
- target_folder, clz_name, n_start, n_end))
第三步: 构建 1000 张猫 + 1000 张狗训练集, 400 张猫 + 400 张狗测试集.
- def main():
- # 1000 张猫 + 1000 张狗训练集; 400 张猫 + 400 张狗测试集
- copy_files('train', 'cat', 0, 1000)
- copy_files('train', 'dog', 0, 1000)
- copy_files('test', 'cat', 0, 400)
- copy_files('test', 'dog', 0, 400)
展示
将多张图片组合成一张图片, 其中每张图片保持比例, 最长边为 416, 使用 Pillow 的 Image 库.
- def draw_multi_imgs(path_list, file_name):
- """
- 绘制相似图片组
- :param path_list: 图片路径列表
- :param file_name: 输出文件名
- :return: None
- """
- img_w, img_h = 4, 3
- img_size = 416
- try:
- o_images = [Image.open(p) for p in path_list]
- images = []
- for img in o_images:
- wp = img_size / float(img.size[0])
- hsize = int(float(img.size[1]) * float(wp))
- img = img.resize((img_size, hsize), Image.ANTIALIAS)
- images.append(img)
- except Exception as e:
- print('Exception: {}'.format(e))
- return
- new_im = Image.new('RGB', (img_size * img_w, img_size * img_h), color=(255, 255, 255))
- x_offset, y_offset = 0, 0
- for i in range(img_h):
- for j in range(img_w):
- im = images[i * img_w + j]
- new_im.paste(im, (x_offset, y_offset))
- x_offset += 416
- y_offset += 416
- x_offset = 0
- new_im.save(file_name) # 保存图片
展示训练集中随机的 12 张猫图片, 和 12 张狗图片.
- def main():
- new_train = os.path.join(DATASET_DIR, 'train')
- new_test = os.path.join(DATASET_DIR, 'test')
- cats_dict, dogs_dict = list_dataset(new_train)
- cats_list = list(cats_dict.values())
- dogs_list = list(dogs_dict.values())
- random.shuffle(cats_list)
- random.shuffle(dogs_list)
- draw_multi_imgs(cats_list[:12], os.path.join(DATA_DIR, 'train_cat.jpg'))
- draw_multi_imgs(dogs_list[:12], os.path.join(DATA_DIR, 'train_dog.jpg'))
数据集:
cats
dogs
至此, 完成构建数据集.
来源: http://www.jianshu.com/p/9b2cba26e4a7