繁体   English   中英

Keras 顺序模型的可变输入形状

[英]Variable Input Shape for Keras Sequential Model

我有一个定义如下的顺序模型:

model = Sequential([
    BatchNormalization(axis=1,input_shape=(2,4)),
    Flatten(),
    Dense(256, activation='relu'),       
    BatchNormalization(),
    Dropout(0.1),
    Dense(2, activation='softmax')
])

我想更改此模型以获取可变形状的输入。 具体来说,第一个维度需要可变。 阅读有关指定输入形状的 Keras 文档,我看到您可以在 input_shape 元组中使用 None 条目,其中 None 表示可能需要任何正整数。

使用我现有的模型,如果我将 input_shape 从 (2,4) 更改为 (None,4),我会收到以下错误:

---> Dense(2, activation='softmax')
TypeError: an integer is required

我不是肯定的,但我不相信当模型包含 Flatten() 层时可以指定可变输入形状。 我读过 Flatten() 需要知道输入形状,因此可变输入形状与 Flatten() 不兼容。 如果我删除 Flatten() 层,我会收到与上面相同的错误。 我不希望这个模型在没有 Flatten() 层的情况下工作,因为我相信输入在传递到 Dense 层之前被展平是一个要求。

鉴于此,任何人都可以解释我如何能够利用可变输入形状吗? 如果这里的问题是 Flatten() 层,那么在将输入传递到 Dense 层之前应将其展平的情况下,有哪些方法可以解决这个问题?

在此先感谢您的任何建议。

编辑:举一个潜在训练集的例子——对于上面显示的带有 input_shape=(2,4) 的模型,训练集可能如下所示,其中每个二维数组的形状为 (2, 4):

x_train = np.array([
         [[1, 1.02, 1.3, 0.9], [1.1, 1.2, 0.91, 0.99]], 
         [[1, 1.02, 1.3, 0.9], [1.1, 1.2, 0.91, 0.99]],
         [[1.01 ,1, 1.2, 1.2], [1.3, 1.2, 0.89, 0.98]]
        ])

对于 input_shape = (None,4) 的数据,其中每个数据点的第一个维度的形状可以变化,第二个维度固定为 4,训练集可能如下所示:

x_train = np.array([
         [[1, 1.02, 1.3, 0.9], [1.1, 1.2, 0.91, 0.99], [1.1, 1.2, 0.91, 0.99]], 
         [[1, 1.02, 1.3, 0.9], [1.1, 1.2, 0.91, 0.99]],
         [[1,1,1,1], [1.3, 1.2, 0.89, 0.98], [1,1,1,1], [1,1,1,1]]
        ])

x_train 具有可变维度,这会在训练阶段引起问题。 如果我们填充额外的零,它会对您的数据产生重大影响吗? 如果不是,请找出不同维度的最大值并相应地构建新数组,如下图所示,在 jupyter notebook 中: x_train 和 x_train2 的维度

填充零的方式

Keras 中的输入形状必须是先验固定的,也许你应该使用 PyTorch 来解决这个问题(动态输入)。

要在 Keras 中解决它,只需找到第一个维度的最大长度,然后使用填充(零值)来完成其他示例,直到它们达到最大长度。

如果您的预期输出具有与输入对应的不同第一维,则第一维是样本数。 在这种情况下,您可以只省略 BatchNormalization 中的 input_shape 参数并添加一个包含特征数量的输入层

model = Sequential([
  Input(4),
  BatchNormalization(axis=1),
  Flatten(),
  Dense(256, activation='relu'),       
  BatchNormalization(),
  Dropout(0.1),
  Dense(2, activation='softmax')
])

由于你的BatchNormalization定义在axis=1上,也就是特征轴上,所以你不需要定义第一个维度,也就是batch size。

模型总结

model.summary()
>>>
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
batch_normalization (BatchNo (None, 4)                 16        
_________________________________________________________________
flatten (Flatten)            (None, 4)                 0         
_________________________________________________________________
dense (Dense)                (None, 256)               1280      
_________________________________________________________________
batch_normalization_1 (Batch (None, 256)               1024      
_________________________________________________________________
dropout (Dropout)            (None, 256)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 2)                 514       
=================================================================
Total params: 2,834
Trainable params: 2,314
Non-trainable params: 520

然后你可以在你的输入上运行它

model.predict(x_train[0])
>>> array([[0.36491784, 0.63508224],
   [0.3834786 , 0.61652136],
   [0.3834786 , 0.61652136]], dtype=float32)

model.predict(x_train[1])
>>> array([[0.36491784, 0.63508224],
   [0.38347858, 0.61652136]], dtype=float32)

但是,如果您想为 x_train 上的每个样本生成形状 (1,2) 的输出,那么 x_train 中的每一行都是一个样本,在这种情况下,您的Dense 层将需要可变数量的参数,这不需要对梯度下降有意义。

在那种情况下,您可能正在寻找一个Recursive Neural Network ,这是一个不同的野兽,一个例子可能是这样的

model = tf.keras.Sequential()
model.add(Input((None, 4)))

model.add(LSTM(128))

model.add(Dense(2))

型号概要

model.summary()
>>>
Model: "sequential_5"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
lstm_3 (LSTM)                (None, 128)               68096     
_________________________________________________________________
dense_4 (Dense)              (None, 2)                 258       
=================================================================
Total params: 68,354
Trainable params: 68,354
Non-trainable params: 0

要在您的数据集上运行它,只需扩展每个样本的第一个维度,也就是说它是一个大小为 1 的批次,即单个样本。

model.predict(np.expand_dims(x_train[0],0))
>>>
array([[0.19657324, 0.09764521]], dtype=float32)

model.predict(np.expand_dims(x_train[1],0))
>>>
array([[0.15233153, 0.08189206]], dtype=float32)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM