python - Keras ValueError:尺寸必须相等,但输入形状为“{{node Equal}}”的尺寸为 9 和 400:[?,9], [?,300,400]
问题描述
我正在尝试训练一个非常简单的 Keras 网络来分类一些保存为np.array
. 输入数据结构由一个.npy
文件组成,其中包含 500 张图像(每个 3 个数组,因为它是 RGB)和一个带有每个图像的 one-hot 编码数组以确定它的分类。每张图像为 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 问题,但我无法弄清楚代码有什么问题。我认为问题可能出在输入层的定义中,但我尝试了其他配置并返回错误。
提前致谢!!
解决方案
最后,我找到了适用于该系统的解决方案。它不是很有效,因为它在运行时会消耗大量内存,但至少它可以运行。问题在于模型本身,因为输入的形状(4D 数组。RGB 通道为 3 维,目标标签为 1 维)与密集层不兼容。
在这种情况下,要定义密集层,必须先创建一个 Flatten 层。除此之外,我还添加了一个 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("============================")
推荐阅读
- javascript - 从对象数组中删除重复项的更好算法是什么?
- python - RandomForestClassifier 获得前 N 个预测和相应的概率
- c++ - 从 WCHAR 转换为 const unsigned char
- google-sheets - 谷歌表格公式突出显示基于重复的几个复选框?
- python - 如何制作一定长度的列表
- swift - 使用 stride 旋转对象
- python - 如何在 Python 中将变量添加到字典中?
- c++11 - 使用递归对向量进行排序的问题
- javascript - 如何在 nodejs 中设置导出默认值?
- c++ - 阐明 C++ 结构中数据类型的析构函数要求