当前位置: 首页 > 知识库问答 >
问题:

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

斜博超
2023-03-14

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

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

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

对于现有模型,如果我将input\u形状从(2,4)更改为(None,4),我将收到以下错误:

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

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

考虑到这一点,有人能解释我如何能够利用可变输入形状吗?如果这里的问题是Flatten()层,考虑到输入应该在传递给密集层之前被展平,有什么方法可以解决这个问题?

提前感谢您的建议。

编辑:给出一个潜在训练集的示例——对于上面显示的input\u shape=(2,4)的模型,训练集可能如下所示,其中集合中的每个二维数组都有shape(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\u 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]]
        ])

共有2个答案

牟嘉
2023-03-14

如果预期的输出具有与输入相对应的变化的第一维度,则第一维度是样本数。在这种情况下,您只需从BatchNormalization中ommit input\u shape参数,然后添加一个具有多个特征的输入层

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

由于BatchNormalization是在轴=1上定义的,即在特征轴上定义的,因此不需要定义第一个维度,即批次大小。

模型摘要

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\U列上的每个样本生成形状(1,2)的输出,则x\U列中的每条线都是一个样本,在这种情况下,密集层将需要可变数量的参数,这对渐变下降没有意义。

在这种情况下,你可能正在寻找一个递归神经网络,这是一个不同的野兽,一个例子可能是这样的

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)
隆长卿
2023-03-14

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

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

 类似资料:
  • 问题内容: 在Keras中创建顺序模型时,我知道您在第一层中提供了输入形状。然后,此输入形状会构成 隐式 输入层吗? 例如,下面的模型明确指定了2个密集层,但这实际上是一个3层模型,即由输入形状隐含的一个输入层,一个具有32个神经元的隐藏密集层,然后一个具有10个可能输出的输出层组成的模型吗? 问题答案: 好吧,实际上它实际上 是 一个隐式输入层,即您的模型是一个具有三层“输入,隐藏和输出”的“老

  • 问题内容: 我正在尝试合并两个模型的输出,并使用keras顺序模型将它们作为第三模型的输入。型号1: 型号1: 型号3: 直到这里,我的理解是,来自两个模型的输出x和y被合并并作为第三模型的输入。但是当我全都喜欢的时候 in1和in2是尺寸为10000 * 750的两个numpy ndarray,其中包含我的训练数据,而np_res_array是相应的目标。 这给了我错误,因为“列表”对象没有属性

  • 我一直在尝试使用Keras构建一个多输入模型。我来自使用顺序模型,并且只有一个相当直接的输入。我一直在查看StackOverflow上的留档(https://keras.io/getting-started/functional-api-guide/)和一些答案(如何在Keras 2.0中“合并”顺序模型?)。基本上,我想要的是让两个输入训练一个模型。一个输入是一段文本,另一个是从该文本中提取的一

  • 我正在使用Keras构建一个CNN,以下Conv1D是我的第一层: 我正在培训以下功能: 其中,train\u df是一个由两列组成的pandas数据帧,其中,对于每一行,标签是一个int(0或1),有效载荷是一个用零填充/截断为1000的浮点数组。train\U df中的培训示例总数为15641。 模型编译,但在训练期间,我得到这个错误: 我看了这篇文章,试图将输入更改为1000个浮点长列表的数

  • 我正在尝试创建一维卷积模型,但我似乎无法获得正确的输入形状。以下是我所拥有的: 我收到以下错误: 有人有什么建议吗?

  • 问题内容: 我知道这是一个有很多问题的主题,但是我找不到解决问题的办法。 我正在使用遮罩层在可变长度输入上训练LSTM网络,但似乎没有任何效果。 输入形状(100、362、24),其中362为最大序列长度,特征为24,特征数为100,样本数为100(划分为75列/有效值为25)。 输出形状(100,362,1)随后转换为(100,362-N,1)。 这是我的网络的代码: 我的数据最后被填充。例: