【学习笔记】使用Keras构建CNN网络完成猫狗分类(适合初学者,简单易上手)
首先准备好猫和狗的图片数据集,在pycharm中新建一个项目cat_dog recognition,把数据集文件放在该文件夹下。
训练集和测试集都有猫和狗的图片。
1.图像数据预处理、
在项目中新建impreprocess.py文件:
from keras.preprocessing.image import ImageDataGenerator,array_to_img,img_to_array,load_img import numpy as np #数据图像生成 datagen=ImageDataGenerator( rotation_range=40,#随机旋转度数 width_shift_range=0.2,#随机水平平移 height_shift_range=0.2,#随机竖直平移 rescale=1/255,#数据归一化 shear_range=0.2,#随机裁剪 zoom_range=0.2,#随机放大 horizontal_flip=True,#水平翻转 fill_mode='nearest',#填充方式 ) #载入图片 image=load_img('images/training_set/cats/cat.1.jpg') x=img_to_array(image)#图像数据是一维的,把它转成数组形式 print(x.shape) x=np.expand_dims(x,0)#在图片的0维增加一个维度,因为Keras处理图片时是4维,第一维代表图片数量 print(x.shape
运行结果:
数据图像生成的参数说明:
生成20张图片数据(特征图):在项目文件夹下新建temp文件夹
#生成20张图片数据 i=0 for batch in datagen.flow(x,batch_size=1,save_to_dir='temp',save_prefix='new_cat',save_format='jpeg'): i+=1 if i==20: break print('finshed!'
运行结果:
在temp文件夹下随机生成20 张旋转、放大、缩小、平移等处理过的图片。这样做的目的是,因为一张图片有许多不同的状态,这样图片的信息量会增多,训练样本数据量就会变大,使得训练模型效果更好。
2.构造简单训练模型
在项目中新建CNNclassification.py文件
from keras.models import Sequential from keras.layers import Conv2D,MaxPool2D,Activation,Dropout,Flatten,Dense from keras.optimizers import Adam from keras.preprocessing.image import ImageDataGenerator,load_img,img_to_array from keras.models import load_model import numpy as np from matplotlib import pyplot as plt #定义模型 #将输入数据大小改为150*150*3再加入模型 model=Sequential() model.add(Conv2D(input_shape= (150,150,3),filters=32,kernel_size=3,padding='same',activation='relu')) model.add(Conv2D(filters=32,kernel_size=3,padding='same',activation='relu')) model.add(MaxPool2D(pool_size=2,strides=2)) model.add(Conv2D(filters=64,kernel_size=3,padding='same',activation='relu')) model.add(Conv2D(filters=64,kernel_size=3,padding='same',activation='relu')) model.add(MaxPool2D(pool_size=2,strides=2)) model.add(Conv2D(filters=128,kernel_size=3,padding='same',activation='relu')) model.add(Conv2D(filters=128,kernel_size=3,padding='same',activation='relu')) model.add(MaxPool2D(pool_size=2,strides=2)) #卷积池化完原始图像是一个二维的特征图 model.add(Flatten())#把二维数据转换为一维 model.add(Dense(64,activation='relu'))#Dense代表全连接层,64是最后卷积池化后输出的神经元个数 model.add(Dropout(0.5))#防止过拟合 model.add(Dense(2,activation='softmax'))#softmax是把训练结果用概率形式表示的函数,2代表二分类 #定义优化器 adam=Adam(lr=1e-4) #定义优化器、代价函数、训练过程中计算准确率 model.compile(optimizer=adam,loss='categorical_crossentropy',metrics=['accuracy']) #数据增强 train_datagen=ImageDataGenerator( rotation_range=40,#随机旋转度数 width_shift_range=0.2,#随机水平平移 height_shift_range=0.2,#随机竖直平移 rescale=1/255,#数据归一化 shear_range=0.2,#随机裁剪 zoom_range=0.2,#随机放大 horizontal_flip=True,#水平翻转 fill_mode='nearest',#填充方式 ) test_datagen=ImageDataGenerator( rescale=1/255,#数据归一化 ) batch=32#每次训练传入32张照片 #生成训练数据 train_generator=train_datagen.flow_from_directory( 'images/training_set',#从训练集这个目录生成数据 target_size=(150,150),#把生成数据大小定位150*150 batch_size=batch, ) #测试数据 test_generator=test_datagen.flow_from_directory( 'images/test_set',#从训练集这个目录生成数据 target_size=(150,150),#把生成数据大小定位150*150 batch_size=batch, ) #查看定义类别分类 print(train_generator.class_indices) #定义训练模型 #传入生成的训练数据、每张图片训练1次,验证数据为生成的测试数据 model.fit_generator(train_generator,epochs=1,validation_data=test_generator
其中CNN卷积神经网络的搭建过程就是卷积层、池化层的组合,这部分内容,可以通过学习吴恩达深度学习课程卷积网络那部分来掌握,很好理解。
运行结果:3873张训练集图像分成两类,1080张测试集图像也分成两类。通过查看类别定义,0赋值给‘cats’,1赋值给‘dogs’。因为数据集太大,而本身电脑硬件条件有限,我把数据集和测试集的图片均删掉一半,并把迭代次数设置为一,方便更快看到效果。可以看到,这个模型训练完成后,训练集的精确度只有51%,测试集是56%,并不高。
3.保存模型
#保存模型 #pip install h5py model.save('model_cnn.h5'
然后可以在项目文件夹中看到H5文件
4.测试模型
还是在该文件中
label=np.array(['cat','dog'])#0、1赋值给标签 #载入模型 model=load_model('model_cnn.h5') #导入图片 image=load_img('images/test_set/cats/cat.4001.jpg') plt.imshow(image) plt.show() image=image.resize((150,150)) image=img_to_array(image) image=image/255#数值归一化,转为0-1 image=np.expand_dims(image,0) print(image.shape) print(label[model.predict_classes(image)]
运行结果:
导入的是测试集中这张照片,但因为模型精确度只有50%,所以给出的答案是dog。
再换一张识别度高的猫咪图片试试:
结果就是cat了。