Keras Sequential 模型

Last updated: 2022-06-27, 11:26


1. 配置

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers

2. 何时使用序列模型

序列(Sequential)模型适合于简单的层堆栈,每层只有一个输入张量和一个输出张量。

从语法上来说,下面的序列模型:

# 定义 3 层 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)

与下面的函数定义等价:

# 创建 3 个 layer
layer1 = layers.Dense(2, activation="relu", name="layer1")
layer2 = layers.Dense(3, activation="relu", name="layer2")
layer3 = layers.Dense(4, name="layer3")

# 在测试输入上调用 layers
x = tf.ones((3, 3))
y = layer3(layer2(layer1(x)))

以下情形不适合用 Sequential 模型:

  • 有多个输入或多个输出;
  • 包含有多个输入或多个输出的网络层;
  • 需要 layer 共享;
  • 需要非线性拓扑结构。

3. 创建序列模型

将 layer 列表传递给 Sequential 的构造函数来创建序列模型:

model = keras.Sequential(
    [
        layers.Dense(2, activation="relu"),
        layers.Dense(3, activation="relu"),
        layers.Dense(4),
    ]
)

这些 layers 可以通过 layers 属性访问:

>>> model.layers
[<keras.layers.core.dense.Dense at 0x1e0d4f2a580>,
 <keras.layers.core.dense.Dense at 0x1e0d4f2ad90>,
 <keras.layers.core.dense.Dense at 0x1e0d4f2aa30>]

也可以通过 add() 逐步添加 layer:

model = keras.Sequential()
model.add(layers.Dense(2, activation="relu"))
model.add(layers.Dense(3, activation="relu"))
model.add(layers.Dense(4))

还可以使用 pop() 方法移除 layer:

>>> model.pop()
>>> print(len(model.layers))
2

可以使用 name 参数为创建的模型命名:

model = keras.Sequential(name="my_sequential")
model.add(layers.Dense(2, activation="relu", name="layer1"))
model.add(layers.Dense(3, activation="relu", name="layer2"))
model.add(layers.Dense(4, name="layer3"))

4. 指定输入 shape

通常来说,Keras 中的所有 layers 需要知道其输入 shape,才能创建对应的 weights。

  • 按照如下方式创建 layer,由于不知道输入 shape,所以其初始状态没有 weights:
>>> layer = layers.Dense(3)
>>> layer.weights # 空 list
[]
  • Keras 在第一次调用时根据输入 shape 创建权重矩阵,因为权重矩阵的 shape 依赖于输入的 shape
>>> # 在测试输入上调用 layer
>>> x = tf.ones((1, 4))
>>> y = layer(x)
>>> layer.weights  # Now it has weights, of shape (4, 3) and (3,)
[<tf.Variable 'dense_6/kernel:0' shape=(4, 3) dtype=float32, numpy=
 array([[-0.57910645,  0.01889718,  0.81052744],
        [-0.6837379 , -0.6663338 , -0.09140235],
        [ 0.91084313, -0.40995848,  0.41564345],
        [-0.3284163 , -0.52211523,  0.5777253 ]], dtype=float32)>,
 <tf.Variable 'dense_6/bias:0' shape=(3,) dtype=float32, numpy=array([0., 0., 0.], dtype=float32)>]

上述行为也适用于 Sequential 模型,在实例化没有输入的 Sequential 模型时,它还没有构建,因此也没有 weights,此时调用 model.weights 会出错。在接受输入数据后,模型才创建 weights:

>>> model = keras.Sequential([
        layers.Dense(2, activation='relu'),
        layers.Dense(3, activation='relu'),
        layers.Dense(4)
    ]) # 此时没有 weights
>>> model.weights # 会抛出错误
ValueError: Weights for model sequential_4 have not yet been created. Weights are created when the Model is first called on inputs or `build()` is called with an `input_shape`.
>>> model.summary() # 也会抛出错误
ValueError: This model has not yet been built. Build the model first by calling `build()` or by calling the model on a batch of data.
>>> x = tf.ones((1, 4))
>>> y = model(x)
>>> len(model.weights)
6
>>> model.summary()
Model: "sequential_4"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 dense_7 (Dense)             (1, 2)                    10        
                                                                 
 dense_8 (Dense)             (1, 3)                    9         
                                                                 
 dense_9 (Dense)             (1, 4)                    16        
                                                                 
=================================================================
Total params: 35
Trainable params: 35
Non-trainable params: 0

