Keras教程:使用Keras开始深度学习和Python(下)

徐大白
4周前 阅读 257 点赞 5

在这个Keras教程中,您将发现开始使用深度学习和Python是多么容易。您将使用Keras深度学习库来在自定义图像数据集上训练您的第一个神经网络,并且您也将实现第一个卷积神经网络(CNN)。

我将给大家带来一个全新的与众不同的Keras教程。

我将教你如何利用这些预先编译的数据集,而不是教你如何使用定制的数据集来训练你的第一个神经网络和卷积神经网络,说实话,你的目标是将深度学习应用到你自己的数据集,而不是内置的Keras,我说的对吗?

引言

今天的Keras教程是针对实践人员设计的——这是实践人员应用深度学习的方法。

在本文的上半部分,我们介绍了前5个步骤,

  1. 在系统上安装Keras和其他依赖项
  2. 从磁盘加载数据
  3. 创建训练和测试分支
  4. 定义您的Keras模型体系结构
  5. 编译你的Keras模型

今天要讨论的是第6.7.8个步骤,包括

6.训练你的训练数据模型

7.在测试数据上评估模型

8.用训练的Keras模型进行预测

6.将您的CARAS模型拟合到数据

图8:在Keras教程的第6步中,我们使用我们的训练数据和编译模型来训练一个深度学习模型。

现在,我们的Keras模型被编译,我们可以“ fit ”(即训练)它对我们的训练数据:

# train the neural network
H = model.fit(trainX, trainY, validation_data=(testX, testY),
	epochs=EPOCHS, batch_size=32)

我们讨论了所有的输入,除了 batch_size 大小。batch_size 控制每个数据组的大小以通过网络。较大的GPU将能够容纳较大的批量大小。我建议从3264为基础开始,再慢慢上升。

7.评估你的Keras模型

图9:在我们拟合模型之后,我们可以使用我们的测试数据进行预测并生成分类报告

我们已经训练了我们的实际模型,但是现在我们需要在测试数据上进行评估。

我们评估测试数据很重要,这样我们就可以得到一个无偏(或者尽可能接近无偏)的表示,来表示我们的模型如何很好地处理从未受过训练的数据。

为了评估我们的Keras模型,我们可以使用模型的.predict 预测方法和来自scikit-learning的classfication_report 的组合:

# evaluate the network
print("[INFO] evaluating network...")
predictions = model.predict(testX, batch_size=32)
print(classification_report(testY.argmax(axis=1),
	predictions.argmax(axis=1), target_names=lb.classes_))
 
# plot the training loss and accuracy
N = np.arange(0, EPOCHS)
plt.style.use("ggplot")
plt.figure()
plt.plot(N, H.history["loss"], label="train_loss")
plt.plot(N, H.history["val_loss"], label="val_loss")
plt.plot(N, H.history["acc"], label="train_acc")
plt.plot(N, H.history["val_acc"], label="val_acc")
plt.title("Training Loss and Accuracy (Simple NN)")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend()
plt.savefig(args["plot"])

在运行这个脚本时,您将注意到我们的Keras神经网络将开始训练,并且一旦训练完成,我们将在我们的测试集上评估网络:

$ python train_simple_nn.py --dataset animals --model output/simple_nn.model \
	--label-bin output/simple_nn_lb.pickle --plot output/simple_nn_plot.png
Using TensorFlow backend.
[INFO] loading images...
[INFO] training network...
Train on 2250 samples, validate on 750 samples
Epoch 1/75
2250/2250 [==============================] - 1s - loss: 1.1033 - acc: 0.3636 - val_loss: 1.0811 - val_acc: 0.3707
Epoch 2/75
2250/2250 [==============================] - 0s - loss: 1.0882 - acc: 0.3862 - val_loss: 1.1292 - val_acc: 0.3227
Epoch 3/75
2250/2250 [==============================] - 0s - loss: 1.0713 - acc: 0.4067 - val_loss: 1.0525 - val_acc: 0.3907
...
Epoch 73/75
2250/2250 [==============================] - 0s - loss: 0.7780 - acc: 0.6067 - val_loss: 0.8438 - val_acc: 0.5813
Epoch 74/75
2250/2250 [==============================] - 0s - loss: 0.7805 - acc: 0.5978 - val_loss: 0.8463 - val_acc: 0.5893
Epoch 75/75
2250/2250 [==============================] - 0s - loss: 0.7765 - acc: 0.6262 - val_loss: 0.8144 - val_acc: 0.6133
[INFO] evaluating network...
             precision    recall  f1-score   support
 
       cats       0.58      0.50      0.54       236
       dogs       0.49      0.50      0.49       236
      panda       0.73      0.81      0.77       278
 
