这是一个用python写CNN的小练习,目标是构建一个能够完成二分类任务(识别猫或者狗)的CNN。
这是一部分的结果展示,可以看到被展示的经过预处理后的图片都被准确识别了。
用以训练神经网络的数据集由8000张带标签的jpg图片构成,其中猫狗各4000张。
任务可以分为五个部分:
1.导入训练数据
2.数据预处理
3.构建神经网络
4.训练神经网络
5.评价以及预测结果查看
以下是各部分的python代码以及详细的介绍:
1.导入以及预处理训练数据:
from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale=1./255)
training_set = train_datagen.flow_from_directory(r'C:\Users\zyh\Desktop\python_course\DL\Chapter3\task1_data\training_set',target_size=(50,50),batch_size=32,class_mode='binary')
keras的ImageDataGenerator可以实现批量的处理导入的图片,在导入的时候就进行了数据的归一化和标准化,其中第二行代码把所有图片的RGB值归一化,第三行代码把所有图片都保存成了50*50的像素,同时告诉电脑要做的是一个二分类问题。
把第一张处理完的图片call出来看一看
from matplotlib import pyplot as plt
fig1 = plt.figure()
plt.imshow(training_set[0][0][0,:,:,:])
2.建立CNN网络
cnn_model = Sequential()
#添加卷积层
cnn_model.add(Conv2D(32,(3,3),input_shape=(50,50,3),activation='relu'))
#添加池化层
cnn_model.add(MaxPool2D(pool_size=(2,2)))
#添加卷积层
cnn_model.add(Conv2D(32,(3,3),activation='relu'))
#添加池化层
cnn_model.add(MaxPool2D(pool_size=(2,2)))
#flatten展开
cnn_model.add(Flatten())
#FC层
cnn_model.add(Dense(units=128,activation='relu'))
#预测输出层
cnn_model.add(Dense(units=1,activation='sigmoid'))
CNN网络通常就是有卷积层、池化层和全连接层组成。卷积层我理解的就是用一个滤波器(filter)去过滤原来的图片,把重要的信息留下来把没用的信息去掉。比如识别猫狗,其实只有图片中间那一点点是有用的信息,边上背景都是增加计算量的垃圾信息。池化通常分max pooling和mean pooling,它的作用我感觉就像是主成分分析(PCA)和数据降维对机器学习算法那样,就是在尽量保留数据真实度的情况下减少计算量。全连接层就是和普通BP神经网络类似,没啥好说的。
设计好的滤波器(filters)和池化方法(pooling)组合可以最有效的滤出图片中的有用信息,同时减少计算量。有名的CNN设计有 Alexnet VGG16等。这里我就选择站在巨人的肩膀上,偷了一个别人设计好的CNN。
3.模型训练
cnn_model.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy'])
cnn_model.fit_generator(training_set,epochs=20)
这个没啥好说的,把处理好的数据和标签丢到CNN去训练。
Epoch 1/20
250/250 [==============================] - 24s 97ms/step - loss: 0.6498 - accuracy: 0.6125
Epoch 2/20
250/250 [==============================] - 19s 78ms/step - loss: 0.5733 - accuracy: 0.7005
Epoch 3/20
250/250 [==============================] - 19s 75ms/step - loss: 0.5151 - accuracy: 0.7384
Epoch 4/20
250/250 [==============================] - 19s 76ms/step - loss: 0.4708 - accuracy: 0.7759
Epoch 5/20
250/250 [==============================] - 20s 81ms/step - loss: 0.4331 - accuracy: 0.7962
Epoch 6/20
250/250 [==============================] - 23s 92ms/step - loss: 0.3885 - accuracy: 0.8210
Epoch 7/20
250/250 [==============================] - 23s 93ms/step - loss: 0.3311 - accuracy: 0.8549
Epoch 8/20
250/250 [==============================] - 22s 89ms/step - loss: 0.2785 - accuracy: 0.8840
Epoch 9/20
250/250 [==============================] - 25s 98ms/step - loss: 0.2144 - accuracy: 0.9153
Epoch 10/20
250/250 [==============================] - 22s 88ms/step - loss: 0.1607 - accuracy: 0.9396
Epoch 11/20
250/250 [==============================] - 22s 87ms/step - loss: 0.1278 - accuracy: 0.9550
Epoch 12/20
250/250 [==============================] - 23s 93ms/step - loss: 0.0801 - accuracy: 0.9760
Epoch 13/20
250/250 [==============================] - 20s 78ms/step - loss: 0.0530 - accuracy: 0.9852
Epoch 14/20
250/250 [==============================] - 18s 73ms/step - loss: 0.0346 - accuracy: 0.9914
Epoch 15/20
250/250 [==============================] - 22s 87ms/step - loss: 0.0259 - accuracy: 0.9934
Epoch 16/20
250/250 [==============================] - 25s 100ms/step - loss: 0.0178 - accuracy: 0.9959
Epoch 17/20
250/250 [==============================] - 20s 82ms/step - loss: 0.0289 - accuracy: 0.9918
Epoch 18/20
250/250 [==============================] - 18s 74ms/step - loss: 0.0359 - accuracy: 0.9877
Epoch 19/20
250/250 [==============================] - 18s 71ms/step - loss: 0.0320 - accuracy: 0.9900
Epoch 20/20
250/250 [==============================] - 18s 73ms/step - loss: 0.0141 - accuracy: 0.9974
可以看到随着一个epoch的进行,准确率一直在升高,损失函数一直在减少。
4.模型评估
accuracy_train = cnn_model.evaluate_generator(training_set)
print(accuracy_train)
[0.048568304628133774, 0.9927499890327454]
准确率99% 还不错哦
把pic1丢进模型里去看一下预测结果
result = cnn_model.predict_classes(pic_1)
print('dog' if result==1 else 'cat')
dog
说明算对了哦哦