以递增的方式构建 Sequential 模型时,并随时使用 summary 显示模型对验证模型的准确性很有效。此时可以通过向模型传递 Input 对象来启动模型,这样它从一开始就知道输入 shape:

model = keras.Sequential()
model.add(keras.Input(shape=(4,)))
model.add(layers.Dense(2, activation='relu'))

model.summary()
Model: "sequential_3"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 dense_7 (Dense)             (None, 2)                 10        
                                                                 
=================================================================
Total params: 10
Trainable params: 10
Non-trainable params: 0
_________________________________________________________________

需要注意的是,Input 对象没有作为 model.layers 的一部分进行显示,因为它不是一个 layer:

>>> model.layers
[<keras.layers.core.dense.Dense at 0x12ad7175730>]

还有一种更简单的指定输入 shape 的方法,对第一层传入 input_shape 参数即可:

>>> model = keras.Sequential()
>>> model.add(layers.Dense(2, activation='relu', input_shape=(4,)))
>>> model.summary()
Model: "sequential_7"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 dense_12 (Dense)            (None, 2)                 10        
                                                                 
=================================================================
Total params: 10
Trainable params: 10
Non-trainable params: 0

这样预定义输入 shape 的模型总有 weights 和输出 shape。

一般来说,如果知道输入 shape,对 Sequential 模型建议提前指定 shape。

5. 通用调试工作流

在构建新的 Sequential 模型时,使用 add() 逐步添加 layers,并使用 summary() 查看模型摘要很有用。例如,可以查看 Conv2DMaxPooling2D 层如何向下采样图像特征:

>>> model = keras.Sequential()
>>> model.add(keras.Input(shape=(250, 250, 3)))  # 250x250 RGB 图片
>>> model.add(layers.Conv2D(32, 5, strides=2, activation='relu'))
>>> model.add(layers.Conv2D(32, 3, activation='relu'))
>>> model.add(layers.MaxPooling2D(3))

# 此时输出的 shape 是多少?不好计算,但是可以直接输出
>>> model.summary()
Model: "sequential_8"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d (Conv2D)             (None, 123, 123, 32)      2432      
                                                                 
 conv2d_1 (Conv2D)           (None, 121, 121, 32)      9248      
                                                                 
 max_pooling2d (MaxPooling2D  (None, 40, 40, 32)       0         
 )                                                               
                                                                 
=================================================================
Total params: 11,680
Trainable params: 11,680
Non-trainable params: 0

# 此时输出 shape 为 (40, 40, 32),继续向下采样
>>> 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: "sequential_8"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d (Conv2D)             (None, 123, 123, 32)      2432      
                                                                 
 conv2d_1 (Conv2D)           (None, 121, 121, 32)      9248      
                                                                 
 max_pooling2d (MaxPooling2D  (None, 40, 40, 32)       0         
 )                                                               
                                                                 
 conv2d_2 (Conv2D)           (None, 38, 38, 32)        9248      
                                                                 
 conv2d_3 (Conv2D)           (None, 36, 36, 32)        9248      
                                                                 
 max_pooling2d_1 (MaxPooling  (None, 12, 12, 32)       0         
 2D)                                                             
                                                                 
 conv2d_4 (Conv2D)           (None, 10, 10, 32)        9248      
                                                                 
 conv2d_5 (Conv2D)           (None, 8, 8, 32)          9248      
                                                                 
 max_pooling2d_2 (MaxPooling  (None, 4, 4, 32)         0         
 2D)                                                             
                                                                 
=================================================================
Total params: 48,672
Trainable params: 48,672
Non-trainable params: 0

# 此时输出为 4x4 的 feature map,然后添加 global max pooling
>>> model.add(layers.GlobalMaxPooling2D())
# 以及最终的分类层
>>> model.add(layers.Dense(10))

最终模型如下:

>>> model.summary()
Model: "sequential_8"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d (Conv2D)             (None, 123, 123, 32)      2432      
                                                                 
 conv2d_1 (Conv2D)           (None, 121, 121, 32)      9248      
                                                                 
 max_pooling2d (MaxPooling2D  (None, 40, 40, 32)       0         
 )                                                               
                                                                 
 conv2d_2 (Conv2D)           (None, 38, 38, 32)        9248      
                                                                 
 conv2d_3 (Conv2D)           (None, 36, 36, 32)        9248      
                                                                 
 max_pooling2d_1 (MaxPooling  (None, 12, 12, 32)       0         
 2D)                                                             
                                                                 
 conv2d_4 (Conv2D)           (None, 10, 10, 32)        9248      
                                                                 
 conv2d_5 (Conv2D)           (None, 8, 8, 32)          9248      
                                                                 
 max_pooling2d_2 (MaxPooling  (None, 4, 4, 32)         0         
 2D)                                                             
                                                                 
 global_max_pooling2d (Globa  (None, 32)               0         
 lMaxPooling2D)                                                  
                                                                 
 dense_13 (Dense)            (None, 10)                330       
                                                                 
