如果你不喜欢小猫和小狗,你可能不知道他们具体是哪一种品种,但是一般来说,你都能区分出这是猫还是狗,猫和狗的特征还是不一样的,那我们如何用机器学习的方法训练一个网络区分猫狗呢?

我们选用的是 Kaggle 的一个数据集(https://www.kaggle.com/c/dogs-vs-cats/data),用神经网络的方法进行模型的训练。下载下来的数据集对于我们测试来说数据有点大,这里面分别有 12500 个猫和狗的训练图片,我们先来缩小一下训练集,然后再进行模型的搭建和训练。我们的做法做法是猫和狗分别选择 1000 个训练图片,500 个验证集和 500 个测试集,我们可以手工完成这个工作,需要做的就是:

// 如下非可执行代码,含义非常清楚的表达,最后会附上可执行代码
mkdir dog-vs-cats-small
cp dog-vs-cats/train/cat/pic-{0-999}.jpg dog-vs-cats-small/train/cat/
cp dog-vs-cats/train/dog/pic-{0-999}.jpg dog-vs-cats-small/train/dog/
cp dog-vs-cats/validation/cat/pic-{1000-1499}.jpg dog-vs-cats-small/validation/cat/
cp dog-vs-cats/validation/dog/pic-{1000-1499}.jpg dog-vs-cats-small/validation/dog/
cp dog-vs-cats/test/cat/pic-{1500-1999}.jpg dog-vs-cats-small/test/cat/
cp dog-vs-cats/test/dog/pic-{1500-1999}.jpg dog-vs-cats-small/test/dog/

从我们前面文章的经验中,我们可以知道,这个卷积神经网络我们可以用 relu 激活的 Conv2D 层与 MaxPooling2D 层堆叠而成,与之前相比稍微需要修改就是网络的大小,更大的网络处理更多是数据。

卷积神经网络网络的深度往往与特征图的尺寸负相关,越深的网络每个特征图的尺寸往往是越小的,我看到的数据往往是:深度 32-> 128,特征图尺寸 150x150 -> 7x7。如下,这是我们构架的网络:

优化器依旧采用 RMSprop,学习率由默认的 0.001 设置为 0.0001,后续我们也将 对不同的优化器进行介绍。由于需要输出的结果是“猫 or 狗”,所以我们最后一层激活参数为 sigmoid,自然损失函数就为 binary_crossentropy 了,如此一来,网络就构建好了,接下来就应该喂给网络数据了。

由于我们这里是一张又一张的图片,jpg 格式,这可不是我们网络所喜欢的格式,需要进行处理,读出图片,将其解码为 RGB 像素,再将 RGB 中的像素值转换成浮点数进行计算,又由于我们的网络对于处理 0-1 之间的数效果更好,因此我们需要将像素值转换区间,即从 0-255 转换到 0-1,是不是觉得有点麻烦,确实!Keras 之所以说是最容易上手的深度学习框架,就是因为它同样把这些繁琐但是使用的工具内置了,Image 包下的 ImageDataGenerator 就可以帮上大忙,这样我们就可以得到 RGB 图像与二进制标签组成的批量。

接下来,我们就要对数据进行拟合了,fit_generator,上面的生成器也将传给它,这样,这一个网络我们就建立完成了,可以进行训练了,与前文一样,我们仍然画出损失曲线和精度曲线。

训练精度逐渐接近百分之百,提醒我们注意过拟合的危险;训练精度在第五次(或六次)次后就维持在 70%左右不再上升了。

第五次或第十次后,验证损失就达到了最小值,嗯……,很显然,过拟合了,我们需要降低过拟合。

出现过拟合的原因是学习样本太少了,我们采用 **数据增强 **来解决这个问题。我们的做法就是在现有的训练数据中生成更多的训练数据,就是增加一些随机变换,这种随机变化生成的图片依然要保证是有效的。这样模型在训练的时候就可以看到不同的更多的图像了,这就使得训练出的模型泛化能力更好。怎么做呢,就可以把图片进行随机的旋转,缩放,平移和翻转等,ImageDataGenerator 提供了这样的能力。同时在密集层之前添加一个 Dropout 层,会更好的降低过拟合,如此一来,看看结果:

可以看出来,效果好了很多。训练精度至少可以到达 80%,再想大幅度提高精度,就需要一些其他的方法了,下一篇文章我们再聊。

老规矩,附上全部代码:

#!/usr/bin/env python3

import os
import shutil
import time import matplotlib.pyplot as plt
from keras import layers
from keras import models
from keras import optimizers
from keras.preprocessing.image import ImageDataGenerator def make_small():
original_dataset_dir = '/Users/renyuzhuo/Desktop/cat/dogs-vs-cats/train'
base_dir = '/Users/renyuzhuo/Desktop/cat/dogs-vs-cats-small'
os.mkdir(base_dir) train_dir = os.path.join(base_dir, 'train')
os.mkdir(train_dir)
validation_dir = os.path.join(base_dir, 'validation')
os.mkdir(validation_dir)
test_dir = os.path.join(base_dir, 'test')
os.mkdir(test_dir)
train_cats_dir = os.path.join(train_dir, 'cats')
os.mkdir(train_cats_dir)
train_dogs_dir = os.path.join(train_dir, 'dogs')
os.mkdir(train_dogs_dir)
validation_cats_dir = os.path.join(validation_dir, 'cats')
os.mkdir(validation_cats_dir)
validation_dogs_dir = os.path.join(validation_dir, 'dogs')
os.mkdir(validation_dogs_dir)
test_cats_dir = os.path.join(test_dir, 'cats')
os.mkdir(test_cats_dir)
test_dogs_dir = os.path.join(test_dir, 'dogs')
os.mkdir(test_dogs_dir)
fnames = ['cat.{}.jpg'.format(i) for i in range(1000)]
for fname in fnames:
src = os.path.join(original_dataset_dir, fname)
dst = os.path.join(train_cats_dir, fname)
shutil.copyfile(src, dst)
fnames = ['cat.{}.jpg'.format(i) for i in range(1000, 1500)]
for fname in fnames:
src = os.path.join(original_dataset_dir, fname)
dst = os.path.join(validation_cats_dir, fname)
shutil.copyfile(src, dst)
fnames = ['cat.{}.jpg'.format(i) for i in range(1500, 2000)]
for fname in fnames:
src = os.path.join(original_dataset_dir, fname)
dst = os.path.join(test_cats_dir, fname)
shutil.copyfile(src, dst) fnames = ['dog.{}.jpg'.format(i) for i in range(1000)]
for fname in fnames:
src = os.path.join(original_dataset_dir, fname)
dst = os.path.join(train_dogs_dir, fname)
shutil.copyfile(src, dst)
fnames = ['dog.{}.jpg'.format(i) for i in range(1000, 1500)]
for fname in fnames:
src = os.path.join(original_dataset_dir, fname)
dst = os.path.join(validation_dogs_dir, fname)
shutil.copyfile(src, dst)
fnames = ['dog.{}.jpg'.format(i) for i in range(1500, 2000)]
for fname in fnames:
src = os.path.join(original_dataset_dir, fname)
dst = os.path.join(test_dogs_dir, fname)
shutil.copyfile(src, dst) def cat():
base_dir = '/Users/renyuzhuo/Desktop/cat/dogs-vs-cats-small'
train_dir = os.path.join(base_dir, 'train')
validation_dir = os.path.join(base_dir, 'validation') model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Flatten())
model.add(layers.Dropout(0.5))
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid')) model.summary()
model.compile(loss='binary_crossentropy', optimizer=optimizers.RMSprop(lr=1e-4), metrics=['acc']) # train_datagen = ImageDataGenerator(rescale=1. / 255)
train_datagen = ImageDataGenerator(
rescale=1. / 255,
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True, ) test_datagen = ImageDataGenerator(rescale=1. / 255) train_generator = train_datagen.flow_from_directory(
train_dir,
target_size=(150, 150),
batch_size=32,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
validation_dir,
target_size=(150, 150),
batch_size=32,
class_mode='binary')
history = model.fit_generator(
train_generator,
steps_per_epoch=100,
epochs=100,
validation_data=validation_generator,
validation_steps=50)
model.save('cats_and_dogs_small_2.h5') acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(len(acc))
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.show()
plt.figure()
plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.show() if __name__ == "__main__":
time_start = time.time()
# make_small()
cat()
time_end = time.time()
print('Time Used: ', time_end - time_start)