avg / total       0.61      0.61      0.61       750
 
[INFO] serializing network and label binarizer...

这个网络很小,当与一个小数据集结合时,我的CPU上每历时只需要2秒。

在这里你可以看到我们的网络正在获得61%的准确度

由于我们有1/3的机会随机地为给定的图像选择正确的标签,我们知道我们的网络实际上已经学习了可用于区分三个类的模式。

我们还保存了一个绘图:

  • 训练损失
  • 确认损失
  • 训练精度
  • 验证精度

……确保我们可以很容易地发现我们的结果过拟合或欠拟合。

图10:我们简单的神经网络训练脚本(用Keras创建)生成一个准确性/损失图,以帮助我们发现不足/过拟合

看看我们的图表,我们看到少量的过拟合开始发生在过去的 epoch~45,在那里,我们的训练和验证损失开始发散,并出现明显的差距。

最后,我们可以将我们的模型保存到磁盘,这样我们就可以在不必重新训练它的情况下重用它:

# save the model and label binarizer to disk
print("[INFO] serializing network and label binarizer...")
model.save(args["model"])
f = open(args["label_bin"], "wb")
f.write(pickle.dumps(lb))
f.close()

8.使用Keras模型预测新数据

在这一点上,我们的模型是训练的-但如果我们想在我们的网络已经训练之后对图像做出预测,怎么办?

  • 那我们怎么办呢?
  • 我们如何从磁盘加载模型?
  • 如何加载图像并对其进行预处理以进行分类?

predict.py 脚本中,我将演示如何使用,所以打开它并插入下面的代码:

# import the necessary packages
from keras.models import load_model
import argparse
import pickle
import cv2
 
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
	help="path to input image we are going to classify")
ap.add_argument("-m", "--model", required=True,
	help="path to trained Keras model")
ap.add_argument("-l", "--label-bin", required=True,
	help="path to label binarizer")
ap.add_argument("-w", "--width", type=int, default=28,
	help="target spatial dimension width")
ap.add_argument("-e", "--height", type=int, default=28,
	help="target spatial dimension height")
ap.add_argument("-f", "--flatten", type=int, default=-1,
	help="whether or not we should flatten the image")
args = vars(ap.parse_args())

首先,我们将导入所需的包和模块。

无论何时编写脚本以从磁盘加载Keras模型,您都需要显式地从 keras.models导入 load_model 。OpenCV将用于注释和显示。pickle 模块将用于加载我们的标签二值化器。

接下来,让我们解析命令行参数:

  1. --image:我们输入图像的路径。
  2. --model:我们训练和序列化的KRAS模型路径。
  3. --label-bin:序列化标签二进制化器的路径。
  4. --width :我们美国有线电视新闻网的输入形状的宽度。记住,你不能只在这里指定任何东西。您需要指定模型设计的宽度。
  5. --height:输入美国有线电视新闻网图像的高度。指定的高度也必须匹配网络的输入形状。
  6. --flatten :我们是否应该使图像变平。默认情况下,我们不会使图像变平。如果需要平移图像,则应该为这个参数传递1。

接下来,让我们加载图像并根据命令行参数调整它的大小:

# load the input image and resize it to the target spatial dimensions
image = cv2.imread(args["image"])
output = image.copy()
image = cv2.resize(image, (args["width"], args["height"]))

然后,如果需要的话,我们会使图像 flatten

# check to see if we should flatten the image and add a batch
# dimension
if args["flatten"] > 0:
	image = image.flatten()
	image = image.reshape((1, image.shape[0]))
 
# otherwise, we must be working with a CNN -- don't flatten the
# image, simply add the batch dimension
else:
	image = image.reshape((1, image.shape[0], image.shape[1],
		image.shape[2]))

扁平的图像标准的全连接网络是简单的(第30-32行)。

在CNN的例子中,我们还添加了批量尺寸,但我们不扁平化图像(第33-38行)。下一节将介绍一个示例— —CNN。

让我们将模型+标签二值化器加载到内存中并进行预测:

# load the model and label binarizer
print("[INFO] loading network and label binarizer...")
model = load_model(args["model"])
lb = pickle.loads(open(args["label_bin"], "rb").read())
 
