检查输入时出错:预期 flatten_input 有 3 个维度,但得到了形状为 (None, 100, 100, 1) 的数组
Posted
技术标签:
【中文标题】检查输入时出错:预期 flatten_input 有 3 个维度,但得到了形状为 (None, 100, 100, 1) 的数组【英文标题】:Error when checking input: expected flatten_input to have 3 dimensions, but got array with shape (None, 100, 100, 1) 【发布时间】:2019-02-25 16:46:42 【问题描述】:使用TensorFlow/Keras,我想将图片分为自拍和非自拍两类。
我已将样本收集到两个文件系统文件夹中,每个类别一个。
在使用从文件系统加载图片后,我按照 MNIST 时尚的官方教程(这也是一个图片分类问题)实施了下面的训练,如 https://***.com/a/52417770/226958 所示。
很遗憾,我收到一个错误:
1.10.1
Tensor("IteratorGetNext:0", shape=(?, 100, 100, 1), dtype=float32)
Tensor("IteratorGetNext:1", shape=(?,), dtype=int32)
Traceback (most recent call last):
File "run.py", line 50, in <module>
model.fit(images, labels, epochs=1, steps_per_epoch=60000)
File "/home/nico/.local/lib/python2.7/site-packages/tensorflow/python/keras/engine/training.py", line 1278, in fit
validation_split=validation_split)
File "/home/nico/.local/lib/python2.7/site-packages/tensorflow/python/keras/engine/training.py", line 878, in _standardize_user_data
exception_prefix='input')
File "/home/nico/.local/lib/python2.7/site-packages/tensorflow/python/keras/engine/training_utils.py", line 182, in standardize_input_data
'with shape ' + str(data_shape))
ValueError: Error when checking input: expected flatten_input to have 3 dimensions, but got array with shape (None, 100, 100, 1)
这里是源代码:
import tensorflow as tf
print(tf.__version__)
out_shape = tf.convert_to_tensor([100, 100])
batch_size = 2
image_paths, labels = ["selfies-data/1", "selfies-data/2"], [1, 2]
epoch_size = len(image_paths)
image_paths = tf.convert_to_tensor(image_paths, dtype=tf.string)
labels = tf.convert_to_tensor(labels)
# The images loading part is from https://***.com/a/52417770/226958
dataset = tf.data.Dataset.from_tensor_slices((image_paths, labels))
dataset = dataset.repeat().shuffle(epoch_size)
def map_fn(path, label):
# path/label represent values for a single example
image = tf.image.decode_jpeg(tf.read_file(path))
# some mapping to constant size - be careful with distorting aspec ratios
image = tf.image.resize_images(image, out_shape)
image = tf.image.rgb_to_grayscale(image)
# color normalization - just an example
image = tf.to_float(image) * (2. / 255) - 1
return image, label
# num_parallel_calls > 1 induces intra-batch shuffling
dataset = dataset.map(map_fn, num_parallel_calls=8)
dataset = dataset.batch(batch_size)
dataset = dataset.prefetch(1)
images, labels = dataset.make_one_shot_iterator().get_next()
# All of the following is from https://www.tensorflow.org/tutorials/keras/basic_classification
from tensorflow import keras
model = keras.Sequential([
keras.layers.Flatten(input_shape=(100, 100)),
keras.layers.Dense(128, activation=tf.nn.relu),
keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer=tf.train.AdamOptimizer(),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
print(images)
print(labels)
model.fit(images, labels, epochs=epoch_size, steps_per_epoch=60000)
虽然我已阅读过类似的问题,但我没有看到与此 None
相关的任何问题。
如何使 Keras 适应我的输入,或转换我的输入以使 Keras 接受它?
【问题讨论】:
【参考方案1】:1) 图像有一个通道,因此这必须反映在输入形状参数中:
keras.layers.Flatten(input_shape=(100, 100, 1))
2) 要使用tf.data
API 加载文件,您需要先获取图像文件名及其对应的标签:
image_paths, lbls = ["selfies-data/1", "selfies-data/2"], [0., 1.]
labels = []
file_names = []
for d, l in zip(image_paths, lbls):
# get the list all the images file names
name = [os.path.join(d,f) for f in os.listdir(d)]
file_names.extend(name)
labels.extend([l] * len(name))
file_names = tf.convert_to_tensor(file_names, dtype=tf.string)
labels = tf.convert_to_tensor(labels)
dataset = tf.data.Dataset.from_tensor_slices((file_names, labels))
# the rest is the same
您可能还需要扩展labels
的维度,使其具有(?, 1)
的形状(而不是(?,)
)。为此,您可以在map_fn
函数中加入以下行:
labels = tf.expand_dims(labels, axis=-1)
3) 如果你有两个类,那么为什么最后一层有 10 个单元?这是一个二元分类问题,所以让最后一层有一个带有sigmoid
激活的单元。最后把loss改成binary_crossentropy
:
# ...
keras.layers.Dense(1, activation=tf.nn.sigmoid)
])
model.compile(optimizer=tf.train.AdamOptimizer(),
loss='binary_crossentropy',
metrics=['accuracy'])
【讨论】:
非常感谢,感谢您的提示,我取得了巨大的进步!以上是关于检查输入时出错:预期 flatten_input 有 3 个维度,但得到了形状为 (None, 100, 100, 1) 的数组的主要内容,如果未能解决你的问题,请参考以下文章
检查输入时出错:预期 input_1 有 4 个维度,但得到了形状为 (224, 224, 3) 的数组
Keras 嵌入层 - ValueError:检查输入时出错:预期有 2 个维度,但得到了 (39978, 20, 20)
ValueError:检查输入时出错:预期dense_1_input的形状为(180,),但数组的形状为(1,)
Keras 图像分类:检查输入时出错:预期 input_1 有 4 个维度,但得到了形状为 (6885、7500) 的数组
检查输入时出错:预期 lstm_input 有 3 个维度,但得到的数组形状为 (4, 1)
ValueError:检查输入时出错:预期的dense_26_input具有形状(45781,)但得到的数组具有形状(2,)