机器学习入坑指南(十):猫狗大战之数据集准备

猫狗大战是 kaggle 的一个著名比赛项目,即编写一个算法使机器能够区分猫和狗(图片)。前面我们已经尝试过使用深度学习的方法识别手写数字图片,效果似乎还不错,稍加改进,就可以应用到这个问题上。

对于机器学习来讲,数据的重要性甚至大于算法。之间已经讨论过数据预处理的问题,但猫狗大战使用的数据集是图像,在方法上有一些区别,所以单独再拿出来说一下。

内容参考自:Python Programming Tutorials,我后续的深度学习内容也是基于这个教程,等不及更新的小伙伴可以直接看原版~

1 获取数据

「点击从微软官方下载猫狗大战数据集」

下载完成后,把它解压到合适的位置。文件夹的结构是:

PetImages
┣ Cat
┗ Dog

2 reshape

猫和狗的图片被分到了不同的子文件夹中。打开观察,发现这些图片的大小并不一样。想想之前的神经网络,输入的维度最好是相同的。所以我们需要把图片 reshape 一下,顺便把颜色丢掉以减少数据量(灰度图像足够识别猫狗了)。

这里需要用到新的模块,opencv,可以使用 pip install opencv-python 安装。

先读进来一张图片:

import numpy as np
import matplotlib.pyplot as plt
import os
import cv2
from tqdm import tqdm

DATADIR = "X:/Datasets/PetImages"

CATEGORIES = ["Dog", "Cat"]

for category in CATEGORIES:
    path = os.path.join(DATADIR,category)
    for img in os.listdir(path): 
        img_array = cv2.imread(os.path.join(path,img) ,cv2.IMREAD_GRAYSCALE)  # 把图片读取为数组
        plt.imshow(img_array, cmap='gray')  # 使用灰度图
        plt.show()  
        break  # 这里先拿一个图片测试,所以 break 两次
    break  

在这里插入图片描述
看看这个图片的大小:

print(img_array.shape)

(398, 500)

扫描二维码关注公众号,回复: 8795342 查看本文章

这个图片的大小是 398x500,我们尝试把它缩小到 50x50:

IMG_SIZE = 50

new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))
plt.imshow(new_array, cmap='gray')
plt.show()

在这里插入图片描述
感觉有些模糊,再试试 100x100
在这里插入图片描述
嗯,这个 OK。接下来我们就可以创建训练集和测试集了。

3 分割数据集

这里需要手动创建一个测试集的文件夹,命名为 Testing,子文件夹仍为 CatDog。然后,从之前的文件夹里分别剪切 (不能复制,否则不能用于测试)15 个图片到两个文件夹中。

接下来,创建训练集:

training_data = []

def create_training_data():
    for category in CATEGORIES:  

        path = os.path.join(DATADIR,category)  
        class_num = CATEGORIES.index(category)  
        
        for img in tqdm(os.listdir(path)):  
            try:
                img_array = cv2.imread(os.path.join(path,img) ,cv2.IMREAD_GRAYSCALE)  
                new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE)) 
                training_data.append([new_array, class_num])  # 把图片数组和分类标签加入数据集
            except Exception as e: 
                pass
                
create_training_data()

print(len(training_data))

100%|███████████████████████████████████| 12486/12486 [00:46<00:00, 267.07it/s]
100%|███████████████████████████████████| 12486/12486 [01:00<00:00, 205.21it/s]
24916

运行后,训练集就创建好啦!这里我们的猫狗图片在数量上是均衡的,如果一个数据集里绝大多数都是狗的照片,显然机器会选择把一切都识别成狗。还有另外一个问题,我们的数据集如果一开始是猫,而后来全是狗,那机器仍然会把所有图片识别成狗。所以我们需要打乱数据的分布顺序:

import random

random.shuffle(training_data)

之后可以验证一下,查看训练集前 10 个数据的标签:

for sample in training_data[:10]:
    print(sample[1])

0
1
0
1
1
0
0
0
1
0

4 创建并保存模型

数据已经准备好了,并被分割成为了训练集和测试集,接下来我们需要把它们读进模型中并保存,方便之后的使用。

X = []
y = []

for features,label in training_data:
    X.append(features)
    y.append(label)

X = np.array(X).reshape(-1, IMG_SIZE, IMG_SIZE, 1)

# 保存模型
import pickle

pickle_out = open("X.pickle","wb")
pickle.dump(X, pickle_out)
pickle_out.close()

pickle_out = open("y.pickle","wb")
pickle.dump(y, pickle_out)
pickle_out.close()

当我们需要使用它的时候,可以使用以下代码:

pickle_in = open("X.pickle","rb")
X = pickle.load(pickle_in)

pickle_in = open("y.pickle","rb")
y = pickle.load(pickle_in)

至此,数据方面的准备已经做好了,在下一篇文章中,我们将尝试使用数据集训练卷积神经网络来实现识别猫狗的目的。

发布了49 篇原创文章 · 获赞 1332 · 访问量 40万+

猜你喜欢

转载自blog.csdn.net/Neuf_Soleil/article/details/83957756