【实战演练】机器学习系列03-keras搭建猫狗识别神经网络

上一篇介绍了keras的安装与搭建线性回归神经网络,这篇我们尝试搭建猫狗识别的神经网络。

提前下载猫狗图片kaggle数据集,下载链接:https://www.kaggle.com/c/dogs-vs-cats-redux-kernels-edition/data

里面带有test1.zip与train.zip的压缩包,其中train里面的图片是用于对模型进行训练的,而test里面的图片是用来对模型进行测试的。

其中train的图片,已经对图片打了标签,例如猫的是cat.0.jpg,狗的是dog.0.jgp,为了给神经网络做有监督式的学习。

先将train.zip解压到c:\data\train\目录,注意windows的\是不行的,路径用/或者\\表示。


1、统计图片类型与数量

import os
train='C:\\data\\train\\'
dogs=[train+i for i in os.listdir(train) if 'dog' in i]
cats=[train+i for i in os.listdir(train) if 'cat' in i]
print(len(dogs),len(cats))

12500 12500

#统计c:\data\train\下面的图片数量,统计完发现dogs有12500张,cats有12500张。将第一步的代码保存为名叫data_process的py文件,方便第二步引用。(如果jupyter notebook是利用anaconda安装,那么放到当前用户的用户目录即可c:\users\xxx\)

2、分拣图片

自动创建一个叫做mini_trainningdata的文件夹,自动从data\train\里面选用1000张猫与1000张狗图片,分别放到c:\mini_trainningdata\train\dogs与cats里面,并且再选取500张猫,500张狗放到c:\mini_trainningdata\test\dogs与cat里面。

import os
def createDir(path):
    if not os.path.exists(path):
        try:
            os.makedirs(path)
        except:
            print("创建文件夹失败")
            exit(1)
path="C:/min_trainingdata/"
createDir(path+"train/dogs")
createDir(path+"train/cats")
createDir(path+"test/dogs")
createDir(path+"test/cats")
import data_process as dp
import shutil
for dog,cat in list(zip(dp.dogs,dp.cats))[:1000]:
    shutil.copyfile(dog,path+"train/dogs/"+os.path.basename(dog))
    print(os.path.basename(dog)+"操作成功")
    shutil.copyfile(cat, path + "train/cats/" + os.path.basename(cat))
    print(os.path.basename(cat) + "操作成功")
for dog, cat in list(zip(dp.dogs, dp.cats))[1000:1500]:
    shutil.copyfile(dog, path + "test/dogs/" + os.path.basename(dog))
    print(os.path.basename(dog) + "操作成功")
    shutil.copyfile(cat, path + "test/cats/" + os.path.basename(cat))
    print(os.path.basename(cat) + "操作成功")

3、数据增强

将以下代码保存为到c:/users/xxx/catvsdogs/morph.py

from keras.preprocessing.image import ImageDataGenerator
train_dir="c:/mini_trainningdata/train/"
test_dir="c:/mini_trainningdata/test/"
train_pic_gen=ImageDataGenerator(rescale=1./255,rotation_range=20,width_shift_range=0.2,height_shift_range=0.2,
                                 shear_range=0.2,zoom_range=0.5,horizontal_flip=True,fill_mode='nearest')
test_pic_gen=ImageDataGenerator(rescale=1./255)
train_flow=train_pic_gen.flow_from_directory(train_dir,(128,128),batch_size=32,class_mode='binary')
test_flow=test_pic_gen.flow_from_directory(test_dir,(128,128),batch_size=32,class_mode='binary')
# print(train_flow.class_indices)

4、构建与训练模型

from keras.models import Sequential
from keras.layers import Convolution2D,MaxPool2D,Flatten,Dense,Dropout
from keras.callbacks import TensorBoard
model=Sequential([
    Convolution2D(32,3,3,input_shape=(128,128,3),activation='relu'),
    MaxPool2D(pool_size=(2,2)),
    Convolution2D(64,3,3,input_shape=(128,128,3),activation='relu'),
    MaxPool2D(pool_size=(2,2)),
    Flatten(),
    Dense(64,activation='relu'),
    Dropout(0.5),
    Dense(1,activation='sigmoid')
])
model.summary()
model.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=['accuracy'])
import catvsdogs.morph as morph#引用上文1的数据增加代码
model.fit_generator(
    morph.train_flow,steps_per_epoch=100,epochs=50,verbose=1,validation_data=morph.test_flow,validation_steps=100,
    callbacks=[TensorBoard(log_dir='./logs/1')]
)
model.save('c:/mini_trainningdata/catdogs_model.h5')

执行后,会发现模型已经启动并且在训练。

5、重新加载,继续训练

from keras.callbacks import TensorBoard
from keras.models import load_model
model=load_model('c:/mini_trainningdata/catdogs_model.h5')
model.summary()
import catvsdogs.morph as morph
model.fit_generator(
    morph.train_flow,steps_per_epoch=100,epochs=50,verbose=1,validation_data=morph.test_flow,validation_steps=100,
    callbacks=[TensorBoard(log_dir='./logs/2')]
)
model.save('c:/mini_trainningdata/catdogs_model.h5')

6、使用自定义的图片测试

可以在pre_x=get_inputs里面修改为自己路径与路径下的图片进行测试。

我们pic0~2采用猫,pic3~5采用狗,pic6鳄鱼、pic7猴子、pic8钢铁侠,分别输入进行测试。

004.png

下属代码需要先安装opencv-python

pip install opencv-python
from keras import models
import numpy as np
import cv2
def get_inputs(src=[]):
    pre_x = []
    for s in src:
        input = cv2.imread(s)
        input = cv2.resize(input, (128, 128))
        input = cv2.cvtColor(input, cv2.COLOR_BGR2RGB)
        pre_x.append(input)  # input一张图片
    pre_x = np.array(pre_x) / 255.0
    return pre_x
def put_prey(pre_y,label):
    output=[]
    for y in pre_y:
        if y[0]<0.5:#二分类,此处只用一个神经元输出
            output.append([label[0],1-y[0]])
        else:
            output.append([label[1], y[0]])
    return output
model=models.load_model('c:/mini_trainningdata/catdogs_model.h5')
pre_x=get_inputs(['C:\\testdata\\pic0.jpg','C:\\testdata\\pic1.jpg','\\testdata\\pic2.jpg',
                  'C:\\testdata\\pic3.jpg','C:\\testdata\\pic4.jpg','C:\\testdata\\pic5.jpg',
                  'C:\\testdata\\pic6.jpg','C:\\testdata\\pic7.jpg','C:\\testdata\\pic8.jpg',
                 ])
pre_y=model.predict(pre_x)
import catvsdogs.morph as mp
output=put_prey(pre_y,list(mp.train_flow.class_indices.keys()))
print(output)

003.png

貌似准确率不是很高,前3只cat只中了2只,然后3只狗只中了1只,最后3只不是的肯定没有办法中。

猜你喜欢

转载自blog.51cto.com/14423403/2419998