Keras ValueError:尺寸必须相等,但输入形状为[?,9],[?, 300,400]的“ {{node Equal}}”的尺寸必须为9和400

时间:2020-10-17 15:15:31

标签: python keras neural-network tensorflow2.0

我正在尝试训练一个非常简单的Keras网络,以对另存为np.array的一些一次性编码图像进行分类。输入数据结构由一个.npy文件组成,具有500张图像(每张图像为RGB,每张3个阵列)和每个图像的一幅热编码阵列,以确定其分类。每个图像为400x300像素(宽x高),目标输出应为9类。因此,每个图像的形状为(300, 400, 3),每个热编码标签列表的长度为9

这是我当前正在使用的代码:

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("============================")

但是,当我尝试运行model.fit()时,总是遇到相同的错误:

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].

我一直在阅读Keras文档和许多SO问题,但是我无法弄清楚代码出了什么问题。我认为问题可能出在输入层的定义上,但是我尝试了其他配置并返回错误。

提前谢谢!

1 个答案:

答案 0 :(得分:0)

最后,我找到了适用于该系统的解决方案。它效率不高,因为它在运行时会占用大量内存,但至少会运行。问题在于模型本身,因为输入的形状(4D阵列。RGB通道为3维,目标标签为1维)与密集层不兼容。

在这种情况下,要定义密集层,必须先创建平坦层。除此之外,我还添加了Conv2D层作为第一个隐藏层。因此,该模型如下所示:

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'))

整个脚本如下:

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("============================")