Сценарий Keras Python иногда работает нормально, иногда происходит сбой с несовместимым размером матрицы: в [0]: [10000,1], в [1]: [3,1] - PullRequest
0 голосов
/ 25 сентября 2018

Я хочу, чтобы Keras распознал Селфи и не Селфи, сначала я разрабатываю только 4 изображения, прежде чем использовать полные данные.

Проблема : Скрипт иногда запускается и завершается нормально,иногда происходит сбой с ошибкой Matrix size-incompatible: In[0]: [10000,1], In[1]: [3,1] ниже:

$ python run.py
TensorFlow version: 1.10.1
file_names: ['selfies-dev-data/0/lego.jpg', 'selfies-dev-data/0/dakota.jpg', 'selfies-dev-data/1/ammar.jpg', 'selfies-dev-data/1/olivier.jpg']
labels: [0.0, 0.0, 1.0, 1.0]
dataset: <PrefetchDataset shapes: ((?, 100, 100, 1), (?, 1)), types: (tf.float32, tf.float32)>
images: Tensor("IteratorGetNext:0", shape=(?, 100, 100, 1), dtype=float32)
labels: Tensor("IteratorGetNext:1", shape=(?, 1), dtype=float32)
Epoch 1/1
2018-09-25 13:59:17.285143: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
1/2 [==============>...............] - ETA: 0s - loss: 0.7741 - acc: 0.0000e+00Traceback (most recent call last):
  File "run.py", line 64, in <module>
    model.fit(images, labels, epochs=1, steps_per_epoch=2)
  File "/home/nico/.local/lib/python2.7/site-packages/tensorflow/python/keras/engine/training.py", line 1363, in fit
    validation_steps=validation_steps)
  File "/home/nico/.local/lib/python2.7/site-packages/tensorflow/python/keras/engine/training_arrays.py", line 205, in fit_loop
    outs = f(ins)
  File "/home/nico/.local/lib/python2.7/site-packages/tensorflow/python/keras/backend.py", line 2914, in __call__
    fetched = self._callable_fn(*array_vals)
  File "/home/nico/.local/lib/python2.7/site-packages/tensorflow/python/client/session.py", line 1382, in __call__
    run_metadata_ptr)
  File "/home/nico/.local/lib/python2.7/site-packages/tensorflow/python/framework/errors_impl.py", line 519, in __exit__
    c_api.TF_GetCode(self.status.status))
tensorflow.python.framework.errors_impl.InvalidArgumentError: Matrix size-incompatible: In[0]: [10000,1], In[1]: [3,1]
         [[Node: rgb_to_grayscale/Tensordot/MatMul = MatMul[T=DT_FLOAT, transpose_a=false, transpose_b=false](rgb_to_grayscale/Tensordot/Reshape, rgb_to_grayscale/Tensordot/Reshape_1)]]
         [[Node: IteratorGetNext = IteratorGetNext[output_shapes=[[?,100,100,1], [?,1]], output_types=[DT_FLOAT, DT_FLOAT], _device="/job:localhost/replica:0/task:0/device:CPU:0"](OneShotIterator)]]

Как исследовать проблему?Код изменяет размеры изображений до 100 * 100, а входной слой также имеет размер 100 * 100, я не знаю, откуда взялся 3.

Для справки, вот мой исходный код:

import os
import tensorflow as tf
print "TensorFlow version: " + tf.__version__

out_shape = tf.convert_to_tensor([100, 100])
batch_size = 2

data_folders = ["selfies-dev-data/0", "selfies-dev-data/1"]
classes = [0., 1.]
epoch_size = len(data_folders)

file_names = [] # Path of all data files
labels = [] # Label of each data file (same size as the array above)
for d, l in zip(data_folders, classes):
    name = [os.path.join(d,f) for f in os.listdir(d)] # get the list of all the images file names
    file_names.extend(name)
    labels.extend([l] * len(name))

print "file_names: " + str(file_names)
print "labels: " +str(labels)

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))
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 aspect 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
    label = tf.expand_dims(label, axis=-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)
print "dataset: " + str(dataset)

images, labels = dataset.make_one_shot_iterator().get_next()

# 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, 1)),
    keras.layers.Dense(128, activation=tf.nn.relu),
    keras.layers.Dense(1, activation=tf.nn.sigmoid)
])

model.compile(optimizer=tf.train.AdamOptimizer(),
              loss='binary_crossentropy',
              metrics=['accuracy'])

print "images: " + str(images)
print "labels: " + str(labels)
model.fit(images, labels, epochs=1, steps_per_epoch=2)

1 Ответ

0 голосов
/ 26 сентября 2018

Проблема, кажется, заключается в следующей строке:

image = tf.image.rgb_to_grayscale(image)

tf.image.rgb_to_grayscale ожидает, что данный тензор изображения будет иметь последнее измерение с размером 3, представляющее каналы RGB.Однако строка:

image = tf.image.decode_jpeg(tf.read_file(path))

может выдавать тензоры с разным количеством каналов.Это связано с тем, что tf.image.decode_jpeg по умолчанию создает тензор с тем же числом каналов, что и в данных JPEG.Таким образом, если у вас есть изображение, которое уже имеет оттенки серого, то у тензора будет только один канал, и программа завершится ошибкой.Вы можете решить эту проблему, запросив во всех случаях декодировать данные JPEG как изображение RGB, установив для параметра channels значение 3:

image = tf.image.decode_jpeg(tf.read_file(path), channels=3)

Это обеспечит одинаковую обработку всех ваших изображений..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...