简体   繁体   English

tensorflow Keras:维度必须相等 ValueError

[英]tensorflow Keras: Dimenions must be equal ValueError

I'm trying to train a model in Keras to suggest the best possible next move when presented with a pawn chess board.我正在尝试在 Keras 中训练 model,以在出现棋盘时建议最佳下一步行动。 the board is represented as a list of 64 integers (0 for empty, 1 for player, 2 for enemy).棋盘表示为 64 个整数的列表(0 表示空,1 表示玩家,2 表示敌人)。 The output is represented by a list of a field and a direction that the figure on that field should move in, which means I need two ouput layers with size 64 (number of fields) and 5 (number of possible move directions, including two forward and no move for when the game is over). output 由字段列表和该字段上的图形应该移动的方向表示,这意味着我需要两个输出层,大小为 64(字段数)和 5(可能的移动方向数,包括两个前向并且在游戏结束时没有移动)。 I have a list of boards and a list of solutions.我有一个板列表和一个解决方案列表。 When I try to fit the model however, I get the above mentioned error.但是,当我尝试适合 model 时,出现上述错误。

The exact error message is:确切的错误信息是:

Epoch 1/75
Traceback (most recent call last):
  File "C:\Users\lulll\Documents\CodeStuff\tfTesting\main.py", line 75, in <module>
    model.fit(train_fig_starts, train_fig_moves, epochs=75)
  File "C:\Users\lulll\Documents\CodeStuff\tfTesting\venv\lib\site-packages\keras\utils\traceback_utils.py", line 70, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File "C:\Users\lulll\AppData\Local\Temp\__autograph_generated_filej0zia4d5.py", line 15, in tf__train_function
    retval_ = ag__.converted_call(ag__.ld(step_function), (ag__.ld(self), ag__.ld(iterator)), None, fscope)
