概述
猫狗大战是 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)
这个图片的大小是 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
,子文件夹仍为 Cat
、Dog
。然后,从之前的文件夹里分别剪切 (不能复制,否则不能用于测试)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)
至此,数据方面的准备已经做好了,在下一篇文章中,我们将尝试使用数据集训练卷积神经网络来实现识别猫狗的目的。
最后
以上就是勤奋八宝粥为你收集整理的机器学习入坑指南(十):猫狗大战之数据集准备2 reshape的全部内容,希望文章能够帮你解决机器学习入坑指南(十):猫狗大战之数据集准备2 reshape所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复