猫狗大战

这份数据集来源于Kaggle。原数据集有12500只猫和12500只狗,我们只取了各个类的前1000张图片。另外我们还从各个类中取了400张额外图片用于测试。

下面是数据集的一些示例图片,图片的数量非常少,这对于图像分类来说是个大麻烦。但现实是,很多真实世界图片获取是很困难的,我们能得到的样本数目确实很有限(比如医学图像,每张正样本都意味着一个承受痛苦的病人。


针对小数据集的深度学习

运用数据提升技术:

为了尽量利用我们有限的训练数据,我们将通过一系列随机变换堆数据进行提升,这样我们的模型将看不到任何两张完全相同的图片,这有利于我们抑制过拟合,使得模型的泛化能力更好。

在Keras中,这个步骤可以通过keras.preprocessing.image.ImageGenerator来实现,这个类使你可以:

在训练过程中,设置要施行的随机变换
通过.flow或.flow_from_directory(directory)方法实例化一个针对图像batch的生成器,这些生成器可以被用作keras模型相关方法的输入,如fit_generator,evaluate_generator和predict_generator


先生成一些图片试试水

1.下载图片集,并保存到路径下https://www.kaggle.com/c/dogs-vs-cats/data

import os
os.chdir('C:/Users/ZWT/Desktop/1/cat_dog_keras/train/train')

先试试水,看一下图片尺寸大小和样子
也是熟悉一下PIL的操作

from PIL import Image
img=Image.open('cat.0.jpg')
print img.format, img.size, img.mode#img.shape是不行的,shape针对的是array格式
img.show()

2.试了一下用图片生成器预处理图片:也就是用一张图片,通过变换,加噪声,偏移….生成更多图片,对图片进行提升

from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
#初始化图片生成器,说明按照什么方式生成
datagen = ImageDataGenerator(
        rotation_range=40,
        width_shift_range=0.2,
        height_shift_range=0.2,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True,
        fill_mode='nearest')

img = load_img('cat.20.jpg')  # this is a PIL image
print img.format,img.size,img.mode
#输出:None (500, 374) RGB,可以看到和Image.open的差别(JPEG和None)

解释一下参数:
1. rotation_range是一个0~180的度数,用来指定随机选择图片的角度。
2. width_shift和height_shift用来指定水平和竖直方向随机移动的程度,这是两个0~1之间的比例。
3. rescale值将在执行其他处理前乘到整个图像上,我们的图像在RGB通道都是0~255的整数,这样的操作可能使图像的值过高或过低,所以我们将这个值定为0~1之间的数。
4. shear_range是用来进行剪切变换的程度,参考剪切变换
5. zoom_range用来进行随机的放大
6. horizontal_flip随机的对图片进行水平翻转,这个参数适用于水平翻转不影响图片语义的时候
7. fill_mode用来指定当需要进行像素填充,如旋转,水平和竖直位移时,如何填充新出现的像素


#图像转成array格式
x = img_to_array(img)# this is a Numpy array with shape (3, 150, 150)
print x.shape
x=x.reshape((1,)+x.shape)
print x.shape
%%输出了:
(3L, 374L, 500L)
(1L, 3L, 374L, 500L)

现在正式开始生成图片了

i=0
for batch in datagen.flow(x,batch_size=1,save_to_dir='preview',save_prefix='cat', save_format='jpeg'):
    i+=1
    if i>20:
        break
#生成20个,这里我在train下建了一个名字为preview的文件夹,生成图片就存在里面

3.
数据提升是对抗过拟合,但还不够,因为提升过的数据仍然是高度相关的。对抗过拟合的你应该主要关注的是模型的“熵容量”——模型允许存储的信息量。也就是特征数量,把没用特征去掉,利用有用特征。
调整模型的“熵容量”方法:
1.调整模型的参数数目,即模型的层数和每层的规模。
2.对权重进行正则化约束,如L1或L2.这种约束会使模型的权重偏向较小的值。


搭建一个只有少量样本的模型

'''
This script goes along the blog post
"Building powerful image classification models using very little data"
from blog.keras.io.
It uses data that can be downloaded at:
https://www.kaggle.com/c/dogs-vs-cats/data
In our setup, we:
- created a data/ folder
- created train/ and validation/ subfolders inside data/
- created cats/ and dogs/ subfolders inside train/ and validation/
- put the cat pictures index 0-999 in data/train/cats
- put the cat pictures index 1000-1400 in data/validation/cats
- put the dogs pictures index 12500-13499 in data/train/dogs
- put the dog pictures index 13500-13900 in data/validation/dogs
So that we have 1000 training examples for each class, and 400 validation examples for each class.
In summary, this is our directory structure:
目录格式
C:/Users/ZWT/Desktop/1/mini_dog_cat/
    train/
        dogs/
            dog001.jpg
            dog002.jpg
            ...
        cats/
            cat001.jpg
            cat002.jpg
            ...
    validation/
        dogs/
            dog001.jpg
            dog002.jpg
            ...
        cats/
            cat001.jpg
            cat002.jpg
            ...

与上面的程序不同,这个是对于一个文件夹中所有图片都进行数据提升。一个文件夹中存放几个子文件夹,子文件名相当于类别数,也就是标签。

这里有几个地方:
图片生成器中的batch_size,指的是每次向模型中输入一个batch内所包含图片的多少
达到samples_per_epoch时,一个epoch完成。

from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense

import h5py
from keras.models import load_model

# dimensions of our images.
img_width, img_height = 150, 150

train_data_dir = 'train'
validation_data_dir = 'validation'
nb_train_samples = 2000
nb_validation_samples = 800
nb_epoch = 50


model = Sequential()
model.add(Convolution2D(32, 3, 3, input_shape=(3, img_width, img_height)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Convolution2D(32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Convolution2D(64, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

# 实例化图片生成器,说明图片是咋变化的
train_datagen = ImageDataGenerator(
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)

# 验证的数据不用变,只需要像素变成0-1区间的
test_datagen = ImageDataGenerator(rescale=1./255)

# 对这个实例化的生成器使用方法,说明它要干什么,从文件夹读图,标签。以及设置要生成目标的参数
train_generator = train_datagen.flow_from_directory(
        train_data_dir,#从这个目录里面读取图片
        target_size=(img_width, img_height),
        batch_size=32,
        class_mode='binary')
#categorical会返回2D的one-hot编码标签,binary返回1D的二值标签

validation_generator = test_datagen.flow_from_directory(
        validation_data_dir,
        target_size=(img_width, img_height),
        batch_size=32,  
        class_mode='binary')

model.fit_generator(
        train_generator,
        samples_per_epoch=nb_train_samples,#2000
        nb_epoch=nb_epoch,#50
        validation_data=validation_generator,
        nb_val_samples=nb_validation_samples)#800

model.save('mini_dog_cat.h5')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值