Cats vs. Dogs(猫狗大战)是Kaggle大数据竞赛某一年的一道赛题,利用给定的数据集,用算法实现猫和狗的识别。
数据集可以从Kaggle官网上下载或者:网盘提取码:k7ik
电脑配置环境:win10+cuda9.0+cudnn v7+anaconda+tensorflow1.8(gpu)
IDE:pycham
- 新建data文件夹下包含test和train两个子文件夹,分别用于存放测试数据和训练数据,下载的数据直接解压到相应的文件夹下即可
- logs文件夹用于存放我们训练时的模型结构以及训练参数
- input_data.py负责实现读取数据,生成批次(batch)
- model.py负责实现我们的神经网络模型
- training.py负责实现模型的训练以及评估
1. 数据的读取——input_data.py
函数get_files(file_dir)
的功能是获取给定路径file_dir
下的所有的训练数据(包括图片和标签),以list的形式返回。
由于训练数据前12500张是猫,后12500张是狗,如果直接按这个顺序训练,训练效果可能会受影响(我自己猜的),所以需要将顺序打乱,至于是读取数据的时候乱序还是训练的时候乱序可以自己选择(视频里说在这里乱序速度比较快)。因为图片和标签是一一对应的,所以要整合到一起乱序。
这里先用np.hstack()
方法将猫和狗图片和标签整合到一起,得到image_list和label_list,hstack((a,b))的功能是将a和b以水平的方式连接,比如原来cats和dogs是长度为12500的向量,执行了hstack(cats, dogs)后,image_list的长度为25000,同理label_list的长度也为25000。接着将一一对应的image_list和label_list再合并一次。temp的大小是2×25000,经过转置(变成25000×2),然后使用np.random.shuffle()
方法进行乱序。
最后从temp中分别取出乱序后的image_list和label_list列向量,作为函数的返回值。这里要注意,因为label_list里面的数据类型是字符串类型,所以加上label_list = [int(i) for i in label_list]这么一行将其转为int类型。
# coding=utf-8
import tensorflow as tf
import numpy as np
import os
train_dir = 'D:/PychamProjects/Cats_Dogs/data/train/'
def get_files(file_dir):
'''
Args:
file_dir: file directory
Returns:
list of images and labels
'''
cats = []
label_cats = []
dogs = []
label_dogs = []
for file in os.listdir(file_dir):
# name = file.split(sep='.')
name = file.split('.')
if name[0] == 'cat':
cats.append(file_dir + file)
label_cats.append(0) #获取路径下所有猫的图片路径,存放到cats,同时贴上标签0
else:
dogs.append(file_dir + file)
label_dogs.append(1)
print('There are %d cats\nThere are %d dogs' % (len(cats), len(dogs)))
#把cat dog合起来组成一个list
image_list = np.hstack((cats, dogs))
label_list = np.hstack((label_cats, label_dogs))
#利用shuuffle打乱顺序
temp = np.array([image_list, label_list])
temp = temp.transpose()
np.random.shuffle(temp)
# 从打乱的temp中再取出list(img和lab
image_list = list(temp[:, 0])
label_list = list(temp[:, 1])
label_list = [int(i) for i in label_list]
return image_list, label_list
# 裁剪图片
#将上面生成的List传入get_batch() ,转换类型,产生一个输入队列queue,因为img和lab是分开的,
#所以使用tf.train.slice_input_producer(),然后用tf.read_file()从队列中读取图像
def get_batch(image, label, image_W, image_H, batch_size, capacity):
'''
Args:
image: list type
label: list type
image_W: image width
image_H: image height
batch_size: batch size
capacity: the maximum elements in queue
Returns:
image_batch: 4D tensor [batch_size, width, height, 3], dtype=tf.float32
label_batch: 1D tensor [batch_size], dtype=tf.int32
'''
# 转换类型
# 将python.list类型转换成tf能够识别的格式
image = tf.cast(image, tf.string)
label = tf.cast(label,<