函数式 API
tf.keras.Sequential
模型是层的简单堆叠,无法表示任意模型。使用 Keras 函数式 API 可以构建复杂的模型拓扑,例如:
- 多输入模型,
- 多输出模型,
- 具有共享层的模型(同一层被调用多次),
- 具有非序列数据流的模型(例如,剩余连接)。
使用函数式 API 构建的模型具有以下特征:
- 层实例可调用并返回张量。
- 输入张量和输出张量用于定义
tf.keras.Model
实例。 - 此模型的训练方式和
Sequential
模型一样。
以下示例使用函数式 API 构建一个简单的全连接网络:
inputs = tf.keras.Input(shape=(32,)) # Returns a placeholder tensor
# A layer instance is callable on a tensor, and returns a tensor.
x = layers.Dense(64, activation='relu')(inputs)
x = layers.Dense(64, activation='relu')(x)
predictions = layers.Dense(10, activation='softmax')(x)
在给定输入和输出的情况下实例化模型。
model = tf.keras.Model(inputs=inputs, outputs=predictions)
# The compile step specifies the training configuration.
model.compile(optimizer=tf.train.RMSPropOptimizer(0.001),
loss='categorical_crossentropy',
metrics=['accuracy'])
# Trains for 5 epochs
model.fit(data, labels, batch_size=32, epochs=5)
Epoch 1/5
1000/1000 [==============================] - 0s 260us/step - loss: 11.7190 - acc: 0.1080
Epoch 2/5
1000/1000 [==============================] - 0s 75us/step - loss: 11.5347 - acc: 0.1010
Epoch 3/5
1000/1000 [==============================] - 0s 74us/step - loss: 11.5020 - acc: 0.1100
Epoch 4/5
1000/1000 [==============================] - 0s 75us/step - loss: 11.4908 - acc: 0.1090
Epoch 5/5
1000/1000 [==============================] - 0s 74us/step - loss: 11.4809 - acc: 0.1330
模型子类化
通过对 tf.keras.Model
进行子类化并定义您自己的前向传播来构建完全可自定义的模型。在 __init__
方法中创建层并将它们设置为类实例的属性。在 call
方法中定义前向传播。
在启用 Eager Execution 时,模型子类化特别有用,因为可以命令式地编写前向传播。
要点:针对作业使用正确的 API。虽然模型子类化较为灵活,但代价是复杂性更高且用户出错率更高。如果可能,请首选函数式 API。
以下示例展示了使用自定义前向传播进行子类化的 tf.keras.Model
:
class MyModel(tf.keras.Model):
def __init__(self, num_classes=10):
super(MyModel, self).__init__(name='my_model')
self.num_classes = num_classes
# Define your layers here.
self.dense_1 = layers.Dense(32, activation='relu')
self.dense_2 = layers.Dense(num_classes, activation='sigmoid')
def call(self, inputs):
# Define your forward pass here,
# using layers you previously defined (in `__init__`).
x = self.dense_1(inputs)
return self.dense_2(x)
def compute_output_shape(self, input_shape):
# You need to override this function if you want to use the subclassed model
# as part of a functional-style model.
# Otherwise, this method is optional.
shape = tf.TensorShape(input_shape).as_list()
shape[-1] = self.num_classes
return tf.TensorShape(shape)
实例化新模型类:
model = MyModel(num_classes=10)
# The compile step specifies the training configuration.
model.compile(optimizer=tf.train.RMSPropOptimizer(0.001),
loss='categorical_crossentropy',
metrics=['accuracy'])
# Trains for 5 epochs.
model.fit(data, labels, batch_size=32, epochs=5)
Epoch 1/5
1000/1000 [==============================] - 0s 224us/step - loss: 11.5206 - acc: 0.0990
Epoch 2/5
1000/1000 [==============================] - 0s 62us/step - loss: 11.5128 - acc: 0.1070
Epoch 3/5
1000/1000 [==============================] - 0s 64us/step - loss: 11.5023 - acc: 0.0980
Epoch 4/5
1000/1000 [==============================] - 0s 65us/step - loss: 11.4941 - acc: 0.0980
Epoch 5/5
1000/1000 [==============================] - 0s 66us/step - loss: 11.4879 - acc: 0.0990
网友评论