Introduction to Keras for Engineers--官网学习

学习Keras,我从一个官方样例Mnist手写数字识别入手,现在着重学习一下为工程师准备的keras介绍。

1. keras训练基本步骤

  • 1)准备数据
    格式诸如Numpy Arrays 或者 Tensorflow的Dataset样式。
    进一步,数据预处理,数据正则归一或者词向量。
  • 2)构建模型
  • 3)训练模型
  • 4)评估模型
  • 5)定制训练方式,构建GAN(生成对抗网络) --可选
  • 6)GPU加速 --可选
  • 7)超参数调试,重定义模型 --可选

2. keras训练步骤 --准备数据

神经网络不直接处理原生数据,比如文本文件、jpg图像文件或者表格csv文件;需要将原生文件处理成矢量化与标准化的格式。例如:

  • 文本文件需要以string tensor的方式读取,然后分解成单词,最后索引并转换成整型tensor张量。比如:RNN预测上下文。训练数据需要这样去处理。
  • 图像文件需要解码成整型tensor张量去读取,然后转换成浮点型并标准归一化为[0,1]。比如:CNN图像分类。
  • CSV文件。需要将数值特征转换为浮点张量,并将分类特征建立索引并转换为整型张量。然后每个特征通常需要概率论均值标准差进行归一标准化。

2.1 数据加载

2.1.1 格式要求等说明

keras模型的输入类型,可以是如下三种:

  • Numpy Arrays
  • Tensorflow Dataset Objects
  • Python生成器generator(keras.utils.Sequence)

训练模型前,请确保训练数据符合如上格式的要求。如果是大型数据集,且使用GPU训练,建议考虑使用第二种Tensorflow Dataset objects格式。因为关键性能细节被监控,比如:

  • GPU忙的时候,可以在cpu上异步处理训练数据;同时缓存到一个队列中。
  • GPU充分利用。在GPU已经完成前批次batch预处理,GPU内存预取数据是即时生效的。

【备注】:不明白此处关键性能监控的直观作用。后面慢慢体会吧。

Keras有一些工具,供开发者将原生数据转化为可以使用的数据集:

  • tf.keras.preprocessing.image_dataset_from_directory
  • tf.keras.preprocessing.text_dataset_from_directory
  • tf.data.experimental.make_csv_dataset(这个是tensorflow本身拥有的接口)
    以上前两个接口是tensorflow 2.x中keras集成的高级接口,1.x中没有此接口。

2.1.2 举例

分别就图片文件和文本文件的处理,做了简单的代码举例。

  • 1)图片文件处理
    Supposed you have image files sorted by class in different folders, like this:
    如果图片文件存放的方式,类似如下:
main_directory/
...class_a/
......a_image_1.jpg
......a_image_2.jpg
...class_b/
......b_image_1.jpg
......b_image_2.jpg

则,可以使用image_dataset_from_directory接口,作如下数据处理:
(这里直接拿MNIST png数据做的实际示例)

from tensorflow import keras

# Create a dataset.
labels_class = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] #如下train目录下的各分类文件夹
dataset = keras.preprocessing.image_dataset_from_directory(
  'I:/work/datasets/MNIST_PNG_Data/train', batch_size=64, class_names=labels_class, image_size=(28, 28))

# For demonstration, iterate over the batches yielded by the dataset.
i = 0
for data, labels in dataset:
    print("============== ", i)    
    print(data.shape)  # (64, 200, 200, 3)
    print(data.dtype)  # float32
    print(labels.shape)  # (64,)
    print(labels)  # int32
    i += 1

此接口中,如果不主动设置class_names参数,则keras按照目录下的文件夹名字字母的排序,作为分类的标识。比如:class_a为0,class_b为1,…
//后面计划用这个接口,使用keras模拟从原始数据-模型训练-测试应用的全过程。前面的一片文章是用keras给的mnist示例下载npz输入数据集。
在这里插入图片描述

  • 2) 文本文件处理
dataset = keras.preprocessing.text_dataset_from_directory(
  'path/to/main_directory', batch_size=64)

# For demonstration, iterate over the batches yielded by the dataset.
for data, labels in dataset:
   print(data.shape)  # (64,)
   print(data.dtype)  # string
   print(labels.shape)  # (64,)
   print(labels.dtype)  # int32

2.2 Data preprocessing with Keras

在2.1节中将数据处理成string/int/float Numpy arrays或者a Dataset object (or Python generator) ;接下来该是将数据作进一步的预处理了。

  • 字符串数据的标记,并且建立单词索引
  • 特征值的标准归一化
  • 缩放数据到很小的值(通常情况下,一个神经网络的输入值应该非常接近0,特别的我们期望这些数据的均值为0,单位方差;或者数据处于[0,1]区间内)

