Sequential模型使用于layer的简单组合,而每一个layer只有一个输入和输出。下面的代码构建了一个简单的Sequential模型。
model = keras.Sequential([
layers.Dense(2, activation="relu", name="layer1"),
layers.Dense(3, activation="relu", name="layer2"),
layers.Dense(4, name="layer3")
])
x = tf.ones((3, 3))
y = model(x)
上面的代码也可以写为:
layer1 = layers.Dense(2, activation="relu", name="layer1")
layer2 = layers.Dense(3, activation="relu", name="layer2")
layer3 = layers.Dense(4, name="layer3")
x = tf.ones((3, 3))
y = layer3(layer2(layer1(x)))
Sequential模型不适用于以下情形:
- 模型需要有多个输入或输出的;
- 任何一个layer需要有多个输入或输出的;
- 需要共享layer的;
- 需要非线性拓扑的。
创建Sequential模型
只需要将多个layer传入,即可创建一个Sequentail模型。
model = keras.Sequential(
[
layers.Dense(2, activation="relu"),
layers.Dense(3, activation="relu"),
layers.Dense(4, name="layer3")
]
)
可以通过Sequentail模型的layers属性来查看模型包含的layer。
model = keras.Sequential(
[
layers.Dense(2, activation="relu"),
layers.Dense(3, activation="relu"),
layers.Dense(4, name="layer3")
]
)
print(model.layers)
Sequentail模型还提供了add和pop函数用以在创建之后增加和删除layer。同时,Sequentail模型还可以在创建时指定name参数,方便在TensorBoard显示。
model.add(layers.Dense(5))
print(model.layers)
model.pop()
print(model.layers)
显示结果为:
[<keras.layers.core.dense.Dense object at 0x0000024D2B6C1700>, <keras.layers.core.dense.Dense object at 0x0000024D4DE56C70>, <keras.layers.core.dense.Dense object at 0x0000024D4DE56820>, <keras.layers.core.dense.Dense object at 0x0000024D4DEE0310>]
[<keras.layers.core.dense.Dense object at 0x0000024D2B6C1700>, <keras.layers.core.dense.Dense object at 0x0000024D4DE56C70>, <keras.layers.core.dense.Dense object at 0x0000024D4DE56820>]
提前指定输入维度
通常,keras的所有layer需要知道输入的维度后才能创建权重变量。
首先对于一个layer来说,在未指定输入之前,权重变量都是空的。权重变量的创建发生在首次指定输入时。
layer = layers.Dense(3)
layer.weights # 此时权重为空
x = tf.ones((1, 4))
y = layer(x)
layer.weights # 此时权重不为空,权重变量的维度是(4, 3)
再次,对于一个Sequentail模型来说,当你初始化模型之时没有指定输入的维度时,模型并没有被实例化:即它没有权重变量。
权重变量的创建也出现在首次指定输入的时候。
model = keras.Sequential(
[
layers.Dense(2, activation="relu"),
layers.Dense(3, activation="relu"),
layers.Dense(4, name="layer3")
]
)
# model.weights # 此时weights为空
# model.summary() # 调用报错
x = tf.ones((1, 4)) # 此时发生了build
y = model(x)
model.summary()
结果为:
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (1, 2) 10
dense_1 (Dense) (1, 3) 9
layer3 (Dense) (1, 4) 16
=================================================================
Total params: 35
Trainable params: 35
Non-trainable params: 0
_________________________________________________________________
在增量的创建Sequential模型时,时常查看一下模型的summay是十分有用的。这时,你可以在创建Sequential模型之处便传入一个Input对象,使得Sequentail模型了解输入的维度。
model = keras.Sequential()
model.add(keras.Input(shape=(4,)))
model.add(layers.Dense(2, activation="relu"))
model.summary()
结果为:
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (None, 2) 10
=================================================================
Total params: 10
Trainable params: 10
Non-trainable params: 0
_________________________________________________________________
由于Input对象不是一个layer,所以调用model.layers时不会出现Input对象。
另外一种做法是,为第一个layer指定输入的维度。如:
model = keras.Sequential()
model.add(layers.Dense(2, activation="relu", input_shape=(4,)))
model.summary()
已经指定了输入维度的模型拥有权重变量,同时拥有输出的维度。在实践中,如果已经确定了输入的维度,建议你直接指定。
常用的调试流程
当创建一个Sequential模型时,通常的做法是动态的增加layer并查看模型的summary是否符合预期。例如,当需要使用conv2D和MaxPooling2D搭建Sequential模型时:
model = keras.Sequential()
model.add(keras.Input(shape=(250, 250, 3))) # 250x250 RGB images
model.add(layers.Conv2D(32, 5, strides=2, activation="relu"))
model.add(layers.Conv2D(32, 3, activation="relu"))
model.add(layers.MaxPooling2D(3))
# 通过查看model.summary来查看是否符合预期的输出
model.summary()
model.add(layers.Conv2D(32, 3, activation="relu"))
model.add(layers.Conv2D(32, 3, activation="relu"))
model.add(layers.MaxPooling2D(3))
model.add(layers.Conv2D(32, 3, activation="relu"))
model.add(layers.Conv2D(32, 3, activation="relu"))
model.add(layers.MaxPooling2D(2))
model.summary()
model.add(layers.GlobalMaxPooling2D())
model.add(layers.Dense(10))
model.summary()
网友评论