原文链接
卷积神经网络实例探究 Keras tutorial - the Happy House-笑脸识别
- 为什么要使用Keras?
- 1- 开心屋
- 2- 在Keras中构建模型
- 3- 总结
欢迎来到第二周的编程作业,在这里你将会
- 学习到一个高级神经网络API(可编程框架)-Keras,它在python中运行,能够运行在包括TensorFlow和CNTK几个较低级别的框架之上的框架。
- 看看如何在几个小时内建立一个DL算法。
为什么要使用Keras?
Keras能够让DL工程师快速构建和试验不同的模型。正如TensorFlow是一个比Python更高级别的框架,Keras是一个更高级的框架,并提供了额外的抽象。能够以最少的时间从想法到现实是找到好模型的关键。然而,Keras比底层框架有更多限制性,所以有一些非常复杂的模型可以在TensorFlow中实现,但在Keras中却没有(没有更多困难)。话虽如此,Keras对于许多常见的模型都能很好地工作。
Keras在python中运行需要配合tensorflow,注意2者的版本匹配,https://docs.floydhub.com/guides/environments/
在本次练习中,你将会要解决笑脸识别问题,我们将在后面详细说明。首先,先我们导入库。
import numpy as np
from keras import layers
from keras.layers import Input, Dense, Activation, ZeroPadding2D, BatchNormalization, Flatten, Conv2D
from keras.layers import AveragePooling2D, MaxPooling2D, Dropout, GlobalMaxPooling2D, GlobalAveragePooling2D
from keras.models import Model
from keras.preprocessing import image
from keras.utils import layer_utils
from keras.utils.data_utils import get_file
from keras.applications.imagenet_utils import preprocess_input
import pydot
#from IPython.display import SVG
from keras.utils.vis_utils import model_to_dot
from keras.utils import plot_model
from kt_utils import *import keras.backend as K
K.set_image_data_format('channels_last')
import matplotlib.pyplot as plt
from matplotlib.pyplot import imshow# %matplotlib inline
注意:正如你所看到的,我们已经从Keras中导入了很多函数。你只需直接调用它们即可轻松使用它们。 比如:X = Input(…) 或者X = ZeroPadding2D(…).
1- 开心屋
下一个假期,你决定和你学校的五个朋友呆一个星期。这是一个非常好的房子,在附近有很多事情要做,但最重要的好处是,每个人都保证他在房子里会感到快乐。所以任何想进入房子的人都必须证明他们目前的快乐状态。
作为一个DL专家,为了确保“快乐”规则得到严格的应用,你将构建一个算法,利用前门摄像头的图片来检查这个人是否快乐。只有当一个人高兴的时候,门才打开。
你收集了你朋友和你自己的照片,这些照片是由前门摄像头拍摄的。数据集已标记标签。
运行下面的代码归一化数据集,了解它的形状。
X_train_orig, Y_train_orig, X_test_orig, Y_test_orig, classes = load_dataset()# Normalize image vectors
X_train = X_train_orig/255.
X_test = X_test_orig/255.# Reshape
Y_train = Y_train_orig.T
Y_test = Y_test_orig.Tprint ("number of training examples = " + str(X_train.shape[0]))
print ("number of test examples = " + str(X_test.shape[0]))
print ("X_train shape: " + str(X_train.shape))
print ("Y_train shape: " + str(Y_train.shape))
print ("X_test shape: " + str(X_test.shape))
print ("Y_test shape: " + str(Y_test.shape))
运行结果
Using TensorFlow backend.
number of training examples = 600
number of test examples = 150
X_train shape: (600, 64, 64, 3)
Y_train shape: (600, 1)
X_test shape: (150, 64, 64, 3)
Y_test shape: (150, 1)
笑脸数据集细节
- 图片形状(64,64,3)
- 训练集:600张图片
- 测试集:150张图片
现在是时间来解决笑脸问题了。
2- 在Keras中构建模型
Keras非常适合于快速建型。在很短的时间内,你将能够建立一个模型,取得显著的成果。
例如
def model(input_shape):# Define the input placeholder as a tensor with shape input_shape. Think of this as your input image!X_input = Input(input_shape)# Zero-Padding: pads the border of X_input with zeroesX = ZeroPadding2D((3, 3))(X_input)# CONV -> BN -> RELU Block applied to XX = Conv2D(32, (7, 7), strides = (1, 1), name = 'conv0')(X)X = BatchNormalization(axis = 3, name = 'bn0')(X)X = Activation('relu')(X)# MAXPOOLX = MaxPooling2D((2, 2), name='max_pool')(X)# FLATTEN X (means convert it to a vector) + FULLYCONNECTEDX = Flatten()(X)X = Dense(1, activation='sigmoid', name='fc')(X)# Create model. This creates your Keras model instance, you'll use this instance to train/test the model.model = Model(inputs = X_input, outputs = X, name='HappyModel')return model
请注意,Keras对变量名使用的约定与numpy和TensorFlow使用的约定不同。
特别是,对于不同层的计算,Keras不是在前向传播的每个步骤(如X、Z1、A1、Z2、A2等)上创建和分配一个新变量,而是在代码中使用X=….将X重新分配给一个新值。换而言之,在前向传播的每一步,我们只是把计算中的最新值写到同一个变量X中。唯一的例外是X_input,我们将其单独保存,并且不会覆盖它,因为我们需要在最后创建Keras模型实例用到它(上面的model = Model(inputs = X_input, outputs = X, name='HappyModel')
)。
练习:实现HappyModel()。本次练习比以往的都要开放。我们建议你从使用我们建议的架构实现一个模型开始,并使用它作为初始模型来完成本任务的其余部分。但是在那之后,你可以再尝试其他模型架构。例如,
- 你可以从上面的模型中获得灵感,根据自己的需要改变网络体系结构和超参数。
- 你也可以使用其他函数, AveragePooling2D(), GlobalMaxPooling2D(), Dropout()。
注意:你必须关注数据的形状。利用你在课程中学到的知识,确保你的卷积层、池层和完全连接层与你要应用它的卷相适应。
实现代码
# GRADED FUNCTION: HappyModeldef HappyModel(input_shape):"""Implementation of the HappyModel. 实现一个检测笑脸的模型Arguments:input_shape -- shape of the images of the datasetReturns:model -- a Model() instance in Keras Keras的模型实例"""### START CODE HERE #### Feel free to use the suggested outline in the text above to get started, and run through the whole# exercise (including the later portions of this notebook) once. The come back also try out other# network architectures as well. # Define the input placeholder as a tensor with shape input_shape. Think of this as your input image!X_input = Input(input_shape)# Zero-Padding: pads the border of X_input with zeroes #0填充:X_input的周围填充0X = ZeroPadding2D((3, 3))(X_input)# CONV -> BN -> RELU Block applied to X#对X使用 CONV -> BN -> RELU 块X = Conv2D(32, (7, 7), strides=(1, 1), name='conv0')(X)X = BatchNormalization(axis=3, name='bn0')(X)X = Activation('relu')(X)# MAXPOOL #最大值池化层X = MaxPooling2D((2, 2), name='max_pool')(X)# FLATTEN X (means convert it to a vector) + FULLYCONNECTED#降维,矩阵转化为向量 + 全连接层X = Flatten()(X)X = Dense(1, activation='sigmoid', name='fc')(X)# Create model. This creates your Keras model instance, you'll use this instance to train/test the model.#创建模型,讲话创建一个模型的实体,我们可以用它来训练、测试。model = Model(inputs=X_input, outputs=X, name='HappyModel')return model### END CODE HERE ###return model
现在你已经构建了一个函数来描述你的模型。要训练和测试此模型,在Keras中有四个步骤:
- 调用上面的函数创建模型
- 使用
model.compile(optimizer = "...", loss = "...", metrics = ["accuracy"])
编译模型 - 使用
model.fit(x = ..., y = ..., epochs = ..., batch_size = ...)
再训练集上训练数据 - 使用
model.evaluate(x = ..., y = ...)
在测试集上测试数据
如果你想了解model.compile(), model.fit(), model.evaluate() 和他们的参数, 请参考官方文档。
练习:完成第一步,创建模型。
### START CODE HERE ### (1 line)
happyModel = HappyModel(X_train.shape[1:])
### END CODE HERE ###
练习:完成第二步,编译模型配置学习过程。compile()选择3个参数。提示:笑脸挑战是一个二元分类问题。
### START CODE HERE ### (1 line)
happyModel.compile('adam', 'binary_crossentropy', metrics=['accuracy'])
### END CODE HERE ###
练习:训练模型。选择迭代次数和batch大小。
### START CODE HERE ### (1 line)
happyModel.fit(X_train, Y_train, epochs=40, batch_size=50)
### END CODE HERE ###
结果
Epoch 1/40
600/600 [==============================] - 10s 16ms/step - loss: 1.6800 - accuracy: 0.5833
Epoch 2/40
600/600 [==============================] - 6s 10ms/step - loss: 0.3476 - accuracy: 0.8667
Epoch 3/40
600/600 [==============================] - 7s 11ms/step - loss: 0.1826 - accuracy: 0.9283
Epoch 4/40
600/600 [==============================] - 7s 12ms/step - loss: 0.1583 - accuracy: 0.9483
Epoch 5/40
600/600 [==============================] - 7s 11ms/step - loss: 0.0985 - accuracy: 0.9650
Epoch 6/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0996 - accuracy: 0.9700
Epoch 7/40
600/600 [==============================] - 6s 11ms/step - loss: 0.0849 - accuracy: 0.9733
Epoch 8/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0639 - accuracy: 0.9833
Epoch 9/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0649 - accuracy: 0.9800
Epoch 10/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0637 - accuracy: 0.9850
Epoch 11/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0498 - accuracy: 0.9867
Epoch 12/40
600/600 [==============================] - 6s 11ms/step - loss: 0.0433 - accuracy: 0.9883
Epoch 13/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0486 - accuracy: 0.9883
Epoch 14/40
600/600 [==============================] - 6s 11ms/step - loss: 0.0393 - accuracy: 0.9917
Epoch 15/40
600/600 [==============================] - 6s 11ms/step - loss: 0.0347 - accuracy: 0.9883
Epoch 16/40
600/600 [==============================] - 6s 11ms/step - loss: 0.0322 - accuracy: 0.9933
Epoch 17/40
600/600 [==============================] - 7s 11ms/step - loss: 0.0353 - accuracy: 0.9900
Epoch 18/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0431 - accuracy: 0.9900
Epoch 19/40
600/600 [==============================] - 6s 11ms/step - loss: 0.0322 - accuracy: 0.9950
Epoch 20/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0252 - accuracy: 0.9933
Epoch 21/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0232 - accuracy: 0.9950
Epoch 22/40
600/600 [==============================] - 6s 11ms/step - loss: 0.0248 - accuracy: 0.9933
Epoch 23/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0248 - accuracy: 0.9950
Epoch 24/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0254 - accuracy: 0.9917
Epoch 25/40
600/600 [==============================] - 6s 11ms/step - loss: 0.0216 - accuracy: 0.9950
Epoch 26/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0220 - accuracy: 0.9917
Epoch 27/40
600/600 [==============================] - 6s 11ms/step - loss: 0.0342 - accuracy: 0.9883
Epoch 28/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0496 - accuracy: 0.9833
Epoch 29/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0549 - accuracy: 0.9733
Epoch 30/40
600/600 [==============================] - 6s 11ms/step - loss: 0.0246 - accuracy: 0.9950
Epoch 31/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0226 - accuracy: 0.9950
Epoch 32/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0154 - accuracy: 0.9967
Epoch 33/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0153 - accuracy: 0.9950
Epoch 34/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0156 - accuracy: 0.9967
Epoch 35/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0206 - accuracy: 0.9950
Epoch 36/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0141 - accuracy: 0.9967
Epoch 37/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0304 - accuracy: 0.9900
Epoch 38/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0168 - accuracy: 0.9950
Epoch 39/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0154 - accuracy: 0.9950
Epoch 40/40
600/600 [==============================] - 6s 10ms/step - loss: 0.0083 - accuracy: 0.9983
练习:运行第四步,测试模型
### START CODE HERE ### (1 line)
preds = happyModel.evaluate(X_test, Y_test, batch_size=32, verbose=1, sample_weight=None)
### END CODE HERE ###
print()
print ("Loss = " + str(preds[0]))
print ("Test Accuracy = " + str(preds[1]))
运行结果
150/150 [==============================] - 1s 4ms/stepLoss = 0.23825763702392577
Test Accuracy = 0.8733333349227905
如果你的模型happyModel()正常,你可以发现它在训练集和测试集上效果应该比随机猜测的50%准确率要高。
为了方便你对比,我们的模型在40个周期内得到了87.3%的测试准确率(和99%的训练精度),batch的大小是16,使用adam算法优化器。虽然我们的模型在2-5个时期之后就有了不错的精确度,如果你比较不同的模型,你也可以在几个时期训练各种模型,看看它们效果对比。
如果你的准确率没有达到75%,这里有些操作可以帮助你达到它
- 使用多个CONV->BATCHNORM->RELU块,例如下面代码,直到你的高度和宽度尺寸非常小,你的通道数量相当大(例如≈32)。你已经把很多有用信息编入包含很多通道的卷中。你可以扁平化卷,并使用一个全连接层。
X = Conv2D(32, (3, 3), strides = (1, 1), name = 'conv0')(X)
X = BatchNormalization(axis = 3, name = 'bn0')(X)
X = Activation('relu')(X)
- 你可以在上面的块后面使用最大值池化层,它将会减少宽、高的维度。
- 改变优化器,这里我们使用的Adam效果很不错
- 如果模型难以运行,并且遇到了内存不够的问题,那么就降低batch_size(12通常是一个很好的折中方案)
- 运行更多迭代次数,直到训练准确率稳定
即便你的准确率达到 75% ,你也可以继续努力以达到更好的效果。
注意:如果你在模型上调试超参,你的测试集实际上变成了开发集,你的模型最终可能在测试/开发集上过拟合。不过对于本次编程练习,我们在这里不需要担心。
3- 总结
恭喜你,你已经完成了笑脸问题的挑战。
现在,你需要把这个模型导入屋子前面的摄像头。在这里,我们不详谈如何做了。
- Keras是我们推荐给你快速建模的工具。它可以让你快速的尝试不同的模型架构。你是否希望使用Keras将深度学习应用到你的日常生活中?
- 请记住Keras中创建模型的4步,Create->Compile->Fit/Train->Evaluate/Test.