2.2.1 Using Keras preprocessing layers

在keras中,可以使用proprocessing layers模块进行数据预处理。包括如下:

  • TextVectorization layer --向量化文本原生strings
  • Normalization layer --特征标准归一
  • Rescaling,CenterCrop --图像缩放、裁剪或者图像数据的扩充

Keras preprocessing layers 优势的关键:它们能直接包含在模型中;使得模型可移植性强,无论在训练中还是训练后。
preprocessing layer状态是通过调用layer.adapt(data)接口获得。

2.2.2 preprocessing layers examples

1). turning strings into sequences of integer word indices

import numpy as np
from tensorflow.keras.layers.experimental.preprocessing import TextVectorization

# Example training data, of dtype `string`.
training_data = np.array([["This is the 1st sample."], ["And here's the 2nd sample."]])

# Create a TextVectorization layer instance. It can be configured to either
# return integer token indices, or a dense token representation (e.g. multi-hot
# or TF-IDF). The text standardization and text splitting algorithms are fully
# configurable.
vectorizer = TextVectorization(output_mode="int")

# Calling `adapt` on an array or dataset makes the layer generate a vocabulary
# index for the data, which can then be reused when seeing new data.
vectorizer.adapt(training_data)

# After calling adapt, the layer is able to encode any n-gram it has seen before
# in the `adapt()` data. Unknown n-grams are encoded via an "out-of-vocabulary"
# token.
integer_data = vectorizer(training_data)
print(integer_data)
tf.Tensor(
[[4 5 2 9 3]
 [7 6 2 8 3]], shape=(2, 5), dtype=int64)

2). turning strings into sequences of one-hot encoded bigrams

这块儿需要看一下

from tensorflow.keras.layers.experimental.preprocessing import TextVectorization

# Example training data, of dtype `string`.
training_data = np.array([["This is the 1st sample."], ["And here's the 2nd sample."]])

# Create a TextVectorization layer instance. It can be configured to either
# return integer token indices, or a dense token representation (e.g. multi-hot
# or TF-IDF). The text standardization and text splitting algorithms are fully
# configurable.
vectorizer = TextVectorization(output_mode="binary", ngrams=2)

# Calling `adapt` on an array or dataset makes the layer generate a vocabulary
# index for the data, which can then be reused when seeing new data.
vectorizer.adapt(training_data)

# After calling adapt, the layer is able to encode any n-gram it has seen before
# in the `adapt()` data. Unknown n-grams are encoded via an "out-of-vocabulary"
# token.
integer_data = vectorizer(training_data)
print(integer_data)
tf.Tensor(
[[0. 1. 1. 1. 1. 0. 1. 1. 1. 0. 0. 0. 0. 0. 0. 1. 1.]
 [0. 1. 1. 0. 0. 1. 0. 0. 0. 1. 1. 1. 1. 1. 1. 0. 0.]], shape=(2, 17), dtype=float32)

3). normalizing features

from tensorflow.keras.layers.experimental.preprocessing import Normalization

# Example image data, with values in the [0, 255] range
training_data = np.random.randint(0, 256, size=(64, 200, 200, 3)).astype("float32")

normalizer = Normalization(axis=-1)
normalizer.adapt(training_data)

normalized_data = normalizer(training_data)
print("var: %.4f" % np.var(normalized_data))
print("mean: %.4f" % np.mean(normalized_data))
#var: 1.0000
#mean: -0.0000

4). rescaling & center-cropping images

from tensorflow.keras.layers.experimental.preprocessing import CenterCrop
from tensorflow.keras.layers.experimental.preprocessing import Rescaling

# Example image data, with values in the [0, 255] range
training_data = np.random.randint(0, 256, size=(64, 200, 200, 3)).astype("float32")

cropper = CenterCrop(height=150, width=150)
scaler = Rescaling(scale=1.0 / 255)

output_data = scaler(cropper(training_data))
print("shape:", output_data.shape)
print("min:", np.min(output_data))
print("max:", np.max(output_data))
#shape: (64, 150, 150, 3)
#min: 0.0
#max: 1.0

2. keras训练步骤 --Building models

在keras中,一个layer层是一个简单的输入和输出转换。比如下面的一个线性投影,将输入映射到一个16维的特征空间中。

dense = keras.layers.Dense(units=16)

模型是layers的有向无环图。可以将模型作为一个bigger layer,包含多个sublayers,且可通过暴露数据进行训练。
构建keras模型,简单粗暴的方式,就是使用keras高级API。以特定的input shape开始,当然开发者可以将shape设为None。比如,200x200 RGB图像数据,其shape维(200,200,3),但是任意size的RGB 输入图像,其shape也可以为(None,None,3)

