strint 2018-10-17
由于深度学习在许多类型的数据中具有高水平的性能,因此它正成为机器学习的一个非常受欢迎的子集。使用深度学习对图像进行分类的一种好方法是构建卷积神经网络(CNN)。Python中的Keras库使构建CNN变得非常简单。
计算机使用像素查看图像。图像中的像素通常是相关的。例如,某组像素可以表示图像中的边缘或某种其他图案。Convolutions可以帮助识别图像。
卷积将像素矩阵与filter矩阵或“核”相乘,并将乘法值相加,然后卷积滑到下一个像素并重复相同的过程,直到所有图像像素都被覆盖。该过程在下面可视化。(对于一个介绍深度学习和神经网络,你可以参考的深度学习文章在这里(https://www.toutiao.com/item/6610192166901776909/)。
在本教程中,我们将使用流行的mnist数据集。该数据集包含70,000个0-9手写数字图像。我们将尝试使用卷积神经网络(CNN)识别它们。
mnist数据集是Keras库的一部分,因此我们可以轻松加载数据集。在数据集中提供的70,000张图像中,60,000张用于训练,10,000张用于测试。
当我们加载下面的数据集时,X_train和X_test将包含图像,y_train和y_test将包含这些图像所代表的数字。
from keras.datasets import mnist #download mnist data and split into train and test sets (X_train, y_train), (X_test, y_test) = mnist.load_data()
现在让我们看一下我们数据集中的一个图像,我们将在数据集中绘制第一个图像,并使用'shape'函数检查其大小。
import matplotlib.pyplot as plt #plot the first image in the dataset plt.imshow(X_train[0])
#check image shape X_train[0].shape
默认情况下,mnist数据集中每个图像的形状为28 x 28,因此我们不需要检查所有图像的形状。使用真实世界的数据集时,您可能不会那么幸运。28 x 28也是一个相当小的尺寸,因此CNN将能够很快地在每个图像上运行。
接下来,我们需要将数据集输入(X_train和X_test)reshape为我们神经网络模型在训练模型时所期望的形状。第一个参数是图像数量(X_train为60,000,X_test为10,000)。然后是每个图像的形状(28x28)。最后一个参数是1,表示图像是灰度的。Python代码如下:
#reshape data to fit model X_train = X_train.reshape(60000,28,28,1) X_test = X_test.reshape(10000,28,28,1)
我们需要对我们的目标变量进行“one-hot编码”。这意味着将为每个输出类别创建一列,并为每个类别输入二进制变量。例如,我们看到数据集中的第一个图像是5.这意味着我们数组中的第六个数字将为1,而数组的其余部分将填充为0。
from keras.utils import to_categorical #one-hot encode target column y_train = to_categorical(y_train) y_test = to_categorical(y_test) y_train[0]
现在我们准备建立我们的神经网络模型。这是Python代码:
from keras.models import Sequential from keras.layers import Dense, Conv2D, Flatten #create model model = Sequential() #add model layers model.add(Conv2D(64, kernel_size=3, activation=’relu’, input_shape=(28,28,1))) model.add(Conv2D(32, kernel_size=3, activation=’relu’)) model.add(Flatten()) model.add(Dense(10, activation=’softmax’))
我们将使用的模型类型是Sequential。Sequential是在Keras中构建模型的最简单方法。它允许您逐层构建模型。
我们使用' add() '函数向模型添加层。
我们的前两层是Conv2D层,卷积层,它们将处理我们的输入图像,这些图像被视为二维矩阵。
第一层中的64和第二层中的32是每层中的节点数。根据数据集的大小,可以将此数字调整为更高或更低。在我们的例子中,64和32运行良好。
Kernel size是我们卷积的filter矩阵的大小。所以核大小为3意味着我们将拥有一个3x3filter矩阵。请参阅介绍和第一张图片,以了解相关信息。
Activation 是层的激活函数。我们将在前两层使用的激活函数是ReLU。这种激活函数已被证明在神经网络中很有效。
我们的第一层也采用输入形状。这是每个输入图像的形状,如前面所见28,28,1,其中1表示图像是灰度的。
在Conv2D层和Dense层之间,存在“Flatten”层。Flatten用作卷积层和Dense层之间的连接。
'Dense'是我们将用于输出层的层类型。Dense是标准层类型,在许多情况下用于神经网络。
我们的输出层将有10个节点,每个节点对应一个可能的结果(0-9)。
激活是'softmax'。Softmax使输出总和达到1,因此输出可以解释为概率。然后,模型将基于哪个选项具有最高概率来进行预测。
接下来,我们需要编译我们的模型。编译模型需要三个参数:优化器,损失和度量。
优化器控制学习率。我们将使用'adam'作为我们的优化器。在许多情况下,Adam通常是一个很好的优化器。adam优化器会在整个训练过程中调整学习率。
学习率决定了计算模型的最佳权重的速度。较小的学习率可能会导致更准确的权重(达到某一点),但计算权重所需的时间会更长。
我们将使用'categorical_crossentropy'来表示我们的损失函数。这是分类的最常见选择。分数越低表示模型表现越好。
为了使事情更容易解释,我们将使用“accuracy”指标在我们训练模型时查看验证集上的准确度分数。
#compile model using accuracy to measure model performance model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
现在我们将训练我们的模型。我们将在模型上使用'fit()'函数,其中包含以下参数:训练数据(train_X),目标数据(train_y),验证数据和epochs数。
对于我们的验证数据,我们将使用在我们的数据集中提供给我们的测试集,我们将其分为X_test和y_test。
epochs数是模型循环数据的次数。我们运行的epochs越多,模型就会越多,直到某一点。在那之后,模型将在每个epoch停止改进。对于我们的模型,我们将epochs数设置为3。
#train the model model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=3)
经过3个epochs,我们的验证集合的准确率达到了97.57%。恭喜,您现在已经建立了CNN!
如果您想查看我们的模型为测试数据做出的实际预测,我们可以使用预测函数。预测函数将给出一个包含10个数字的数组。这些数字是输入图像代表每个数字(0-9)的概率。具有最高编号的数组索引表示模型预测。每个数组的总和等于1(因为每个数字是一个概率)。
为了表明这一点,我们将展示测试集中前4个图像的预测。
注意:如果我们有新数据,我们可以将新数据输入到预测函数中,以查看我们的模型对新数据的预测。由于我们没有任何新的看不见的数据,我们现在将使用测试集显示预测。
#predict first 4 images in the test set model.predict(X_test[:4])
我们可以看到我们的模型预测了前四幅图像的7,2,1和0。
让我们将其与实际结果进行比较。
#actual results for first 4 images in test set y_test[:4]
实际结果表明前四个图像也是7,2,1和0.我们的模型正确预测!