使用 TensorFlow 和 Keras
TensorFlow 非常适合为程序员提供的灵活性和强大功能。这样做的一个缺点是原型模型和迭代各种测试对程序员来说可能很麻烦。 Keras 是深度学习库的包装器,可以更轻松地处理模型的各个方面并使编程更容易。在这里,我们选择在 TensorFlow 之上使用 Keras。事实上,使用带有 TensorFlow 后端的 Keras 非常受欢迎,TensorFlow 中有一个 Keras 库。对于这个秘籍,我们将使用该 TensorFlow 库在 MNIST 数据集上进行完全连接的神经网络和简单的 CNN 图像网络。
做好准备
对于这个秘籍,我们将使用驻留在 TensorFlow 内部的 Keras 函数。 Keras( https://keras.io/ )已经是一个可以安装的独立 python 库了。如果您选择使用纯 Keras 路线,则必须为 Keras 选择后端(如 TensorFlow)。
在本文中,我们将在 MNIST 图像识别数据集上执行两个单独的模型。第一个是直接完全连接的神经网络,而第二个是从第 8 章第 2 节“实现简单的 CNN”复制我们的 CNN 网络。
操作步骤
- 我们将首先为脚本加载必要的库。
import tensorflow as tf
from sklearn.preprocessing import MultiLabelBinarizer
from keras.utils import to_categorical
from tensorflow import keras
from tensorflow.python.framework import ops
ops.reset_default_graph()
# Load MNIST data
from tensorflow.examples.tutorials.mnist import input_data
- 我们可以在 TensorFlow 中使用提供的 MNIST 数据导入函数加载库。虽然原始 MNIST 图像是 28 像素乘 28 像素,但导入的数据是它们的扁平版本,其中每个观察是 0 到 1 之间的 784 个灰度点的行.y 标签作为 0 到 9 之间的整数导入。
mnist = input_data.read_data_sets("MNIST_data/")
x_train = mnist.train.images
x_test = mnist.test.images
y_train = mnist.train.labels
y_test = mnist.test.labels
y_train = [[i] for i in y_train]
y_test = [[i] for i in y_test]
- 我们现在将使用 scikit-learn 的
MultiLabelBinarizer()
函数将目标整数转换为单热编码向量,如下所示:
one_hot = MultiLabelBinarizer()
y_train = one_hot.fit_transform(y_train)
y_test = one_hot.transform(y_test)
- 我们将创建一个三层完全连接的神经网络,其中包含 32,16 和 10 个相应的隐藏节点。然后最终输出的大小为 10(每个数字一个)。我们使用以下代码创建此网络:
# We start with a 'sequential' model type (connecting layers together)
model = keras.Sequential()
# Adds a densely-connected layer with 32 units to the model, followed by an ReLU activation.
model.add(keras.layers.Dense(32, activation='relu'))
# Adds a densely-connected layer with 16 units to the model, followed by an ReLU activation.
model.add(keras.layers.Dense(16, activation='relu'))
# Add a softmax layer with 10 output units:
model.add(keras.layers.Dense(10, activation='softmax'))
- 为了训练模型,我们接下来要做的就是使用适当的参数调用
compile()
方法。我们需要的参数是优化函数和损失类型。但我们也想记录模型的准确率,因此度量列表包括accuracy
参数。
model.compile(optimizer=tf.train.AdamOptimizer(0.001),
loss='categorical_crossentropy',
metrics=['accuracy'])
- 这将导致输出应类似于以下内容:
Epoch 1/5
64/55000 [..............................] - ETA: 1:44 - loss: 2.3504 - acc: 0.0625
3776/55000 [=>............................] - ETA: 2s - loss: 1.7904 - acc: 0.3676
...
47104/55000 [========================>.....] - ETA: 0s - loss: 0.1337 - acc: 0.9615
50880/55000 [==========================>...] - ETA: 0s - loss: 0.1336 - acc: 0.9617
55000/55000 [==============================] - 1s 13us/step - loss: 0.1335 - acc: 0.9615
Out[]: <tensorflow.python.keras.callbacks.History at 0x7f5768a40da0>
要配置均方误差损失的回归模型,我们将使用模型编译,如下所示:
model.compile(optimizer=tf.train.AdamOptimizer(0.01), loss='mse', metrics=['mae'])
- 接下来,我们将看到如何实现具有两个卷积层的 CNN 模型,其具有最大池,全部后面是完全连接的层。首先,我们必须将平面图像重塑为 2D 图像,并将 y 目标转换为 numpy 数组,如下所示:00
x_train = x_tra0in.reshape(x_train.shape[0], 28, 28, 1)
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)
input_shape = (28, 28, 1)
num_classes = 10
# Categorize y targets
y_test = to_categorical(mnist.test.labels)
y_train = to_categorical(mnist.train.labels)
- 我们将像以前一样以类似的顺序层方法创建 CNN。这次我们将使用
Conv2D()
,MaxPooling2D()
和Dense()
Keras 函数创建我们的 CNN 模型,如下所示:
cnn_model = keras.Sequential()
# First convolution layer
cnn_model.add(keras.layers.Conv2D(25,
kernel_size=(4, 4),
strides=(1, 1),
activation='relu',
input_shape=input_shape))
# Max pooling
cnn_model.add(keras.layers.MaxPooling2D(pool_size=(2, 2),
strides=(2, 2)))
# Second convolution layer
cnn_model.add(keras.layers.Conv2D(50,
kernel_size=(5, 5),
strides=(1, 1),
activation='relu'))
# Max pooling
cnn_model.add(keras.layers.MaxPooling2D(pool_size=(2, 2),
strides=(2, 2)))
# Flatten for dense (fully connected) layer
cnn_model.add(keras.layers.Flatten())
# Add dense (fully connected) layer
cnn_model.add(keras.layers.Dense(num_classes, activation='softmax'))
- 接下来,我们将通过选择优化和损失函数来编译我们的模型。
cnn_model.compile(optimizer=tf.train.AdamOptimizer(0.001),
loss='categorical_crossentropy',
metrics=['accuracy'])
- Keras 还允许我们将函数插入到名为 Callbacks 的训练代码中。回调是在代码中的某些时间执行的函数,可用于执行各种函数。有许多预制回调,可以保存模型,在特定标准下停止训练,记录值等等。有关各种选项的更多信息,请参阅 https://keras.io/callbacks/ 。为了说明如何制作我们自己的自定义回调并显示它们如何工作,我们将创建一个名为
RecordAccuracy()
的回调,它是一个 Keras Callback 类,并将在每个周期的末尾存储精度,如下所示:
class RecordAccuracy(keras.callbacks.Callback):
def on_train_begin(self, logs={}):
self.acc = []
def on_epoch_end(self, batch, logs={}):
self.acc.append(logs.get('acc'))
accuracy = RecordAccuracy()
- 接下来,我们将使用
fit()
方法训练我们的 CNN 模型。这里我们将提供validation_data
和callbacks
如下:
cnn_model.fit(x_train,
y_train,
batch_size=64,
epochs=3,
validation_data=(x_test, y_test),
callbacks=[accuracy])
print(accuracy.acc)
- 此训练将产生类似的输出,如下所示:
Train on 55000 samples, validate on 64 samples
Epoch 1/3
64/55000 [..............................] - ETA: 2:59 - loss: 2.2805 - acc: 0.0625
192/55000 [>.............................] - ETA: 1:14 - loss: 2.2729 - acc: 0.1302\
...
54848/55000 [============================>.] - ETA: 0s - loss: 0.0603 - acc: 0.9816
54976/55000 [============================>.] - ETA: 0s - loss: 0.0603 - acc: 0.9816
55000/55000 [==============================] - 26s 469us/step - loss: 0.0604 - acc: 0.9816 - val_loss: 0.0139 - val_acc: 1.0000
Out[]: <tensorflow.python.keras.callbacks.History at 0x7f69494c7780>
[0.9414363636450334, 0.9815818181731484, 0.9998980778226293]
工作原理
在这个秘籍中,我们展示了 Keras 的简洁创建和训练模型。您可以自动处理变量类型,维度和数据摄取的许多复杂细节。虽然这可以让人放心,但我们应该意识到,如果我们掩盖太多模型细节,我们可能无意中实现了错误的模型。
另见
有关 Keras 的更多信息,建议读者查看以下资源:
- 官方 Keras 文件: https://keras.io/
- TensorFlow Keras 教程: https://www.tensorflow.org/guide/keras
- “Keras 简介”,Francois Chollet 在斯坦福大学的客座讲座(幻灯片中的 PDF 格式): https://web.stanford.edu/class/cs20si/lectures/march9guestlecture.pdf