标签:iter view var sch 手动 因此 功能 sha 获取
Sequential Model:(the simplest type of model)
Getting started with the Keras Sequential model
之前在研读MobileNet V3的源码时,其代码在基于TensorFlow框架中使用了tf.keras。在基于tf.keras下,模型的构建更加容易,也略显高级。再次附上MobileNet V3代码:https://github.com/Bisonai/mobilenetv3-tensorflow。
官方教程:https://tensorflow.google.cn/guide/keras/overview
tf.keras是TensorFlow实现的keras API规范。这是一个用于构建和训练模型的高级API,包含对tensorflow特定功能的支持。
1 import tf.keras 2 # form tensorflow import keras
Keras 2.2.5是最后一个支持TensorFlow1.的版本,也是2.2.*最后一个用Keras实现的版本。最新的版本是Keras2.3.0,其对API进行了重大的改进,并添加对TensorFlow 2.0的支持。
**************************************Keras使用基础*****************************************
Sequential 模型就是多个网络层的线性堆叠。 model.add()
1 from keras.models import Sequential 2 from keras.layers import Dense 3 model = Sequential() 4 model.add(Dense(units=64, activation="relu", input_dim=100)) 5 model.add(Dense(units=10, activation="softmax"))
一旦模型搭建完成,可以通过.compile()配置它的学习过程。
1 model.compile(loss=‘categorical_crossentropy‘, 2 optimizer=‘sgd‘, 3 metrics=[‘accuracy‘]
如果需要,也可以优化配置,如下所述。此时,损失、优化器的设置将会显式的调用方法,而不是通过某字段:
1 model.compile(loss=keras.losses.categorical_crossentropy, 2 optimizer=keras.optimizers.SGD(lr=0.01, momentum=0.9, nesterov=True))
训练阶段:
然后,可以将数据输入模型,并进行训练。自动将输入数据划分为batch进行训练:
model.fit(x_train, y_train, epoch=5, batch_size=32)
当然,也可以手动将batch数据集输入到模型中(这种情况通常是在需要手动建立样本对时,如siamese network):
model.train_on_batch(x_batch, y_batch)
训练时,验证模型:
loss_and_metrics = model.evaluate(x_test, y_test, batch_size=128)
测试阶段:
classes = model.predict(x_test, batch_size=128)
以上是最简明的Keras教程。
Sequential model 就是一些层的线性堆叠。
堆叠的方式包含两种:
1 from keras.models import Sequential 2 from keras.layers import Dense, Activation 3 4 model = Sequential([ 5 Dense(32, input_shape=(784,)), 6 Activation(‘relu‘), 7 Dense(10), 8 Activation(‘softmax‘), 9 ])
将由层构成的列表添加到Sequential中。
1 model = Sequential() 2 model.add(Dense(32, input_dim=784)) 3 model.add(Activation(‘relu‘))
一般会直接把激活函数添加到层中:
model.add(Dense(units=10, activation="softmax"))
模型需要明确输入形状(就像TensorFlow中占位符tf.placeholder()的声明)。
因此,序列模型中的第一层(只有第一层,因为后续层可以进行自动形状推断)需要接收关于其输入形状的信息。Keras有几种可能的方法来做到这一点:
1 model = Sequential() 2 model.add(Dense(32, input_shape=(784,)))
如上所示,将input_shape传递给第一层中。
1 model = Sequential() 2 model.add(Dense(32, input_dim=784))
如上所示,Dense中既包含input_dim参数的传递,也包含input_shape参数的传递。
在训练模型之前,需要配置训练过程的一些参数,通过compile函数完成。必需传递的三个参数:
optimizer:
可以使用现存优化器的字符串或者是一个优化器类的实例来识别。
1 from keras import optimizers 2 3 model = Sequential() 4 model.add(Dense(64, kernel_initializer=‘uniform‘, input_shape=(10,))) 5 model.add(Activation(‘softmax‘)) 6 # 情形1: 类的实例 7 sgd = optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True) 8 model.compile(loss=‘mean_squared_error‘, optimizer=sgd) 9 # 情形2:字符串 10 model.compile(loss=‘mean_squared_error‘, optimizer=‘sgd‘)
优化器中可以添加clipnorm和clipvalue参数对梯度进行截断。
1 from keras import optimizers 2 3 # All parameter gradients will be clipped to 4 # a maximum norm of 1. 5 sgd = optimizers.SGD(lr=0.01, clipnorm=1.)
1 from keras import optimizers 2 3 # All parameter gradients will be clipped to 4 # a maximum value of 0.5 and 5 # a minimum value of -0.5. 6 sgd = optimizers.SGD(lr=0.01, clipvalue=0.5)
常用的优化方式包括SGD、RMSprop、Adagrad、Adadelta、Adam、Adamax、Nadam。具体使用详见:https://keras.io/optimizers/
loss funtion:
同样可以通过字符串或类实例来识别。
1 from keras import losses 2 # 情形1 字符串 3 model.compile(loss=‘mean_squared_error‘, optimizer=‘sgd‘) 4 # 情形2 类实例 5 model.compile(loss=losses.mean_squared_error, optimizer=‘sgd‘)
可以获取到的损失函数详见:https://keras.io/losses/
metrics:
对于任何分类问题,需要设置一些metrics=[‘accuracy‘],也是通过字符串和类实例识别。
1 from keras import metrics 2 # 情形1 字符串 3 model.compile(loss=‘mean_squared_error‘, 4 optimizer=‘sgd‘, 5 metrics=[‘mae‘, ‘acc‘]) 6 # 情形2 类实例 7 model.compile(loss=‘mean_squared_error‘, 8 optimizer=‘sgd‘, 9 metrics=[metrics.mae, metrics.categorical_accuracy])
可以获得的metrics详见:https://keras.io/metrics/
Keras训练通过Numpy数组作为输入数据。
1 # For a single-input model with 2 classes (binary classification): 2 3 model = Sequential() 4 model.add(Dense(32, activation=‘relu‘, input_dim=100)) 5 model.add(Dense(1, activation=‘sigmoid‘)) 6 model.compile(optimizer=‘rmsprop‘, 7 loss=‘binary_crossentropy‘, 8 metrics=[‘accuracy‘]) 9 10 # Generate dummy data 11 import numpy as np 12 data = np.random.random((1000, 100)) 13 labels = np.random.randint(2, size=(1000, 1)) 14 15 # Train the model, iterating on the data in batches of 32 samples 16 model.fit(data, labels, epochs=10, batch_size=32)
one-hot操作:
1 # Convert labels to categorical one-hot encoding 2 one_hot_labels = keras.utils.to_categorical(labels, num_classes=10)
更多Keras中函数参数使用详见:https://keras.io/models/sequential/
后端使用详见:https://keras.io/backend/
************************************************************************************************************
上面介绍了一些关于Keras的使用,这是使用tf.keras的基础。
言归正传,回到tf.keras的道路上...
tf.keras是TensorFlow实现的keras API规范。这是一个用于构建和训练模型的高级API,包括对tensorflow特定功能(如eager execution、tf.data和Estimators) tf.keras使TensorFlow更易于使用,同时又不牺牲灵活性和性能。
eager execution、tf.data和Estimators会在TensorFlow的介绍中详细解读,tf.keras中暂不作详述。
首先,导入需要的一些设置:
1 from __future__ import absolute_import, division, print_function, unicode_literals 2 import tensorflow as tf 3 from tensorflow import keras
tf.keras中可以运行与Keras兼容的任意代码,但需要注意的是:
仿照Keras中的Sequential()方法,此时,在TensorFlow中也可以使用这种线性堆叠的方法:tf.keras.Sequentials()
1 import tensorflow as tf 2 from tensorflow.keras import layers 3 4 model = tf.keras.Sequential() 5 # Adds a densely-connected layer with 64 units to the model: 6 model.add(layers.Dense(64, activation=‘relu‘)) 7 # Add another: 8 model.add(layers.Dense(64, activation=‘relu‘)) 9 # Add an output layer with 10 output units: 10 model.add(layers.Dense(10))
tf.keras.layers中提供了一些可用的层,详见:https://tensorflow.google.cn/api_docs/python/tf/keras/layers
这些层会包含一些共同的参数:
1 # 创建一个激活函数是relu的全连接层: 2 layers.Dense(64, activation=‘relu‘) 3 # 也可以通过 类实例 设置激活函数: 4 layers.Dense(64, activation=tf.nn.relu) 5 6 # 创建一个对权重使用L1正则化,并且参数为0.01的全连接层: 7 layers.Dense(64, kernel_regularizer=tf.keras.regularizers.l1(0.01)) 8 9 # 创建一个对偏执使用L2正则化,并且参数为0.01的全连接层: 10 layers.Dense(64, bias_regularizer=tf.keras.regularizers.l2(0.01)) 11 12 # 对权重选择orthogonal的初始化方式 13 layers.Dense(64, kernel_initializer=‘orthogonal‘) 14 15 # 将偏执初始化为2.0 16 layers.Dense(64, bias_initializer=tf.keras.initializers.Constant(2.0))
在模型搭建完成后,便可以配置训练过程的参数,这些过程与Keras一致,只不过是通过tf.keras来调用。
1 model.compile(optimizer=tf.keras.optimizers.Adam(0.01), 2 loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True), 3 metrics=[‘accuracy‘])
在compile可以设置run_eager=True ,to make sure the model trains and evaluates eagerly。
不需要将数据喂到张量中,可以直接将数据输入到.fit()函数中。
1 import numpy as np 2 3 data = np.random.random((1000, 32)) 4 labels = np.random.random((1000, 10)) 5 6 model.fit(data, labels, epochs=10, batch_size=32
tf.keras.Model.fit()函数中包含3个重要参数:
1 import numpy as np 2 3 data = np.random.random((1000, 32)) 4 labels = np.random.random((1000, 10)) 5 6 val_data = np.random.random((100, 32)) 7 val_labels = np.random.random((100, 10)) 8 9 model.fit(data, labels, epochs=10, batch_size=32, 10 validation_data=(val_data, val_labels))
此处只是简单的介绍,tf.data是读取数据的API,可以实现数据在多设备上的训练。可以通过tf.data.Dataset实例获取数据,并将数据传入到 .fit 方法中。
详见:https://tensorflow.google.cn/guide/data
1 dataset = tf.data.Dataset.from_tensor_slices((data, labels)) 2 dataset = dataset.batch(32) 3 4 model.fit(dataset, epochs=10)
由于Dataset生成(yeild)批量数据,因此model.fit()中不再需要batch_size参数的设置。同时,Dataset也可以用于验证数据的生成:
1 dataset = tf.data.Dataset.from_tensor_slices((data, labels)) 2 dataset = dataset.batch(32) 3 4 val_dataset = tf.data.Dataset.from_tensor_slices((val_data, val_labels)) 5 val_dataset = val_dataset.batch(32) 6 7 model.fit(dataset, epochs=10, 8 validation_data=val_dataset)
tf.keras.Model.evaluate和tf.keras.Model.predict方法可以使用Numpy数据和tf.data.Dataset数据进行验证和预测。
.evaluate
1 # With Numpy arrays 2 data = np.random.random((1000, 32)) 3 labels = np.random.random((1000, 10)) 4 5 model.evaluate(data, labels, batch_size=32) 6 7 # With a Dataset 8 dataset = tf.data.Dataset.from_tensor_slices((data, labels)) 9 dataset = dataset.batch(32) # 此处按照batch划分 10 11 model.evaluate(dataset) # 此处不再需要batch参数
.predict
1 result = model.predict(data, batch_size=32) 2 print(result.shape)
详见:https://tensorflow.google.cn/guide/keras/train_and_evaluate
也许在上面的介绍中,你可能会觉得这只是在tensorflow中调用keras,搞出来了一个tf.keras这么个东东,还不如直接用Keras来的实惠。这只是创建简单的模型,在本节中,将会见到tf.keras的奇妙之处,也是在MobileNet V3源码中广泛使用的模型子类化(Model subclassing)和自定义层(Custom layers) ,一起揭开其神秘的面纱。
使用tf.keras.Sequential构建模型是一种层与层之间简单堆叠式的方式,其不能表征任意的模型。使用Keras functional API可以创建复杂的模型,例如:
创建一个由functional API 构建的模型需要如下几步:
下面的全连接网络实例便是使用的the functional API,在其中,可以隐约的看到keras版的YOLO v3的影子:
1 inputs = tf.keras.Input(shape=(32,)) # Returns an input placeholder 2 3 # 1. 层实例可以回调一个张量,也可以返回一个张量 --- 完成模型的构建 4 x = layers.Dense(64, activation=‘relu‘)(inputs) 5 x = layers.Dense(64, activation=‘relu‘)(x) 6 predictions = layers.Dense(10)(x) 7 # 2. 通过给定输出 输出 实例化一个模型 8 model = tf.keras.Model(inputs=inputs, outputs=predictions) 9 10 # 3. 通过与sequential模型相同的训练方式训练模型 11 model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001), 12 loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True), 13 metrics=[‘accuracy‘]) 14 15 # Trains for 5 epochs 16 model.fit(data, labels, batch_size=32, epochs=5)
通过tf.keras.Model子类化和定义前向过程的方式完全自主的创建model。在_init__方法中创建层,并将它们设置为类实例的属性。在call方法中定义前向过程。
当启用了立即执行时,模型子类化特别有用,因为它允许强制地编写正向传递。
下面的实例中展示了一个使用子类化tf.keras.Model,并且自定义前向过程的模型:
1 class MyModel(tf.keras.Model): 2 3 def __init__(self, num_classes=10): 4 super(MyModel, self).__init__(name=‘my_model‘) 5 self.num_classes = num_classes 6 # Define your layers here. 7 self.dense_1 = layers.Dense(32, activation=‘relu‘) # __init__中定义层 8 self.dense_2 = layers.Dense(num_classes) 9 10 def call(self, inputs): # call 函数中定义前向过程 11 # Define your forward pass here, 12 # using layers you previously defined (in `__init__`). 13 x = self.dense_1(inputs) 14 return self.dense_2(x)
实例化建立的MyModel类,那并进行编译训练:
1 model = MyModel(num_classes=10) 2 3 # The compile step specifies the training configuration. 4 model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001), 5 loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True), 6 metrics=[‘accuracy‘]) 7 8 # Trains for 5 epochs. 9 model.fit(data, labels, batch_size=32, epochs=5)
上面的使用过程可以描述为以下几个步骤:
通过子类化tf.keras.layers来创建一个自定义层。使用以下方法实现:
下面是一个自定义层的例子,它实现了一个带有核矩阵的输入矩阵:
1 class MyLayer(layers.Layer): 2 3 def __init__(self, output_dim, **kwargs): 4 self.output_dim = output_dim # 输出个数的定义 5 super(MyLayer, self).__init__(**kwargs) # 初始化layers.Layer变量。 6 7 def build(self, input_shape): # 添加权重矩阵 8 # Create a trainable weight variable for this layer. 9 self.kernel = self.add_weight(name=‘kernel‘, 10 shape=(input_shape[1], self.output_dim), 11 initializer=‘uniform‘, 12 trainable=True) 13 14 def call(self, inputs): # 定义前向过程 15 return tf.matmul(inputs, self.kernel) 16 17 def get_config(self): 18 base_config = super(MyLayer, self).get_config() 19 base_config[‘output_dim‘] = self.output_dim 20 return base_config 21 22 @classmethod 23 def from_config(cls, config): 24 return cls(**config)
使用自定义的层,创建一个模型:
1 model = tf.keras.Sequential([ 2 MyLayer(10)]) 3 4 # The compile step specifies the training configuration 5 model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001), 6 loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True), 7 metrics=[‘accuracy‘]) 8 9 # Trains for 5 epochs. 10 model.fit(data, labels, batch_size=32, epochs=5)
更加细致的内容详见: https://tensorflow.google.cn/guide/keras/custom_layers_and_models
回调是传递给模型的对象,用于在训练期间自定义和扩展其行为。编写自己的自定义回调,或者使用内置的tf.keras.callbacks,包括: ---- callbacks 参数是在.fit()中应用。
1 callbacks = [ 2 # Interrupt training if `val_loss` stops improving for over 2 epochs 3 tf.keras.callbacks.EarlyStopping(patience=2, monitor=‘val_loss‘), 4 # Write TensorBoard logs to `./logs` directory 5 tf.keras.callbacks.TensorBoard(log_dir=‘./logs‘) 6 ] 7 model.fit(data, labels, batch_size=32, epochs=5, callbacks=callbacks, 8 validation_data=(val_data, val_labels))
1 # Save weights to a TensorFlow Checkpoint file 2 model.save_weights(‘./weights/my_model‘) 3 4 # Restore the model‘s state, 5 # this requires a model with the same architecture. 6 model.load_weights(‘./weights/my_model‘)
上述函数默认保存的模型权重是TensorFlow的checkpoint(.ckpt)格式。也可以保存为Keras版的HDF5格式,只需要修改保存格式参数即可:
1 # Save weights to a HDF5 file 2 model.save_weights(‘my_model.h5‘, save_format=‘h5‘) 3 4 # Restore the model‘s state 5 model.load_weights(‘my_model.h5‘)
非训练过程调整的参数保存,如yolo中的cfg文件。可以保存为JSON和YAML两种格式:
1 # Serialize a model to JSON format 2 json_string = model.to_json() # 保存 为json 3 yaml_string = model.to_yaml() # 保存 为yaml
导入
1 import json 2 import pprint 3 pprint.pprint(json.loads(json_string))
复现模型:
1 fresh_model = tf.keras.models.model_from_json(json_string) # 由json复现 2 fresh_model = tf.keras.models.model_from_yaml(yaml_string) # 由yaml复现
1 # Save entire model to a HDF5 file 2 model.save(‘my_model‘) 3 4 # Recreate the exact same model, including weights and optimizer. 5 model = tf.keras.models.load_model(‘my_model‘)
更多关于保存模型内容详见:https://tensorflow.google.cn/guide/keras/save_and_serialize
下一篇链接:https://www.cnblogs.com/monologuesmw/p/13534871.html
https://tensorflow.google.cn/guide/keras
【tf.keras】官方教程一 Keras overview
标签:iter view var sch 手动 因此 功能 sha 获取
原文地址:https://www.cnblogs.com/monologuesmw/p/13534857.html