以貓狗分類,講述深度學(xué)習(xí)的分類算法。

Cat and Dog
第1部分,數(shù)據(jù)集,包括:
- 下載數(shù)據(jù)集:使用Kaggle API下載數(shù)據(jù)集;
- 預(yù)處理數(shù)據(jù)集:將數(shù)據(jù)集劃分為訓(xùn)練和測試兩部分;
- 展示數(shù)據(jù)集:使用Pillow繪制多幅圖片的組合;
下載
數(shù)據(jù)集:https://www.kaggle.com/c/dogs-vs-cats/data

Data
使用Kaggle API進(jìn)行下載,GitHub,命令如下:
kaggle competitions download -c dogs-vs-cats

Kaggle API
下載數(shù)據(jù)集:

Download
訓(xùn)練集:25000張圖片,12500張貓,12500張狗;
測試集:12500張圖片,沒有區(qū)分類別;
關(guān)于Kaggle API的配置:
- 登錄賬號,在
My Account頁面的API項(xiàng)目中,點(diǎn)擊Create New API Token,下載kaggle.json,json中包含username和key。

kaggle.json
將kaggle.json放置入.kaggle文件夾,如果不存在,則需要?jiǎng)?chuàng)建文件夾。
修改kaggle.json為可讀權(quán)限,即
chmod 600 .kaggle/kaggle.json。安裝Kaggle API,即
pip install kaggle。執(zhí)行下載命令,如
kaggle competitions download -c dogs-vs-cats。
預(yù)處理
將1000張貓和1000張狗作為訓(xùn)練集,將400張貓和400張狗作為測試集。
第一步:將數(shù)據(jù)集讀入內(nèi)存,區(qū)分貓和狗兩部分。
def list_dataset(dataset_dir):
"""
將訓(xùn)練數(shù)據(jù)集讀入內(nèi)存,分為貓和狗兩部分
"""
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
第二步:復(fù)制數(shù)據(jù)集,將若干張貓或狗,復(fù)制到新的文件夾。
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)
# 測試數(shù)據(jù)
# 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("[完成]目標(biāo)文件夾: {}, 類別: {}, 起止: {} ~ {}".format(
target_folder, clz_name, n_start, n_end))
第三步:構(gòu)建1000張貓+1000張狗訓(xùn)練集、400張貓+400張狗測試集。
def main():
# 1000張貓+1000張狗訓(xùn)練集;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) # 保存圖片
展示訓(xùn)練集中隨機(jī)的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'))
數(shù)據(jù)集:

cats

dogs
至此,完成構(gòu)建數(shù)據(jù)集。