我有一个Sequential模型定义如下:
model = Sequential([
BatchNormalization(axis=1,input_shape=(2,4)),
Flatten(),
Dense(256, activation='relu'),
BatchNormalization(),
Dropout(0.1),
Dense(2, activation='softmax')
])
我想更改此模型以接受可变形状的输入。具体而言,第一维需要是可变的。 阅读specifying the input shape上的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-d数组都具有形状(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]]
])
答案 0 :(得分:0)
答案 1 :(得分:0)
Keras中的输入形状必须先验固定,也许您应该使用PyTorch解决此问题(动态输入)。
要在Keras中解决该问题,只需找到第一维的最大长度,然后使用填充(零值)完成其他示例,直到它们达到最大长度。
答案 2 :(得分:0)
如果您的预期输出具有与输入对应的不同第一维,则第一维是样本数。在这种情况下,您可以从 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层需要可变数量的参数,这对梯度下降没有意义。
在这种情况下,您可能正在寻找一个递归神经网络,这是一个不同的野兽,一个例子可能是这样的
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)