=================================================================
Total params: 49,002
Trainable params: 49,002
Non-trainable params: 0

6. 使用模型

准备好模型后:

  • 训练、评估模型,并使用模型进行推断;
  • 保存和恢复模型;
  • 使用多个 GPU 加速训练模型。

7. 使用序列模型提取特征

序列模型构建好后,其行为和 函数 API 模型类似,即每层都有 inputoutput 属性。这些属性可用来做一些简单的事情,比如用来快速创建模型,提取 Sequential 模型中所有中间层的输出:

initial_model = keras.Sequential(
    [
        keras.Input(shape=(250, 250, 3)),
        layers.Conv2D(32, 5, strides=2, activation="relu"),
        layers.Conv2D(32, 3, activation="relu"),
        layers.Conv2D(32, 3, activation="relu"),
    ]
)
feature_extractor = keras.Model(
    inputs=initial_model.inputs,
    outputs=[layer.output for layer in initial_model.layers],
)

# Call feature extractor on test input.
x = tf.ones((1, 250, 250, 3))
features = feature_extractor(x)

也可以只提取某一层的特征:

initial_model = keras.Sequential(
    [
        keras.Input(shape=(250, 250, 3)),
        layers.Conv2D(32, 5, strides=2, activation="relu"),
        layers.Conv2D(32, 3, activation="relu", name="my_intermediate_layer"), # 提取该层的输出
        layers.Conv2D(32, 3, activation="relu"),
    ]
)
feature_extractor = keras.Model(
    inputs=initial_model.inputs,
    outputs=initial_model.get_layer(name="my_intermediate_layer").output,
)
# Call feature extractor on test input.
x = tf.ones((1, 250, 250, 3))
features = feature_extractor(x)

8. 基于序列模型的迁移学习

迁移学习冻结模型的底层,只训练顶层。下面是两个常见的涉及序列模型的迁移学习范本。

首先,假设你有一个序列模型,需要冻结除最后一层外的所有层,此时只需要迭代模型的 model.layers(除最后一层),对每层设置 layer.trainable = False。如下:

model = keras.Sequential([
    keras.Input(shape=(784)),
    layers.Dense(32, activation='relu'),
    layers.Dense(32, activation='relu'),
    layers.Dense(32, activation='relu'),
    layers.Dense(10),
])

# 加载预训练的权重
model.load_weights(...)

# 冻结最后一层外的所有层
for layer in model.layers[:-1]:
  layer.trainable = False

# 重新编译和训练,此时只会更新最后一层的权重
model.compile(...)
model.fit(...)

另一种是使用序列模型堆叠预先训练过的模型和一些新初始化的分类层。如下:

# 加载预训练的基础卷积层
base_model = keras.applications.Xception(
    weights='imagenet',
    include_top=False,
    pooling='avg')

# 冻结基础模型
base_model.trainable = False

# 使用序列模型在顶部添加可训练的分类器
model = keras.Sequential([
    base_model,
    layers.Dense(1000),
])

# 编译,训练
model.compile(...)
model.fit(...)

使用迁移学习会经常使用这两种模式

