Keras中的卷积神经网络
在本文中,我将教你如何创建卷积神经网络(CNN)来预测照片是猫还是狗。可以进一步扩展的目标是让神经网络能够预测猫或狗的种类,但这可以看作是一个垫脚石。
在进入代码之前,请确保您正确安装了带有tensorflow后端的python 3以及opencv,以便在进行预测时将图片转换为可读格式。我在安装opencv时遇到了一些挑战,最简单的方法是在anaconda终端输入:
>>> conda install opencv
以下是您需要用于此项目的所有导入列表:
from keras.models import Sequential
from keras.preprocessing.image import ImageDataGenerator
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
from keras.models import model_from_json
import cv2
Sequential是一个非常有用的工具,因为它允许您顺序构建CNN。下面是我们将用来建立我们的CNN的Keras管道的图片:
ImageDataGenerator是一种允许Keras创建一系列训练数据的工具。Conv2D, MaxPooling2D, Flatten和density只是我们可以添加到神经网络的一系列不同层。最后,model_from_json允许我们在CNN完成构建后加载它。
我们的第一步是定义我们的网络,按照惯例,我们将把我们的网络称为“模型”
model = Sequential()
这为我们的神经网络建立了基础,我们可以逐层构建它。然后我们需要添加卷积滤波器,这是检测图像中特征和模式的第一步
model.add(Conv2D(32, (3,3), input_shape = (50,50,3), activation = 'relu'))
Conv2D的第一个参数是网络的输出空间,这对我来说是一个任意的选择。第二个参数是一个二元元组,它表示您的卷积窗口的大小,这个过滤器负责检测某些特性。第三个参数告诉网络输入图像的形状。最后利用修正后的线性单元激活函数
下一步是添加最大池层,这有助于降低正在处理的数据的维度。这是一个简单的图像,应该能够让你了解这个图层实际上是什么:
两维最大池
我们将使用2x2 filter ,就像在这张图片中一样:
model.add(MaxPooling2D(pool_size = (2,2)))
现在我们在这一点上消除了很多噪音,我们重复添加另一个卷积层和另一个最大池2x2 filter。一个例外是我们不需要指定我们图像的输入形状,因为我们已经在第一层中完成了这些。
model.add(Conv2D(32, (3,3), activation = 'relu'))
model.add(MaxPooling2D(pool_size = (2,2)))
我们非常接近完成我们的神经网络,但我们还需要添加三个组件:flatten和两个dense 层。
Flatten需要一个n维输入并将其平滑到一条线上。例如,如果您的模型的形状是(16像素,32像素),那么当您flattens它时,会得到一条16像素x 32像素= 512像素的线条。
我们最后的两个图层是dense层,它允许您将flattened 层连接到尽可能多的像素。在我们的模型中,第一个dense层将有128个单元,而我们的输出层将具有1个单元的二进制输出。
model.add(Dense(units=128, activation='relu'))
model.add(Dense(units=1, activation='sigmoid'))
注意,没有为所有层使用“relu”激活函数,而是将sigmoid激活函数用于最后一层。这是因为sigmoid压缩了0到1之间的实数轴,这对于预测图像是猫(0)还是狗(1)是最理想的。
现在我们已经构建了我们的模型,我们转到下一个阶段:编译。
model.compile(optimizer ='adam',loss ='binary_crossentropy',metrics = ['accuracy'])
可以随意使用优化器,但我希望尽可能遵循常规。二元交叉熵函数是二元输出的一个很好的损失函数
现在编译了神经网络,我们需要在数据集上进行训练。我使用了Kaggle的DogsvsCats数据集(https://www.kaggle.com/c/dogs-vs-cats),但如果您愿意,可以随意使用自己的图片库
train_datagen = ImageDataGenerator(rescale = 1./300,
shear_range=0.3, zoom_range=0.3, horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1./300)
training_set = train_datagen.flow_from_directory(directory=yourDir,
target_size=(50,50), batch_size=32, class_mode='binary')
请随意复制此代码,只需将“yourDir”更改为放置照片的目录。
接下来,我们要适应神经网络。这一步需要非常非常长的时间,所以如果一个小时过去了,你的程序仍然没有完成,不要惊慌
model.fit_generator(training_set,steps_per_epoch = 9000,epochs =
10,
validation_steps = 2000)
我曾见过一些人用过25个epochs 或更多的数据集,但是如果你想要第一个CNN的像样的结果,我在10个epochs 后准确率达到96%,我很高兴。
这里可能是本文最关键的部分:保存你的神经网络:
model_json = model.to_json()
with open(“model.json”,“w”)as json_file:
json_file.write(model_json)
model.save_weights(“model.h5”)
你必须确保这样做,因为神经网络需要很长时间才能进行训练,并且你不希望每过一次你想测试你的CNN都要重新训练它。
现在已经完成了,下面是一个函数,它读入一个示例图像并为您的模型做好准备:
def getimgready(imgPath):
img = cv2.imread(imgPath)
img = cv2.resize(img, (50,50))
img = img.reshape(1,50,50,3)
准备好图像后,最后一步是:
model.predict(yourImage)