# make a prediction on the image
preds = model.predict(image)
 
# find the class label index with the largest corresponding
# probability
i = preds.argmax(axis=1)[0]
label = lb.classes_[i]

我们的模型和标签二值化器通过第42和43行加载。

我们可以通过调用 model.predict 来预测输入image(第46行)。

preds 数组是什么样子的?

(Pdb) preds
array([[5.4622066e-01, 4.5377851e-01, 7.7963534e-07]], dtype=float32)

2D数组包含批处理中的图像的索引(这里只有一个索引,因为只有一个图像被传递到NN中进行分类)和与每个类标签相对应的百分比,如通过查询我的Python调试器中的变量所示:

  • cats :54.6%
  • dogs :45.4%
  • panda :~0%

换言之,我们的网络“认为”它看到“猫”,它肯定是“知道”它看不到“熊猫”。

第50行查找最大值的索引(第0次“猫”索引)。

第51行从标签二值化器中提取“猫”字符串标签。

容易吗?

现在让我们来展示结果:

# draw the class label + probability on the output image
text = "{}: {:.2f}%".format(label, preds[0][i] * 100)
cv2.putText(output, text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7,
	(0, 0, 255), 2)
 
# show the output image
cv2.imshow("Image", output)
cv2.waitKey(0)

我们在第54行格式化 text 字符串。这包括 label 和百分比格式的预测值。

然后我们把 text 放在output 图像上(第55行和第56行)。

最后,我们在屏幕上显示输出图像,并等待直到用户按下第59行和第60行中的任何键(观看Homer Simpson试图定位“any”键)。

我们的预测脚本相当直截了当。

一旦您使用本教程的“下载”部分下载了代码,就可以打开终端并尝试在自定义映像上运行经过训练的网络:

$ python predict.py --image images/cat.jpg --model output/simple_nn.model \
	--label-bin output/simple_nn_lb.pickle --width 32 --height 32 --flatten 1
Using TensorFlow backend.
[INFO] loading network and label binarizer...

确保您从文件夹内相对于脚本复制/粘贴或键入了整个命令(包括命令行参数)。如果你在命令行参数上遇到问题,给这个博客帖子读一读。

图11:在我们的Keras教程中,用一个简单的神经网络正确地分类了一只猫

在这里,您可以看到,我们简单的Keras神经网络已经以55.87%的概率将输入图像分类为“cats”,尽管猫的脸被一块面包部分遮挡。

9.奖励:用Keras训练第一个卷积神经网络

诚然,使用标准的前馈神经网络来分类图像不是一个明智的选择。

相反,我们应该利用设计成对图像的原始像素强度进行操作的卷积神经网络(CNN),并学习可用于以高精度对图像进行分类的鉴别滤波器。

我们今天要讨论的模型是 VGGNET 的一个较小的变体,我称之为“SmallVGGNet”。

VGGNET-like 模型有两个共同的特征:

  1. 仅使用3×3卷积。
  2. 在应用破坏性池操作之前,卷积层在网络体系结构中彼此堆叠得更深。

现在让我们来执行SmallVGGNet。

打开smallvggnet.py 文件并插入以下代码:

# import the necessary packages
from keras.models import Sequential
from keras.layers.normalization import BatchNormalization
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.layers.core import Activation
from keras.layers.core import Flatten
from keras.layers.core import Dropout
from keras.layers.core import Dense
from keras import backend as K

从第2-10行的输入中可以看出,SmallVGGNet所需要的一切都来自Keras。我鼓励大家熟悉Keras文档我的深度学习手册中的每一个。

然后,我们开始定义SmallVGGNet类和 build 方法:

class SmallVGGNet:
	@staticmethod
	def build(width, height, depth, classes):
		# initialize the model along with the input shape to be
		# "channels last" and the channels dimension itself
		model = Sequential()
		inputShape = (height, width, depth)
		chanDim = -1
 
		# if we are using "channels first", update the input shape
		# and channels dimension
		if K.image_data_format() == "channels_first":
			inputShape = (depth, height, width)
			chanDim = 1

我们的类定义在第12行,唯一的 build 方法是在第14行中定义的。

build 需要四个参数:输入图像的width 、高度输入图像的heightdepthclass数。

depth 也可以被认为是频道的数量。我们的图像位于RGB颜色空间中,因此当调用build 方法时,我们将传递3depth

