基于CNN模型的火焰识别
采用CNN网络模型进行火焰识别,包含完整的数据集和代码,采用Python3.7.5和jupyter notework
完整代码及数据集见文末
首先选定数据集,并产生对应的训练集和验证集。
# 训练集位置
TRAINING_DIR = "./Datasets 1-2/Training"
training_datagen = ImageDataGenerator(rescale=1. / 255,
horizontal_flip=True,
rotation_range=30,
height_shift_range=0.2,
fill_mode='nearest')
# 训练器
train_generator = training_datagen.flow_from_directory(
TRAINING_DIR,
target_size=(224, 224),
class_mode='categorical',
batch_size=64
)
# 验证生成器
validation_generator = validation_datagen.flow_from_directory(
VALIDATION_DIR,
target_size=(224, 224),
class_mode='categorical',
batch_size=16
)
然后搭建CNN网络模型。
这个CNN网络结构是一个基于卷积神经网络的深度学习模型,用于图像分类任务。该模型由输入层、卷积层、池化层、全连接层和输出层共同构成,在每一层都使用了不同的参数,以提高模型的准确性和泛化能力。
具体网络结构如下:
-
输入层(Input Layer):该神经层通过tf.keras.layers.Conv2D来对输入的图像进行特征提取。这里我们采用了96个11x11的卷积核,并且步长为4。同时,激活函数为ReLU(rectified linear unit)。输入图像的宽度为224,高度为224,通道个数为3。
-
池化层(Pooling Layer):池化层主要用来缩小之前卷积层输出的特征图的大小和数量,从而减少计算量。这里我们采用了最大池化(MaxPooling2D)。池化窗口大小为3x3,步长为2,即每隔2个像素进行取样,保留最大值作为该区域的输出。
-
卷积层(Convolutional Layer):该神经层通过tf.keras.layers.Conv2D来对上一层输出的特征图进行特征提取。这里我们采用了256个5x5的卷积核。同时,激活函数为ReLU。
-
池化层(Pooling Layer):同第二层池化层,采用最大池化(MaxPooling2D)。窗口大小为3x3,步长为2。
-
卷积层(Convolutional Layer):同第三层卷积层,使用384个5x5的卷积核,并且激活函数为ReLU。
-
池化层(Pooling Layer):同第四层池化层,使用最大池化(MaxPooling2D),窗口大小为3x3,步长为2。
-
全连接层(Dense Layer):该神经层通过tf.keras.layers.Dense来对之前所有层的输出进行全连接。我们首先采用了Flatten层将所有的特征图展平成一维的向量。然后,采用Dropout(0.2)随机断开20%的神经元,以防止过拟合。接着,采用了2048个神经元的全连接层,并且激活函数为ReLU。
-
全连接层(Dense Layer):同第七层,采用了Dropout(0.25)来随机断开一部分神经元。接着,采用了1024个神经元的全连接层,并且激活函数为ReLU。
-
全连接层(Dense Layer):同第八层,采用了Dropout(0.2)随机断开20%的神经元。接着,采用了2个神经元的全连接层,并且激活函数为softmax函数。softmax函数将输出的结果转换为分类概率,用于进行2类分类任务。
-
输出层(Output Layer):该层输出2个神经元,对应我们的2类分类任务。
最终,整个CNN网络结构使用交叉熵损失函数来计算误差,并且使用Adam优化器进行训练。同时,对模型进行了准确率的评价指标。
from keras.optimizers import RMSprop, Adam
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(96, (11, 11), strides=(4, 4), activation='relu', input_shape=(224, 224, 3)),
tf.keras.layers.MaxPooling2D(pool_size=(3, 3), strides=(2, 2)),
tf.keras.layers.Conv2D(256, (5, 5), activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=(3, 3), strides=(2, 2)),
tf.keras.layers.Conv2D(384, (5, 5), activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=(3, 3), strides=(2, 2)),
tf.keras.layers.Flatten(),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(2048, activation='relu'),
tf.keras.layers.Dropout(0.25),
tf.keras.layers.Dense(1024, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(2, activation='softmax')
])
然后就是进行训练
# class myCallback(tf.keras.callbacks.Callback):
# def on_epoch_end(self, epoch, logs={}):
# if(logs.get('val_acc')>=0.98):
# print('\nReached ^98%')
# self.model.stop_training = True
# callbacks = myCallback()
history = model.fit(
train_generator,
steps_per_epoch=15,
epochs=50,
validation_data=validation_generator,
validation_steps=15
#callbacks=[callbacks]
)
#保存训练好的模型参数文件
model.save('my_model.h5')
并绘制训练的loss图
%matplotlib inline
import matplotlib.pyplot as plt
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(len(acc))
plt.plot(epochs, acc, 'g', label='Training accuracy')
plt.plot(epochs, val_acc, 'b', label='Validation accuracy')
plt.title('Training and validation accuracy')
plt.legend(loc=0)
plt.figure()
plt.show()
plt.plot(epochs, loss, 'r', label='Training loss')
plt.plot(epochs, val_loss, 'orange', label='Validation loss')
plt.title('Training and validation loss')
plt.legend(loc=0)
plt.figure()
plt.show()
最后则是进行预测
# 预测任意的图片
import numpy as np
import cv2
# from google.colab import files
# from keras.preprocessing import image
import keras
from keras.utils import image_utils
# from PIL import Image
# 加载训练好的模型
model = keras.models.load_model('my_model.h5')
# uploaded = files.upload()
# for fn in uploaded.keys():
# path = '/content/' + fn
# img = image.load_img(path, target_size=(224, 224))
# x = image.img_to_array(img)
# x = np.expand_dims(x, axis=0) /255
# classes = model.predict(x)
# print(np.argmax(classes[0])==0, max(classes[0]))
# 利用训练好的模型对图片进行验证
path = './test/1.jpg'
img = image_utils.load_img(path, target_size=(224, 224))
x = image_utils.img_to_array(img)
x = np.expand_dims(x, axis=0) / 255
classes = model.predict(x)
print(np.argmax(classes[0]) == 0, max(classes[0]))
# 判断为火焰
if np.argmax(classes[0]) == 0:
raw_img = cv2.imread('./test/1.jpg')
logo = "fire %s" % str(max(classes[0]))
print(logo)
cv2.putText(raw_img, logo, (100, 100), cv2.FONT_HERSHEY_SIMPLEX, 2.0,
(0, 0, 255), 2, cv2.LINE_AA)
cv2.imshow("./test/1_predict.ipg", raw_img)
cv2.waitKey()
cv2.imwrite("./test/1_predict.jpg", raw_img)
更多推荐
所有评论(0)