上一篇介绍了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钢铁侠,分别输入进行测试。
下属代码需要先安装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)
貌似准确率不是很高,前3只cat只中了2只,然后3只狗只中了1只,最后3只不是的肯定没有办法中。