AI:是猫还是狗,这是个问题的更多相关文章

  1. 【深度学习】keras + tensorflow 实现猫和狗图像分类

    本文主要是使用[监督学习]实现一个图像分类器,目的是识别图片是猫还是狗. 从[数据预处理]到 [图片预测]实现一个完整的流程, 当然这个分类在 Kaggle 上已经有人用[迁移学习](VGG,Resn ...

  2. Java案例——猫与狗(接口版)

    一.需求:对猫跟狗进行训练,加入跳高功能,采用抽象类和接口实现,并创建测试类测试 二.分析: 1.定义接口(Jummping) 成员方法 跳高(): /*定义跳高接口 * */public inter ...

  3. Pytorch学习--编程实战:猫和狗二分类

    Pytorch学习系列(一)至(四)均摘自<深度学习框架PyTorch入门与实践>陈云 目录: 1.程序的主要功能 2.文件组织架构 3. 关于`__init__.py` 4.数据处理 5 ...

  4. Java中如何分析一个案列---猫狗案例为例

    猫狗案例: 具体事务: 猫.狗 共性: 姓名.年龄.吃饭 分析:从具体到抽象 猫: 姓名.年龄--->成员变量 吃饭       ---> 成员方法 构造方法:无参.有参 狗: 姓名.年龄 ...

  5. 用tensorflow迁移学习猫狗分类

    笔者这几天在跟着莫烦学习TensorFlow,正好到迁移学习(至于什么是迁移学习,看这篇),莫烦老师做的是预测猫和老虎尺寸大小的学习.作为一个有为的学生,笔者当然不能再预测猫啊狗啊的大小啦,正好之前正 ...

  6. 1.keras实现-->自己训练卷积模型实现猫狗二分类(CNN)

    原数据集:包含 25000张猫狗图像,两个类别各有12500 新数据集:猫.狗 (照片大小不一样) 训练集:各1000个样本 验证集:各500个样本 测试集:各500个样本 1= 狗,0= 猫 # 将 ...

  7. CC17:猫狗收容所

    题目 有家动物收容所只收留猫和狗,但有特殊的收养规则,收养人有两种收养方式,第一种为直接收养所有动物中最早进入收容所的,第二种为选择收养的动物类型(猫或狗),并收养该种动物中最早进入收容所的. 给定一 ...

  8. 100天搞定机器学习|day40-42 Tensorflow Keras识别猫狗

    100天搞定机器学习|1-38天 100天搞定机器学习|day39 Tensorflow Keras手写数字识别 前文我们用keras的Sequential 模型实现mnist手写数字识别,准确率0. ...

  9. python练习:寒冰猴子狐狸,猫狗咬架

    python练习:寒冰猴子狐狸,猫狗咬架 一,寒冰猴子狐狸 class Person: def __init__(self, na, gen, age, fig): self.name = na se ...

随机推荐

  1. 第04项目:淘淘商城(SpringMvc+Spring+Mybatis) 的学习实践总结【第三天】

    淘淘商城(SpringMVC+Spring+Mybatis)  是传智播客在2015年9月份录制的,几年过去了.由于视频里课上老师敲的代码和项目笔记有些细节上存在出入,只有根据日志报错信息作出适当的调 ...

  2. IOS之Core Foundation框架和Cocoa Foundation框架的区别(转)

    Core Foundation框架 (CoreFoundation.framework) 是一组C语言接口,它们为iOS应用程序提供基本数据管理和服务功能.下面列举该框架支持进行管理的数据以及可提供的 ...

  3. 二、linux-mysql -cmake方式安装mysql 5.5

    1.安装解压cmake包  cmake软件cd /home/oldboy/tools/tar xf cmake-2.8.8.tar.gzcd cmake-2.8.8./configure#CMake ...

  4. D - Association for Control Over Minds Kattis - control (并查集+STL)

    You are the boss of ACM (Association for Control over Minds), an upstanding company with a single go ...

  5. D. Almost All Divisors

    We guessed some integer number xx. You are given a list of almost all its divisors. Almost all means ...

  6. JavaScript--DOM,BOM

    前戏 到目前为止,我们已经学过了JavaScript的一些简单的语法.但是这些简单的语法,并没有和浏览器有任何交互. 也就是我们还不能制作一些我们经常看到的网页的一些交互,我们需要继续学习BOM和DO ...

  7. 104)PHP,目录树状输出

    使用特定数量的缩进达到树状目的! 核心问题,计算需要缩进的数量! 缩进级别,与递归调用深度保持一致.每当执行一级递归操作,所找到的文件的缩进级别+; 语法实现: 增加一个参数,表示当前函数调用的深度级 ...

  8. 花生壳的ddns 关键时刻又掉链子,准备迁到阿里万网

    https://www.oray.com/news/affiche/?aid=628 免费版花生壳服务故障 因免费版机房线路节点负荷突然暴增,导致花生壳免费版登录缓慢或异常,或出现域名指向到127.0 ...

  9. vue element 全屏不好用问题

    Chrome71版本使用screenfull.js全屏功能时报参数错误   在生产环境长期使用的一个“全屏”功能突然失效了,查看Console 如下报错: Failed to execute 'req ...

  10. Python迭代器和关键字 global ,nonlocal

    1.关键字 global : 可以修改全局变量 可以在局部作用域声明一个全局变量,剪切 : 此时局部作用域没有该变量,全局作用域中有 name = 1 def func(): global name ...