首先,我们初始化一个sequential 模型(第17行)。

然后,我们确定频道排序。Keras支持“channels_last”(即TensorFlow)和“channels_first”(即Theano)排序。第18-25行允许我们的模型支持任何类型的后端。

现在,让我们添加一些层到网络:

		# CONV => RELU => POOL layer set
		model.add(Conv2D(32, (3, 3), padding="same",
			input_shape=inputShape))
		model.add(Activation("relu"))
		model.add(BatchNormalization(axis=chanDim))
		model.add(MaxPooling2D(pool_size=(2, 2)))
		model.add(Dropout(0.25))

这个块添加了第一个CONV => RELU => POOL

我们的第一个CONV层有32个大小为3x3的过滤器。

我们指定第一层的inputshape非常重要,因为所有后续的层次维都将使用向下触发的方法计算。

我们将在这个网络体系结构中使用ReLU(整流线性单元)激活函数。有许多激活方法,我鼓励您熟悉使用Python的“深度学习用于计算机视觉”中的流行方法,其中讨论了优缺点。

还应用了批量标准化、最大池化和辍学。

批量标准化用于在将给定输入卷传递到网络中的下一层之前对它的激活进行标准化。它已被证明在减少训练CNN所需的时间数量以及稳定训练本身方面非常有效。

池层具有逐渐减小输入卷的空间大小(即宽度和高度)到层的主要功能。在CNN体系结构中,在连续的CONV层之间插入池层是常见的。

Dropout 是一个不容忽视的有趣概念。为了迫使网络更加稳定,我们可以应用Dropout,即在层之间断开随机神经元连接的过程。这一过程被证明可以减少过拟合,提高精度,并且允许我们的网络更好地对不熟悉的图像进行泛化。如该参数所示,在每次训练迭代期间,25%的节点连接在层之间被随机断开(退出)。

注意:如果你对深度学习很陌生,这对你来说可能是一种不同的语言。就像学习一种新的口语一样,它需要时间、学习和实践。

继续,我们到达下一个块(CONV= > Relu)* 2 = >POOL:

		# (CONV => RELU) * 2 => POOL layer set
		model.add(Conv2D(64, (3, 3), padding="same"))
		model.add(Activation("relu"))
		model.add(BatchNormalization(axis=chanDim))
		model.add(Conv2D(64, (3, 3), padding="same"))
		model.add(Activation("relu"))
		model.add(BatchNormalization(axis=chanDim))
		model.add(MaxPooling2D(pool_size=(2, 2)))
		model.add(Dropout(0.25))

注意,我们的过滤器尺寸保持不变(3X3,这是常见的问题如网络);然而,我们增加从32到64的过滤器的总数量。

这之后是一个(CONV= > Relu= >POOL)* 3层集合:

        # (CONV => RELU) * 3 => POOL layer set
		model.add(Conv2D(128, (3, 3), padding="same"))
		model.add(Activation("relu"))
		model.add(BatchNormalization(axis=chanDim))
		model.add(Conv2D(128, (3, 3), padding="same"))
		model.add(Activation("relu"))
		model.add(BatchNormalization(axis=chanDim))
		model.add(Conv2D(128, (3, 3), padding="same"))
		model.add(Activation("relu"))
		model.add(BatchNormalization(axis=chanDim))
		model.add(MaxPooling2D(pool_size=(2, 2)))
		model.add(Dropout(0.25))

再次,请注意所有CONV层如何学习3x3过滤器,但是CONV层学习的过滤器总数从64增加到128。在CNN中越深入(并且随着输入的卷越来越小),通常的做法是增加过滤器的总数。

最后我们有一组FC=>Relu层:

		# first (and only) set of FC => RELU layers
		model.add(Flatten())
		model.add(Dense(512))
		model.add(Activation("relu"))
		model.add(BatchNormalization())
		model.add(Dropout(0.5))
 
		# softmax classifier
		model.add(Dense(classes))
		model.add(Activation("softmax"))
 
		# return the constructed network architecture
		return model

全连通层表示为 dense 的Keras。最后一层与三个输出完全连接(因为我们的数据集中有三个 class )。softmax 层返回每个标签的类概率。

既然已经实现了SmallVGGNet,让我们编写将用于在我们的动物数据集上训练它的驱动程序脚本。

这里的大部分代码将与前面的示例类似,但我将:

  • 完整地回顾整个脚本
  • 并消除所有的分歧

打开train_vgg.py脚本,让我们开始:

