【问题标题】:keras Input layer passes a 2 dimensional tensors while its shape is 1 dimensionalkeras 输入层传递一个二维张量,而它的形状是一维的
【发布时间】:2021-10-02 12:41:32
【问题描述】:

我正在使用 tensorflow 和 keras 迈出第一步,我创建了一个数据集,其中包含元组,其中嵌入了来自 VGG16 模型的图像作为数据和标签,它们是二进制多标签。例如,这是我的数据集中的一个元素的打印:

(<tf.Tensor: shape=(4096,), dtype=float32, numpy=
array([0.32185513, 0.14869851, 0.4276036 , ..., 0.        , 0.        ,
       1.7438936 ], dtype=float32)>, <tf.Tensor: shape=(12,), dtype=int32, numpy=array([0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0])>)

我建立了以下模型:

inputs = Input(shape = (4096,), name = 'input_1')
dense_1 = Dense(units = 2048, name = "dense_1", activation = 'sigmoid')(inputs)
dense_2 = Dense(units = 2048, name = "dense_2", activation = 'sigmoid')(dense_1)
output = Dense(units = 12, name = "output", activation = 'sigmoid')(dense_2)
model = Model(inputs = inputs, outputs = output)
model.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = 'accuracy')
model.summary()
model.fit(train_ds, validation_data = val_ds)

当我尝试拟合模型时出现以下错误

ValueError:dense_1 层的输入 0 与该层不兼容:输入形状的预期轴 -1 具有值 4096,但接收到形状为 [4096, 1] 的输入

据我了解,模型期望一维张量作为输入,但得到一个二维张量,数据集中的数组是一维的,因此我不明白为什么它们作为二维张量从输入层传递。 任何帮助找出导致此错误的原因以及如何解决它?

编辑: 创建数据集的代码是:

embed_train = np.load("Desktop/DL projects/pawpularity/petfinder-pawpularity-score/VGG16_embed.npy")
print(embed_train.shape)
>>>(9912, 4096)
print(train_labels.shape)
>>>(9912, 12)
train_ds = tf.data.Dataset.from_tensor_slices((embed_train, train_labels))
train_ds = train_ds.shuffle(10000)
test_ds = train_ds.take(1000)
train_ds = train_ds.skip(1000)
val_ds = train_ds.take(2000)
train_ds = train_ds.skip(2000)

embed_traintrain_labels 都是 numpy 数组,如您所见,我一共有 9912 个示例,每个示例包含 4096 个特征,需要针对每个标签进行分类(共 12 个标签)独立。

【问题讨论】:

  • 你能告诉我们train_ds.shape是什么吗?
  • 嗨,我编辑了问题并添加了数据集的代码,指定了我用来创建它的数组的形状

标签: python tensorflow keras deep-learning neural-network


【解决方案1】:

我能够使用Dataset 让您的代码正常工作,而是直接传递训练数据和标签。

import tensorflow as tf
import numpy as np
from tensorflow.keras import Input
from tensorflow.keras.layers import Dense
from tensorflow.keras.models import Model

# random data in your shape - you can split for validation/validation labels if you want. 
# You would use your own embed_train and labels here
embed_train = np.random.rand(9912, 4096) 
train_labels= np.random.randint(0, 12, [9912, 12])

inputs = Input(shape=(4096,), name ='input_1')
dense_1 = Dense(units = 2048, name = "dense_1", activation = 'sigmoid', input_shape=(4096,1))(inputs)
dense_2 = Dense(units = 2048, name = "dense_2", activation = 'sigmoid')(dense_1)
output = Dense(units = 12, name = "output", activation = 'sigmoid')(dense_2)
model = Model(inputs = inputs, outputs = output)
model.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = 'accuracy')
model.summary()
model.fit(embed_train , train_labels)

如果你想打乱数据,你可以使用another帖子中的这个答案:

indices = tf.range(start=0, limit=tf.shape(embed_train)[0], dtype=tf.int32)
idx = tf.random.shuffle(indices)

x_data = tf.gather(embed_train, idx)
y_data = tf.gather(train_labels, idx)

model.fit(x_data, y_data)

编辑: 对于数据集,我认为您需要指定批量大小:

train_ds = train_ds.batch(32)

model.fit(train_ds)

这适用于我的电脑。

【讨论】:

  • 谢谢! model.fit 确实以这种方式运行,但是我仍然很好奇为什么它不能与 tf 数据集一起使用,知道吗?
  • 在我的回复中编辑它。我想我明白为什么了。
  • 修复了,谢谢 :)
猜你喜欢
  • 2018-02-19
  • 1970-01-01
  • 1970-01-01
  • 2019-11-04
  • 1970-01-01
  • 2020-10-20
  • 1970-01-01
  • 2017-07-08
  • 2019-01-30
相关资源
最近更新 更多