65.9K
CodeProject 正在变化。 阅读更多。
Home

Keras 入门

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (4投票s)

2020年6月22日

CPOL

6分钟阅读

viewsIcon

9513

downloadIcon

158

本文将深入探讨Keras,一个用于神经网络的高级库。

这是我们学习Python及其在机器学习和人工智能中应用的系列文章中的第七个模块。在上一个模块中,我们讨论了NLTK在文本分析中的应用。现在,让我们深入了解Keras,一个用于神经网络的高级库。

安装

使用Anaconda的conda install安装Keras非常简单

conda install keras

这会立即安装您需要的所有依赖项。

后端配置

Keras可以使用几个可用的库之一作为其后端,后端负责处理张量等底层操作。我们将使用TensorFlow,这是默认选项。

首先,我们将对TensorFlow的配置进行一些小调整。具体来说,我们将`allow_growth`选项设置为true,这允许TensorFlow动态地增长使用的GPU内存,而不是提前分配所有内存。否则,TensorFlow可能会尝试分配过多的内存,导致您的GPU立即耗尽内存(对我来说是这样)。要做到这一点,请将以下代码放在文件的开头

如果您的后端是TensorFlow 1.x

from keras.backend.tensorflow_backend import set_session
import tensorflow as tf
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
set_session(tf.Session(config=config))

对于TensorFlow 2.x,您必须为您的GPU调用set_memory_growth函数。您可以在tf.config.experimental.set_memory_growth文档中阅读更多关于这背后的细节。

您拥有哪个版本?通过运行conda list命令查看您的TensorFlow版本。在一台计算机上我得到的是1.13.1,在另一台计算机上我得到的是2.1.0,即使使用了相同的Anaconda安装命令。

如果您想强制Keras使用CPU而不是GPU,请在第一次导入Keras之前添加此内容

import os
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'

这比GPU慢得多,但如果您没有多少GPU内存,您可能需要这样做。

使用Keras进行图像分类

我们将演示Keras在图像分类中的应用,使用Intel图像分类数据集。该数据集包含六个类别的图像,分布在六个不同的目录中,这非常方便,因为Keras提供了内置功能来处理该格式的数据。

虽然您不必过多担心神经网络背后的数学原理,但您确实需要充分理解,因为您必须精确指定模型由哪些层组成。

Keras提供的模型之一是顺序模型,即层的堆栈。创建顺序模型并添加层非常容易

from keras.models import Sequential

model = Sequential()
model.add(layer_one)
model.add(layer_two)
# ...

这是我们的图像分类模型的外观

from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Dropout, Flatten, Dense
from keras.layers.normalization import BatchNormalization

model = Sequential()

model.add(Conv2D(32, kernel_size=(3, 3), activation="relu", input_shape=(150, 150, 3))) # our images are 150*150
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(BatchNormalization())