# Let's say we expect our inputs to be RGB images of arbitrary size
inputs = keras.Input(shape=(None, None, 3))

定义完毕input后,就可以在input上,进行各种layer层的各种所需转换,直到最后的输出,请看如下示例代码:

  • input keras.Input:对输入先裁剪缩放
  • transformations keras.layers.Conv2D等:经过二维卷积、最大池化、二维卷积、最大池化、二维卷积、均值池化。
  • dense keras.layers.Dense:经过各种layers的转换,通过softmax映射到10维特征空间中。
from tensorflow.keras import layers

# Center-crop images to 150x150
x = CenterCrop(height=150, width=150)(inputs)
# Rescale images to [0, 1]
x = Rescaling(scale=1.0 / 255)(x)

# Apply some convolution and pooling layers
x = layers.Conv2D(filters=32, kernel_size=(3, 3), activation="relu")(x)
x = layers.MaxPooling2D(pool_size=(3, 3))(x)
x = layers.Conv2D(filters=32, kernel_size=(3, 3), activation="relu")(x)
x = layers.MaxPooling2D(pool_size=(3, 3))(x)
x = layers.Conv2D(filters=32, kernel_size=(3, 3), activation="relu")(x)

# Apply global average pooling to get flat feature vectors
x = layers.GlobalAveragePooling2D()(x)

# Add a dense classifier on top
num_classes = 10
outputs = layers.Dense(num_classes, activation="softmax")(x)
  • 实例一个模型对象keras.Mode:定义完layers有向无环图后,就可以实例一个模型类对象了;
model = keras.Model(inputs=inputs, outputs=outputs)
data = np.random.randint(0, 256, size=(64, 200, 200, 3)).astype("float32")
processed_data = model(data)
print(processed_data.shape)
#(64, 10)

开发者可以通过 model.summary() 方法打印模型每一步的数据转换细节,对于调试非常有用。
注意:每个layer层的输出shape都包含batch size。

Model: "model"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, None, None, 3)]   0         
_________________________________________________________________
center_crop_1 (CenterCrop)   (None, 150, 150, 3)       0         
_________________________________________________________________
rescaling_1 (Rescaling)      (None, 150, 150, 3)       0         
_________________________________________________________________
conv2d (Conv2D)              (None, 148, 148, 32)      896       
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 49, 49, 32)        0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 47, 47, 32)        9248      
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 15, 15, 32)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 13, 13, 32)        9248      
_________________________________________________________________
global_average_pooling2d (Gl (None, 32)                0         
_________________________________________________________________
dense (Dense)                (None, 10)                330       
=================================================================
Total params: 19,722
Trainable params: 19,722
Non-trainable params: 0
_________________________________________________________________

3. keras训练步骤 – Training models with fit()

数据准备、构建模型后,接下来就可以训练模型了。Model类提供了一个内置的循环训练 方法接口fit()。当然在调用fit()前,开发者需要指定一个优化器和损失函数。这部分的工作由keras提供的compile()接口执行。

model.compile(optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
              loss=keras.losses.CategoricalCrossentropy())
// or use as follows:
model.compile(optimizer='rmsprop', loss='categorical_crossentropy')

compile()后,我们就可以开始fit()。fit()用法例子:

model.fit(numpy_array_of_samples, numpy_array_of_labels,
          batch_size=32, epochs=10)

关于fit()的形参几点说明:除了所需的训练数据外,批处理batch_size和迭代次数epochs也需要特别指定。当然如果输入的数据集已经集成batch处理,可以不再指定batch_size。
至此,Training结束。有关训练的进阶,开发者可以研究源码。比如:

  • Keeping track of performance metrics
  • Using callbacks for checkpointing
  • Monitoring training progress with TensorBoard

4. keras训练步骤 – Evaluating models with evaluate()

通过compile、fit训练完模型后,我们就可以通过测试数据评估模型的loss和其他metrics指标了。
在keras中,提供 evaluate() 接口实现上述的功能。

loss, acc = model.evaluate(val_dataset)  # returns loss and metrics
print("loss: %.2f" % loss)
print("acc: %.2f" % acc)
# 157/157 [==============================] - 0s 688us/step - loss: 0.1041 - acc: 0.9692
# loss: 0.10
# acc: 0.97

如果开发者想得到预测结果怎么办。别急,Keras也提供了相应的接口predict()

predictions = model.predict(val_dataset)
print(predictions.shape)
# (10000, 10)

备注:后面的定制化训练、GPU加速和超参数调试。这里就不翻译了。有需要了解的,去官网即可。
后续我用到了,再学习更新。

提示:以上的代码示例,都是基于tensorflow 2.x的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值