9. 参考

  • https://www.tensorflow.org/guide/keras/sequential_model
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,针对你的问题,我可以给出一个简单的 Keras Sequential 模型进行图像识别的实现示例。 首先,我们需要导入必要的库: ```python import tensorflow as tf from tensorflow import keras from tensorflow.keras import layers ``` 然后,我们可以定义一个基本的 Sequential 模型: ```python model = keras.Sequential( [ keras.Input(shape=(28, 28, 1)), layers.Conv2D(32, kernel_size=(3, 3), activation="relu"), layers.MaxPooling2D(pool_size=(2, 2)), layers.Conv2D(64, kernel_size=(3, 3), activation="relu"), layers.MaxPooling2D(pool_size=(2, 2)), layers.Flatten(), layers.Dropout(0.5), layers.Dense(10, activation="softmax"), ] ) ``` 这里的模型包含两个卷积层和一个全连接层,其中使用了 relu 激活函数和 softmax 输出层。在模型定义中,我们还指定了输入数据的形状为 (28, 28, 1),这意味着我们将使用 28x28 像素的灰度图像作为输入。 接下来,我们可以编译模型并指定损失函数、优化器和评估指标: ```python model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"]) ``` 在训练模型之前,我们还需要将数据进行预处理,以便它们适合模型。例如,我们可以将像素值缩放到 0 到 1 之间,并将标签转换为 one-hot 编码: ```python (x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data() x_train = x_train.astype("float32") / 255.0 x_test = x_test.astype("float32") / 255.0 y_train = keras.utils.to_categorical(y_train, 10) y_test = keras.utils.to_categorical(y_test, 10) ``` 最后,我们可以开始训练模型: ```python model.fit(x_train, y_train, epochs=5, batch_size=64, validation_split=0.1) ``` 这里我们使用了 5 个 epoch 和 64 个批次的训练数据,并使用 10% 的数据作为验证集。在训练过程中,模型将尝试最小化交叉熵损失,并优化准确率。 以上就是一个简单的 Keras Sequential 模型进行图像识别的实现示例。希望对你有所帮助! ### 回答2: Keras Sequential是一种基于Python的高级神经网络API,它可以用于图像识别任务。图像识别是计算机视觉领域中的一个热门研究方向,它旨在让计算机能够自动识别和分类图像内容。 在Keras中使用Sequential模型进行图像识别,首先需要安装Keras和相关的依赖库。然后,我们可以使用Sequential类创建一个空的神经网络模型。通过逐步添加不同类型的层,如卷积层、池化层和全连接层,我们可以构建出一个完整的图像识别模型。 例如,对于图像分类任务,我们可以使用卷积层来提取图像中的特征,再通过全连接层对提取到的特征进行分类。我们可以根据不同的问题和数据集来调整模型的层数和参数。 在模型构建完成后,我们可以使用fit()函数将模型与训练数据进行拟合,从而进行模型训练。通过逐步迭代训练,我们可以逐渐提高模型的准确性。 在模型训练完成后,我们可以使用evaluate()函数对模型进行评估,可以计算出模型在测试数据上的准确率和其他指标。 接下来,我们可以使用模型对新的图像进行预测。通过调用predict()函数,我们可以获取预测结果,即图像的类别或是概率分布。 总之,Keras Sequential是一个非常方便和高效的工具,可以帮助我们基于神经网络进行图像识别。我们只需要按照一定的步骤构建模型、训练模型和预测模型即可。当然,更复杂的图像识别任务可能需要更多的技巧和技术手段,但Keras Sequential为我们提供了一个简单而直观的起点。 ### 回答3: Keras是一个开源的深度学习库,它提供了一种方便快捷的方式来构建神经网络模型,其中之一就是使用Sequential模型实现图像识别。 在Keras中使用Sequential模型进行图像识别,首先需要导入相关的库和模块,比如图像处理库(如PIL)、Keras库和一些辅助函数库(如numpy)等。然后,我们需要加载和预处理图像数据集。 对于图像识别问题,一般会使用卷积神经网络(Convolutional Neural Network, CNN)作为模型。通过添加多个卷积层、池化层和全连接层,可以逐渐提取图像特征并进行分类。 使用Sequential模型构建卷积神经网络模型的步骤如下: 1. 创建Sequential模型对象。 2. 添加卷积层,可指定卷积核的尺寸、激活函数等参数。这一层将对输入图像进行特征提取。 3. 添加池化层,可指定池化窗口的尺寸和池化类型。这一层将对卷积层的输出进行降维,减少参数数量。 4. 添加Flatten层,将池化层的输出展平为一维数组。 5. 添加全连接层,可指定神经元数量和激活函数等参数。这一层将通过学习对图像进行分类。 6. 编译模型,可以指定优化器、损失函数和评估指标等参数。 7. 训练模型,使用训练数据集进行模型训练,并指定训练的批次大小、迭代次数等参数。 8. 评估模型,使用测试数据集评估模型的性能,并计算准确率等指标。 在构建和训练模型之前,还需要进行数据预处理步骤,如图像归一化、标签编码等。 通过以上步骤,我们可以使用KerasSequential模型实现图像识别任务。在实际应用中,还可以尝试使用不同的激活函数、正则化技术、数据增强等方法来改善模型的性能和准确率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值