Keras ValueError: Dimensions must be equal, but are 9 and 400 for '{{node Equal}}' with input shapes: [?,9], [?,300,400]

我们两清 提交于 2021-01-28 06:11:48

问题


I'm trying to train a very simple Keras network to classify some one-hot encoded images saved as np.array. The input data structure is made of a .npy file, with 500 images (3 arrays each one, as it's RGB) and a one-hot encoded array with each image to determine it's classification. Each image is 400x300 pixels (Width x Height), and the target output should be of 9 classes. Hence, each image has a shape of (300, 400, 3) and each one-hot encoded label list has a length of 9.

This is the code that I am currently using:

import numpy as np
import cv2
import time
import os
import pandas as pd
from collections import deque
from random import shuffle
import pickle

# Do not display following messages:
# 0 = all messages are logged (default behavior)
# 1 = INFO messages are not printed
# 2 = INFO and WARNING messages are not printed
# 3 = INFO, WARNING, and ERROR messages are not printed
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

import tensorflow as tf
physical_devices = tf.config.experimental.list_physical_devices('GPU')
tf.config.experimental.set_memory_growth(physical_devices[0],True)

#os.environ["KERAS_BACKEND"] = "plaidml.keras.backend"

from keras import Input
from keras.models import load_model


lr = 0.01 # Learning Rate

WIDTH = 400
HEIGHT = 300


file_name = 'path/to/training_data.npy'
train_data = np.load(file_name, allow_pickle=True)

SAMPLE = len(train_data)
print('training_data.npy - Sample Size: {}'.format(SAMPLE))

X = np.array([i[0] for i in train_data]) / 255.0 # Divide to normalize values between 0 and 1
print('X shape: {}'.format(str(X.shape)))
Y = np.array([i[1] for i in train_data])

print("============================")
model = tf.keras.models.Sequential()
model.add(tf.keras.Input(shape=(WIDTH, HEIGHT, 3)))
model.add(tf.keras.layers.Dense(512, activation='relu'))
model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(tf.keras.layers.Dense(9, activation='softmax'))

model.compile(
              optimizer = tf.keras.optimizers.SGD(lr=lr),
              loss = 'mse',
              metrics = ['acc']
              )

model.summary()

model.fit(X, Y, epochs=5)
print("============================")

However, when I try to run model.fit(), I always face the same error:

WARNING:tensorflow:Model was constructed with shape (None, 400, 300, 3) for input Tensor("input_1:0", shape=(None, 400, 300, 3), dtype=float32), but it was called on an input with incompatible shape (None, 300, 400, 3).
Traceback (most recent call last):
  File "test.py", line 78, in <module>
    model.fit(X, Y, epochs=5)
  File "D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\keras\engine\training.py", line 108, in _method_wrapper
    return method(self, *args, **kwargs)
  File "D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\keras\engine\training.py", line 1098, in fit
    tmp_logs = train_function(iterator)
  File "D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\eager\def_function.py", line 780, in __call__
    result = self._call(*args, **kwds)
  File "D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\eager\def_function.py", line 823, in _call
    self._initialize(args, kwds, add_initializers_to=initializers)
  File "D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\eager\def_function.py", line 697, in _initialize
    *args, **kwds))
  File "D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\eager\function.py", line 2855, in _get_concrete_function_internal_garbage_collected
    graph_function, _, _ = self._maybe_define_function(args, kwargs)
  File "D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\eager\function.py", line 3213, in _maybe_define_function
    graph_function = self._create_graph_function(args, kwargs)
  File "D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\eager\function.py", line 3075, in _create_graph_function
    capture_by_value=self._capture_by_value),
  File "D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\framework\func_graph.py", line 986, in func_graph_from_py_func
    func_outputs = python_func(*func_args, **func_kwargs)
  File "D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\eager\def_function.py", line 600, in wrapped_fn
    return weak_wrapped_fn().__wrapped__(*args, **kwds)
  File "D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\framework\func_graph.py", line 973, in wrapper
    raise e.ag_error_metadata.to_exception(e)