# set the matplotlib backend so figures can be saved in the background
import matplotlib
matplotlib.use("Agg")
 
# import the necessary packages
from pyimagesearch.smallvggnet import SmallVGGNet
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from keras.preprocessing.image import ImageDataGenerator
from keras.optimizers import SGD
from imutils import paths
import matplotlib.pyplot as plt
import numpy as np
import argparse
import random
import pickle
import cv2
import os

输入与我们以前的训练脚本相同,有两个例外:

我们通过from pyimagesearch.smallvggnet import SmallVGGNet导入的是SmallVGGNetfrom而不是keras.models import Sequential ,略微向上滚动,以查看SmallVGGNet implementation

我们将用ImageDataGenerator来扩充我们的数据。Data augmentation(数据增强) 几乎总是被推荐,并导向更好推广的模型。数据增强涉及添加随机旋转、移位、剪切和缩放到现有的训练数据。你不会看到一堆新的.png.jpg文件——它是在脚本执行时即时完成的。

在这点上,您应该知道其他的导入。如果不是,请参考上面的列表。

让我们解析命令行参数:

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", required=True,
	help="path to input dataset of images")
ap.add_argument("-m", "--model", required=True,
	help="path to output trained model")
ap.add_argument("-l", "--label-bin", required=True,
	help="path to output label binarizer")
ap.add_argument("-p", "--plot", required=True,
	help="path to output accuracy/loss plot")
args = vars(ap.parse_args())

我们有四个命令行参数解析:

  • --dataset:磁盘上的图像数据集的路径。这可以是动物/或以相同方式组织的另一个数据集的路径。
  • --model:我们的模型将被序列化并输出到磁盘。此参数包含输出模型文件的路径。一定要相应地命名您的模型,这样您就不会覆盖任何先前训练的模型(比如简单的神经网络模型)。
  • --labelbin:DataSet 标签被序列化到磁盘,以便于在其他脚本中进行回溯。这是输出标签二值化器文件的路径。
  • -plot:输出训练绘图图像文件的路径。我们将检查这个图以检查数据的过/欠拟合。每次使用参数更改训练模型时,您应该在命令行中指定不同的绘图文件名,以便您在笔记本或笔记本文件中具有与训练笔记相对应的绘图历史。本教程使深度学习看起来很容易,但是请记住,在确定要在此脚本中与您共享的所有参数之前,我经历了几次反复的训练。

让我们加载和预处理我们的数据:

# initialize the data and labels
print("[INFO] loading images...")
data = []
labels = []
 
# grab the image paths and randomly shuffle them
imagePaths = sorted(list(paths.list_images(args["dataset"])))
random.seed(42)
random.shuffle(imagePaths)
 
# loop over the input images
for imagePath in imagePaths:
	# load the image, resize it to 64x64 pixels (the required input
	# spatial dimensions of SmallVGGNet), and store the image in the
	# data list
	image = cv2.imread(imagePath)
	image = cv2.resize(image, (64, 64))
	data.append(image)
 
	# extract the class label from the image path and update the
	# labels list
	label = imagePath.split(os.path.sep)[-2]
	labels.append(label)
 
# scale the raw pixel intensities to the range [0, 1]
data = np.array(data, dtype="float") / 255.0
labels = np.array(labels)

正如简单的神经网络脚本一样,这里我们:

  1. 初始化我们的数据和标签的列表(第35行和第36行)。
  2. 抓取图像并随机洗牌(第31-41行)。在我们排序和洗牌之前,paths.list_image函数将方便地在我们的输入数据集目录中找到所有图像。
  3. 开始在数据集(第44行)中循环所有imagepaths

当我们在每个图像路径上循环时,我们进行:

  1. 将图像加载到内存中(第48行)。
  2. 将图像调整为64×64,这是SmallVGGNet 所需的输入空间维度(第49行)。一个关键的区别是,我们没有平坦化我们的神经网络数据,因为它是卷积的。
  3. 将调整大小的image追加到data(第50行)。
  4. imagepath中提取图像的类label并将其添加到labels列表(第54行和第55行)。

在第58行,我们以阵列形式从范围[0, 255 ]到[0, 1 ]缩放像素强度。

我们还将标签列表转换为Numpy数组格式(第59行)。

然后我们将分割数据并将标签二进制化:

# partition the data into training and testing splits using 75% of
# the data for training and the remaining 25% for testing
(trainX, testX, trainY, testY) = train_test_split(data,
	labels, test_size=0.25, random_state=42)
 
# convert the labels from integers to vectors (for 2-class, binary
# classification you should use Keras' to_categorical function
# instead as the scikit-learn's LabelBinarizer will not return a
# vector)
lb = LabelBinarizer()
trainY = lb.fit_transform(trainY)
testY = lb.transform(testY)

我们对数据进行了75/25次训练和测试分割(第63行和第64行)。我鼓励你尝试的一个实验是把训练分为80/20,看看结果是否显著改变。

标签二进制化发生在第70—72行。这允许一个热编码以及将标签二值化器序列化到脚本后面的pickle文件中。

现在是数据扩充:

# construct the image generator for data augmentation
aug = ImageDataGenerator(rotation_range=30, width_shift_range=0.1,
	height_shift_range=0.1, shear_range=0.2, zoom_range=0.2,
	horizontal_flip=True, fill_mode="nearest")
 
# initialize our VGG-like Convolutional Neural Network
model = SmallVGGNet.build(width=64, height=64, depth=3,
	classes=len(lb.classes_))

在第75-77行,我们初始化我们的图像数据生成器来执行图像增强。

图像增强允许我们通过随机旋转、移位、剪切、缩放和翻转从现有训练数据中构建“附加”训练数据。

数据扩充通常是一个关键步骤:

  1. 避免过拟合
  2. 确保模型推广良好

我建议您始终执行数据扩充,除非您有明确的理由不这样做。

为了构建我们的SmallVGGNet,我们只需调用SmallVGGNet.build ,同时传递必要的参数(第80行和第81行)。

让我们编译和训练我们的模型:

# initialize our initial learning rate, # of epochs to train for,
# and batch size
INIT_LR = 0.01
EPOCHS = 75
BS = 32
 
# initialize the model and optimizer (you'll want to use
# binary_crossentropy for 2-class classification)
print("[INFO] training network...")
opt = SGD(lr=INIT_LR, decay=INIT_LR / EPOCHS)
model.compile(loss="categorical_crossentropy", optimizer=opt,
	metrics=["accuracy"])
 
# train the network
H = model.fit_generator(aug.flow(trainX, trainY, batch_size=BS),
	validation_data=(testX, testY), steps_per_epoch=len(trainX) // BS,
	epochs=EPOCHS)

首先,我们建立我们的学习率,时代的数量,和批次大小(线85-87)。

然后,我们初始化我们的随机梯度下降(SGD)优化器(第92行)。

我们现在准备编译和训练我们的模型(第93-99行)。因为我们正在执行数据增强,所以我们称为model.fit_generator (而不是model.fit)。我们必须以generator(生成器)的训练数据作为第一个参数。生成器将根据我们先前所做的设置产生批量扩充的训练数据。

最后,我们将评估我们的模型,绘制损失/精度曲线,并保存模型:

# evaluate the network
print("[INFO] evaluating network...")
predictions = model.predict(testX, batch_size=32)
print(classification_report(testY.argmax(axis=1),
	predictions.argmax(axis=1), target_names=lb.classes_))
 
# plot the training loss and accuracy
N = np.arange(0, EPOCHS)
plt.style.use("ggplot")
plt.figure()
plt.plot(N, H.history["loss"], label="train_loss")
plt.plot(N, H.history["val_loss"], label="val_loss")
plt.plot(N, H.history["acc"], label="train_acc")
plt.plot(N, H.history["val_acc"], label="val_acc")
plt.title("Training Loss and Accuracy (SmallVGGNet)")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend()
plt.savefig(args["plot"])
 
# save the model and label binarizer to disk
print("[INFO] serializing network and label binarizer...")
model.save(args["model"])
f = open(args["label_bin"], "wb")
f.write(pickle.dumps(lb))
f.close()

我们对测试集进行预测,然后使用scikit-learning计算和打印我们的classification_report(第103-105行)。

利用Matplotlib 绘制损耗/精度曲线-第108~118行显示我的典型绘图设置。第119行将图形保存到磁盘。

最后,我们将我们的模型和标签二值化器保存到磁盘(123-126行)。

让我们继续训练我们的模型。

确保你已经使用了这个博客文章的“下载”部分来下载源代码和示例数据集。

从那里打开一个终端并执行以下命令:

$ python train_vgg.py --dataset animals --model output/smallvggnet.model \
	--label-bin output/smallvggnet_lb.pickle \
	--plot output/smallvggnet_plot.png