model.add(Conv2D(64, kernel_size=(3, 3), activation="relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(BatchNormalization())

model.add(Conv2D(128, kernel_size=(3, 3), activation="relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(BatchNormalization())

model.add(Flatten())
model.add(Dense(128, activation="relu"))
model.add(Dropout(0.15))
model.add(Dense(64, activation="relu"))
model.add(Dense(6, activation="softmax"))

神经网络模型的构建超出了本模块的范围,但简而言之:在图像分类问题的第一步通常采用卷积层(随着模式变得更复杂,滤波器的数量会增加)、最大池化层和批归一化重复的模式。该步骤的输出是多维的,我们使用Flatten层将其展平为一维向量。最后,我们添加几个密集连接层,中间有一个dropout层以帮助对抗过拟合。最后一层必须输出一个包含六个元素的向量,因为我们有六个类别。

接下来,我们编译模型,这意味着我们配置它进行训练

model.compile(loss='sparse_categorical_crossentropy',
          	   optimizer='adam',
          	   metrics=['accuracy'])

我们的损失函数sparse_categorical_crossentropy非常适合类别之间没有重叠的分类问题。有关损失函数的完整讨论,请参阅Keras文档。我们正在使用Adam优化器。优化器的完整列表可以在相关的文档中找到。而metrics指定了模型在训练和测试期间评估的内容。

拟合模型

现在我们有了模型的结构,我们可以将其拟合到我们的数据集。

from keras.preprocessing.image import ImageDataGenerator

datagen = ImageDataGenerator(validation_split=0.2)
train_generator = 
    datagen.flow_from_directory("intel-images/seg_train/seg_train", 
    batch_size=32, target_size=(150,150), class_mode="sparse", 
    subset="training")
validation_generator = 
    datagen.flow_from_directory("intel-images/seg_train/seg_train", 
    batch_size=32, target_size=(150, 150), class_mode="sparse", 
    subset="validation")
model.fit_generator(train_generator, epochs=40, 
                    validation_data=validation_generator)

(如果您想更快地完成过程,可以随意减少epochs的数量,精度也会降低,尤其是在使用CPU时。40个epochs需要相当长的时间。)

根据Keras文档,这是ImageDataGenerator的作用

生成具有实时数据增强的张量图像数据批次。数据将被循环(分批)。

我们的示例不进行任何数据增强。我们稍后将介绍该功能。

在前面的代码中,validation_split=0.2意味着我们将使用20%的训练集进行验证。由于数据集只包含训练集和测试集,因此我们必须使用训练集的子集作为验证集。

flow_from_directory是一个很棒的内置函数,非常适合我们这样的数据集结构:每个类别一个子目录。

class_mode="sparse"意味着我们正在处理一维整数标签。

fit_generator以我们指定的epoch数量将模型拟合到ImageDataGenerator

测试模型

训练后,我们可以使用evaluate_generator函数测试模型。就像fit_generator一样,它接受一个生成器作为参数。我们可以为我们的测试数据创建一个生成器,类似于我们为训练数据所做的

test_datagen = ImageDataGenerator()
test_generator = 
    datagen.flow_from_directory(
        "intel-images/seg_test/seg_test", 
        target_size=(150,150), class_mode="sparse")
print(model.evaluate_generator(test_generator))

对于我们的示例,这将返回一个包含两个值的数组:损失和准确率。(您可以通过查看model.metrics_names值来检查这一点。)

我的准确率为81.7%,对于一个相对简单的模型在非平凡数据集上来说,这还不错。

生成预测

您现在可以使用model.predict方法对任何图像生成预测。此方法接受图像的NumPy数组作为输入,其中图像也是一个形状为(150, 150, 3)的NumPy数组。要对单个图像进行预测,您可以这样做

import skimage.io
import numpy as np

model.predict(np.expand_dims(skimage.io.imread("file.jpg"), axis=0))

skimage.io.imread将读取图像,expand_dims将为数组添加另一个维度。输出是一个预测数组,其中每个预测都是一个数组,表示每个类别的概率。

数据增强

数据增强是指根据现有训练集生成新的训练数据,以提高准确率和泛化能力,并减少过拟合。

对于图像,可以通过对图像进行各种变换来进行数据增强:旋转、翻转、缩放、平移、剪切等。

ImageDataGenerator使这变得容易。要将数据增强应用于我们的模型,只需更改两行代码。

首先,使用更多参数实例化ImageDataGenerator,指定我们想要进行的变换

datagen = ImageDataGenerator(rotation_range=30, 
                             horizontal_flip=True, 
                             zoom_range=0.2, 
                             shear_range=0.2)

还有更多可能性——有关参数的完整列表,请参阅图像预处理文档

第二行是fit_generator调用。此函数具有可选的steps_per_epochvalidation_steps参数,我们以前可以省略它们,因为我们有固定数量的训练样本。有了数据增强,我们可能有更多的训练样本,所以我们必须指定我们想使用多少。如果我们不这样做,该函数将只使用我们固定大小的样本集。一个步骤对应于给定batch_size的一个批次。

model.fit_generator(train_generator, epochs=40, 
                    validation_data=validation_generator, 
                    steps_per_epoch=1600, validation_steps=32)

同样,如果您希望过程更快,可以随时减少epochs数量或步骤数量。在训练2-3小时后,我的准确率为85.5%。

保存和恢复模型

Keras允许您以HDF5格式保存训练好的模型

model.save("images_model.h5")

恢复模型也只需一行代码

import keras.models
model = keras.models.load_model("images_model.h5")

这需要h5py包,如果您使用了conda install,它应该已经被安装了。如果您没有它,请在Jupyter Notebook单元格中运行此pip命令

!pip install --upgrade h5py

后续步骤

在本模块中,我们通过一个图像分类问题演示了Keras的使用。Keras提供了比我们这里使用的更多的层。如果您想深入研究,可以使用Keras文档作为起点。它还提供了许多常见深度学习问题的示例。

下一个模块中,我们将简要介绍TensorFlow、NumPy和scikit-learn。

© . All rights reserved.