ValueError: in user code:

    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\keras\engine\training.py:806 train_function  *
        return step_function(self, iterator)
    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\keras\engine\training.py:796 step_function  **
        outputs = model.distribute_strategy.run(run_step, args=(data,))
    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\distribute\distribute_lib.py:1211 run
        return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\distribute\distribute_lib.py:2585 call_for_each_replica
        return self._call_for_each_replica(fn, args, kwargs)
    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\distribute\distribute_lib.py:2945 _call_for_each_replica
        return fn(*args, **kwargs)
    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\keras\engine\training.py:789 run_step  **
        outputs = model.train_step(data)
    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\keras\engine\training.py:759 train_step
        self.compiled_metrics.update_state(y, y_pred, sample_weight)
    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\keras\engine\compile_utils.py:409 update_state
        metric_obj.update_state(y_t, y_p, sample_weight=mask)
    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\keras\utils\metrics_utils.py:90 decorated
        update_op = update_state_fn(*args, **kwargs)
    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\keras\metrics.py:176 update_state_fn
        return ag_update_state(*args, **kwargs)
    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\keras\metrics.py:612 update_state  **
        matches = ag_fn(y_true, y_pred, **self._fn_kwargs)
    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\util\dispatch.py:201 wrapper
        return target(*args, **kwargs)
    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\keras\metrics.py:3309 sparse_categorical_accuracy
        return math_ops.cast(math_ops.equal(y_true, y_pred), K.floatx())
    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\util\dispatch.py:201 wrapper
        return target(*args, **kwargs)
    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\ops\math_ops.py:1613 equal
        return gen_math_ops.equal(x, y, name=name)
    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\ops\gen_math_ops.py:3224 equal
        name=name)
    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\framework\op_def_library.py:744 _apply_op_helper
        attrs=attr_protos, op_def=op_def)
    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\framework\func_graph.py:593 _create_op_internal
        compute_device)
    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\framework\ops.py:3485 _create_op_internal
        op_def=op_def)
    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\framework\ops.py:1975 __init__
        control_input_ops, op_def)
    D:\Anaconda3\envs\pygta5_env_tf2.0\lib\site-packages\tensorflow\python\framework\ops.py:1815 _create_c_op
        raise ValueError(str(e))

    ValueError: Dimensions must be equal, but are 9 and 400 for '{{node Equal}} = Equal[T=DT_FLOAT, incompatible_shape_error=true](Cast_1, Cast_2)' with input shapes: [?,9], [?,300,400].

I have been reading Keras documentation and lots of SO questions, but I can't figure out what's wrong with the code. I think that the problem might be located in the definiton of the input layer, but I have tried other configurations and returns errors as well.

Thanks in advance!!


回答1:


Finally, I've found a solution that works for the system. It's not very efficient as it consumes a lot of memory while running, but at least it runs. The problem was the model itself, as the shape of the input (4D array. 3 dimensions for RGB channels and 1 dimension for target labels) was incompatible with the dense layer.

To define a Dense layer in this case, it's necessary to create previously a Flatten layer. Besides this, I've added a Conv2D layer as first hidden layer. Thus, the model looks like this:

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Conv2D(filters=2, kernel_size=2, input_shape=(HEIGHT,WIDTH,3)))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(9, activation='relu'))

And whole script like this:

import numpy as np
import cv2
import time
import os
import pandas as pd
from collections import deque
from random import shuffle
import pickle

# Do not display following messages:
# 0 = all messages are logged (default behavior)
# 1 = INFO messages are not printed
# 2 = INFO and WARNING messages are not printed
# 3 = INFO, WARNING, and ERROR messages are not printed
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

import tensorflow as tf
physical_devices = tf.config.experimental.list_physical_devices('GPU')
tf.config.experimental.set_memory_growth(physical_devices[0],True)

#os.environ["KERAS_BACKEND"] = "plaidml.keras.backend"

from keras import Input
from keras.models import load_model


lr = 0.01 # Learning Rate

WIDTH = 400
HEIGHT = 300


file_name = 'path/to/training_data.npy'
train_data = np.load(file_name, allow_pickle=True)

SAMPLE = len(train_data)
print('training_data.npy - Sample Size: {}'.format(SAMPLE))

X = np.array([i[0] for i in train_data]) / 255.0 # Divide to normalize values between 0 and 1
print('X shape: {}'.format(str(X.shape)))
Y = np.array([i[1] for i in train_data])

print("============================")
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Conv2D(filters=2, kernel_size=2, input_shape=(HEIGHT,WIDTH,3)))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(9, activation='relu'))

model.compile(
              optimizer = tf.keras.optimizers.SGD(lr=lr),
              loss = 'mse',
              metrics = ['acc']
              )

model.summary()

model.fit(X, Y, epochs=5)
print("============================")


来源:https://stackoverflow.com/questions/64404009/keras-valueerror-dimensions-must-be-equal-but-are-9-and-400-for-node-equal

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!