Using TensorFlow backend.
[INFO] loading images...
[INFO] training network...
Epoch 1/75
70/70 [==============================] - 3s - loss: 1.3783 - acc: 0.5165 - val_loss: 2.3654 - val_acc: 0.3133
Epoch 2/75
70/70 [==============================] - 2s - loss: 1.0382 - acc: 0.5998 - val_loss: 2.7962 - val_acc: 0.3173
Epoch 3/75
70/70 [==============================] - 2s - loss: 0.9366 - acc: 0.6018 - val_loss: 2.2790 - val_acc: 0.3173
...
Epoch 73/75
70/70 [==============================] - 2s - loss: 0.4402 - acc: 0.8044 - val_loss: 0.4975 - val_acc: 0.7880
Epoch 74/75
70/70 [==============================] - 2s - loss: 0.4306 - acc: 0.8055 - val_loss: 0.6150 - val_acc: 0.7520
Epoch 75/75
70/70 [==============================] - 2s - loss: 0.4179 - acc: 0.8110 - val_loss: 0.5624 - val_acc: 0.7653
[INFO] evaluating network...
             precision    recall  f1-score   support
 
       cats       0.62      0.84      0.71       236
       dogs       0.75      0.50      0.60       236
      panda       0.95      0.92      0.93       278
 
avg / total       0.78      0.77      0.76       750
 
[INFO] serializing network and label binarizer...

当您粘贴命令时,确保您拥有所有命令行参数以避免“使用”错误。如果对于命令行参数是新的,请确保在继续之前阅读它们

在CPU上的训练需要一些时间- epoch 75的每一个都需要一分钟以上。训练将花费一个多小时。

一个GPU将在几分钟内完成这个过程,因为每个时代只需要2秒,如所演示的!

让我们看看在输出/目录中产生的训练图:

图12:我们对Keras精度/损失图的深度学习表明,使用SmallVGNet模型,我们在动物数据上获得了78%的准确性

正如我们的结果所显示的,您可以看到,我们使用卷积神经网络在动物数据集上达到了78%的准确率,显著高于使用标准全连接网络的61%的准确率。

我们也可以应用我们新训练的Keras CNN为例:

$ python predict.py --image images/panda.jpg --model output/smallvggnet.model \
	--label-bin output/smallvggnet_lb.pickle --width 64 --height 64
Using TensorFlow backend.
[INFO] loading network and label binarizer...

图13:我们的深度学习与Keras教程已经展示了我们如何自信地认出熊猫在图像中

我们的CNN非常自信这是一只“熊猫”。我也是,但我只是希望他不要再盯着我看!

让我们试试可爱的小猎犬:

$ python predict.py --image images/dog.jpg --model output/smallvggnet.model \
	--label-bin output/smallvggnet_lb.pickle --width 64 --height 64
Using TensorFlow backend.
[INFO] loading network and label binarizer...

图14:猎犬被识别为狗,使用Keras、TensorFlow和Python。我们的Keras教程已经介绍了用于深度学习的基础知识,但它只是划破了领域的表面

一对比格犬是我家庭和童年的一部分。我很高兴我在网上找到的这只比格犬照片被认作是狗!

我可以用一个类似的CNN在我的电脑上找到我的猎犬的狗的照片。

事实上,在Google Photos中,如果你在搜索框中键入“dog”,你的照片库中的狗的图片将会被返回——我敢肯定,CNN已经被用于图像搜索引擎的特性。图像搜索引擎并不是CNN的唯一用例——我敢打赌你的大脑已经开始想出各种各样的应用深度学习的想法。

总结

在今天的教程中,您学习了如何开始使用Keras、深度学习和Python。

具体地说,您了解了使用Keras和您自己的自定义数据集的七个关键步骤:

  1. 如何从磁盘加载数据
  2. 如何创建训练和测试分支
  3. 如何定义Keras模型体系结构
  4. 如何编译和编写Keras模型
  5. 如何训练你的训练数据模型
  6. 如何评估测试数据的模型
  7. 如何利用训练的Keras模型进行预测

您还学习了如何实现卷积神经网络,使您能够获得比标准全连接网络更高的精度。


原文链接:Keras Tutorial: How to get started with Keras, Deep Learning, and Python

翻译:徐大白



| 5
登录后可评论,马上登录吧~
评论 ( 1 )
像徐大神学习
回复
4周前