ValueError: in user code:

    File "C:\Users\lulll\Documents\CodeStuff\tfTesting\venv\lib\site-packages\keras\engine\training.py", line 1249, in train_function  *
        return step_function(self, iterator)
    File "C:\Users\lulll\Documents\CodeStuff\tfTesting\venv\lib\site-packages\keras\engine\training.py", line 1233, in step_function  **
        outputs = model.distribute_strategy.run(run_step, args=(data,))
    File "C:\Users\lulll\Documents\CodeStuff\tfTesting\venv\lib\site-packages\keras\engine\training.py", line 1222, in run_step  **
        outputs = model.train_step(data)
    File "C:\Users\lulll\Documents\CodeStuff\tfTesting\venv\lib\site-packages\keras\engine\training.py", line 1024, in train_step
        loss = self.compute_loss(x, y, y_pred, sample_weight)
    File "C:\Users\lulll\Documents\CodeStuff\tfTesting\venv\lib\site-packages\keras\engine\training.py", line 1082, in compute_loss
        return self.compiled_loss(
    File "C:\Users\lulll\Documents\CodeStuff\tfTesting\venv\lib\site-packages\keras\engine\compile_utils.py", line 265, in __call__
        loss_value = loss_obj(y_t, y_p, sample_weight=sw)
    File "C:\Users\lulll\Documents\CodeStuff\tfTesting\venv\lib\site-packages\keras\losses.py", line 152, in __call__
        losses = call_fn(y_true, y_pred)
    File "C:\Users\lulll\Documents\CodeStuff\tfTesting\venv\lib\site-packages\keras\losses.py", line 284, in call  **
        return ag_fn(y_true, y_pred, **self._fn_kwargs)
    File "C:\Users\lulll\Documents\CodeStuff\tfTesting\venv\lib\site-packages\keras\losses.py", line 2176, in binary_crossentropy
        backend.binary_crossentropy(y_true, y_pred, from_logits=from_logits),
    File "C:\Users\lulll\Documents\CodeStuff\tfTesting\venv\lib\site-packages\keras\backend.py", line 5688, in binary_crossentropy
        bce = target * tf.math.log(output + epsilon())

    ValueError: Dimensions must be equal, but are 2 and 64 for '{{node binary_crossentropy/mul}} = Mul[T=DT_FLOAT](binary_crossentropy/Cast, binary_crossentropy/Log)' with input shapes: [?,2], [?,64].

I have absolutely no idea what is causing this.我完全不知道是什么原因造成的。 I've searched for the error already, but the only mentions I've found seem to be describing a completely different scenario.我已经搜索了错误,但我发现的唯一提及似乎描述了一个完全不同的场景。 Since it probably helps, here's the code used to create and fit the model:因为它可能有帮助,下面是用于创建和拟合 model 的代码:

inputs = tf.keras.layers.Input(shape=64)
x = tf.keras.layers.Dense(32, activation='relu')(inputs)
out_field = tf.keras.layers.Dense(64, name="field")(x)
out_movement = tf.keras.layers.Dense(5, name="movement")(x)

model = tf.keras.Model(inputs=inputs, outputs=[out_field, out_movement])

model.compile(optimizer='adam',
              loss=tf.keras.losses.BinaryCrossentropy(),
              metrics=['accuracy'])

model.fit(train_fig_starts, train_fig_moves, epochs=75) #train_fig_starts and moves are defined above

EDIT 1: Here's a sample of the dataset I'm using (the whole thing is too long for the character limit)编辑 1:这是我正在使用的数据集的示例(整个内容对于字符限制来说太长了)

train_fig_starts = [[0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 2, 0, 1, 0, 0, 0, 0, 1, 2, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 1], [0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0], [0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 1, 2, 2, 2, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 2, 2, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]]
train_fig_moves = [[0, 0], [0, 0], [0, 0], [0, 0], [15, 2], [15, 2]]

EDIT 2: I changed it to sparsecategorialcrossentropy since that seems more like what I'm looking for.编辑 2:我将其更改为 sparsecategorialcrossentropy 因为这看起来更像我正在寻找的东西。 This is now the model code这是现在的 model 代码

inputs = tf.keras.layers.Input(shape=64)
x = tf.keras.layers.Dense(64, activation='relu')(inputs)

out_field = tf.keras.layers.Dense(64, activation="relu",  name="field")(x)
out_field = tf.keras.layers.Dense(64, activation="softmax", name="field_softmax")(out_field)

out_movement = tf.keras.layers.Dense(5, activation="relu", name="movement")(x)
out_movement = tf.keras.layers.Dense(5, activation="softmax", name="movement_softmax")(out_movement)

model = tf.keras.Model(inputs=inputs, outputs=[out_field, out_movement])

print(model.summary())
tf.keras.utils.plot_model(model, to_file='model_plot.png', show_shapes=True, show_layer_names=True)

model.compile(optimizer='adam',
              loss=[tf.keras.losses.SparseCategoricalCrossentropy(),
                    tf.keras.losses.SparseCategoricalCrossentropy()],
              metrics=['accuracy'])

it still throws an error, this time its the following:它仍然会抛出错误,这次是以下错误:

Node: 'sparse_categorical_crossentropy_1/SparseSoftmaxCrossEntropyWithLogits/SparseSoftmaxCrossEntropyWithLogits'
logits and labels must have the same first dimension, got logits shape [32,5] and labels shape [64]
     [[{{node sparse_categorical_crossentropy_1/SparseSoftmaxCrossEntropyWithLogits/SparseSoftmaxCrossEntropyWithLogits}}]] [Op:__inference_train_function_1666]

I have no idea why its like that.我不知道为什么会这样。 Output logits and labels should both be [64, 2]. Output logits 和 labels 都应该是 [64, 2]。 Since I'm using sparse crossentropy I should be able to use integers in my training data to signify the "index" of the ouput neuron with the highest logit, right?因为我使用的是稀疏交叉熵,所以我应该能够在我的训练数据中使用整数来表示具有最高 logit 的输出神经元的“索引”,对吧? Correct me if I'm wrong.如我错了请纠正我。 If it helps, here's a diagram of my model: plot of the model如果有帮助,这是我的 model 的图表: model 的 plot

The problem is you are returning the 64-length output from the model which is called the logit and your loss function needs 2-length input.问题是您从 model 返回 64 位长度的 output,称为logit ,而您的损失 function 需要 2 位长度的输入。

import numpy as np
import tensorflow as tf

train_fig_starts = tf.constant([[0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 2, 0, 1, 0, 0, 0, 0, 1, 2, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 1], [0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0], [0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 1, 2, 2, 2, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 2, 2, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]])
train_fig_moves = tf.constant([[0, 0], [0, 0], [0, 0], [0, 0], [15, 2], [15, 2]])

inputs = tf.keras.layers.Input(shape=64)
x = tf.keras.layers.Dense(32, activation='relu')(inputs)
out_field = tf.keras.layers.Dense(64, activation='relu')(x)
out_field = tf.keras.layers.Dense(2, name="field" , activation='softmax')(out_field)

out_movement = tf.keras.layers.Dense(32, activation='relu')(x)
out_movement = tf.keras.layers.Dense(2, name="movement", activation='softmax')(out_movement)

model = tf.keras.Model(inputs=inputs, outputs=[out_field, out_movement])

model.compile(optimizer='adam',
              loss=tf.keras.losses.CategoricalCrossentropy(),
              metrics=['accuracy'])
model.fit(train_fig_starts, train_fig_moves, epochs=75) #train_fig_starts and moves are defined above
0s 8ms/step - loss: 5.2342 - field_loss: 2.7274 - movement_loss: 2.5068 - field_accuracy: 0.6667 - movement_accuracy: 1.0000

So I fixed the issue by myself now.所以我现在自己解决了这个问题。 Honestly it was a pretty stupid error to make but the error messages didn't really explain well what was going on.老实说,这是一个非常愚蠢的错误,但错误消息并没有很好地解释发生了什么。 I swapped the outputs for one hot encoding and changed the loss to CategorialCrossEntropy, which is also more fitting for a categorisation problem (Sparse didn't work with my integers for some reason).我将输出交换为一种热编码,并将损失更改为 CategorialCrossEntropy,这也更适合分类问题(由于某些原因,Sparse 不适用于我的整数)。 After that I needed to change the label list from a 1dim list containing lists of len = 2 to a 2dim list containing both the field and the move one hots in a separate list.之后,我需要将 label 列表从包含 len = 2 列表的 1dim 列表更改为包含字段和 move one hots 的 2dim 列表,在单独的列表中。 If anyone runs into a similar issue and can't make sense of it, maybe this will help.如果有人遇到类似的问题并且无法理解它,也许这会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ValueError:尺寸必须相等(keras) - ValueError: Dimensions must be equal (keras) Keras LSTM 层值错误:尺寸必须相等,但为 17 和 2 - Keras LSTM Layer ValueError: Dimensions must be equal, but are 17 and 2 Tensorflow错误:尺寸必须相等 - Tensorflow error : Dimensions must be equal ValueError:两个形状中的尺寸2必须相等,但分别为3和32 - ValueError: Dimension 2 in both shapes must be equal, but are 3 and 32 ValueError:尺寸必须相等,输入形状 - ValueError: Dimensions must be equal, with input shapes ValueError:输入张量必须具有等级 4 TensorFlow - ValueError: input tensor must have rank 4 TensorFlow ValueError:应在输入列表上调用合并层。 Tensorflow Keras - ValueError: A merge layer should be called on a list of inputs. Tensorflow Keras ValueError:使用可迭代设置时必须具有相等的 len 键和值 - ValueError: Must have equal len keys and value when setting with an iterable ValueError:尺寸必须相等,但输入形状为 100 和 19:[?,100], [?,100,19] - ValueError: Dimensions must be equal, but are 100 and 19 with input shapes: [?,100], [?,100,19] ValueError:创建预训练模型的集合时,模型的输出张量必须是Keras Layer的输出 - ValueError: Output tensors to a Model must be the output of a Keras `Layer` when creating ensemble of pre-trained model
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM