这是错误
ValueError: Dimensions must be equal, but are 6 and 9 for '{{node Equal}} = Equal[T=DT_FLOAT, incompatible_shape_error=true](IteratorGetNext:1, Cast_1)' with input shapes: [?,6], [?,9]
我正在尝试为一个简单的Keras网络提供一组9 x 3 numpy整数数组,其预期输出为6个类别的softmax,目标为6个类别的一个热门分类。我正在使用填充来创建一致的9,3数组(我很想摆脱它,但会产生一系列其他错误)。现在,model.fit接受输入和目标,但是在运行时遇到此错误。我相信它正在尝试将9 x 3输入数组的每一行与目标数组的每个内部元素相关联。这不是我想要建立的预期关联。我想将整个9乘3数组,并将其与6个类别之一相关联。显然,我做错了什么,但我不知道这是什么。我到处寻找类似问题的人,但找不到{{node Equal}}
部分的人。其他大多数具有相同ValueError的人在那儿有不同的部分,这使得它看起来无关紧要,包括一些Kera中直接出现的错误。
这里有一些简单的代码可以重新创建错误。
import tensorflow as tf
import numpy as np
from tensorflow import keras
model = keras.Sequential()
model.add(keras.layers.Dense(16, input_shape=(9, 3), activation='relu'))
model.add(keras.layers.Dense(32, activation='relu'))
model.add(keras.layers.Dense(32, activation='relu'))
model.add(keras.layers.Dense(16, activation='relu'))
model.add(keras.layers.Dense(6, activation='softmax'))
model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
example_array = np.array([
np.array([[ 5, 0, 1],
[ 2, 0, 1],
[ 4, 0, 1],
[-1, -1, -1],
[-1, -1, -1],
[-1, -1, -1],
[-1, -1, -1],
[-1, -1, -1],
[-1, -1, -1]]),
np.array([[ 4, 3, 0],
[ 4, 2, 2],
[-1, -1, -1],
[-1, -1, -1],
[-1, -1, -1],
[-1, -1, -1],
[-1, -1, -1],
[-1, -1, -1],
[-1, -1, -1]]),
np.array([[ 3, 0, 2],
[ 1, 1, 1],
[ 3, 2, 0],
[ 3, 0, 3],
[ 1, 0, 2],
[ 4, 1, 1],
[ 1, 1, 1],
[ 3, 1, 1],
[-1, -1, -1]])])
example_target = np.array([[1, 0, 0, 0, 0, 0,],
[0, 0, 0, 0, 1, 0,],
[0, 0, 0, 0, 0, 1,]])
model.fit(example_array, example_target, epochs=1)
尽管这似乎会产生一个错误,并且其(Cast_2,Cast_3)位与原始(IteratorGetNext:1,Cast_1)有所不同
ValueError: Dimensions must be equal, but are 6 and 9 for '{{node Equal}} = Equal[T=DT_FLOAT, incompatible_shape_error=true](Cast_2, Cast_3)' with input shapes: [?,6], [?,9].
考虑到我是从我的主代码示例运行中获取此示例的,就不会发生这种情况,但是如果您希望与之交互,这是我的主代码。
Network.py
import gym
import random
import numpy as np
import tensorflow as tf
from tensorflow import keras
from statistics import median, mean
from collections import Counter
import Mastermind
INITIAL_GAMES = 1000
#The number of avaliable colours
COLOURS = 6
GUESS_LENGTH = 4
#The number of guesses avaliable to the player
GUESSES = 10
env = Mastermind.MastermindEnv(GUESS_LENGTH, COLOURS, GUESSES)
colours = env.colours
def initial_games():
# [OBS, MOVES]
training_data = []
# all scores:
scores = []
# just the scores that met our threshold:
accepted_scores = []
# iterate through however many games we want:
for _ in range(INITIAL_GAMES):
env.reset()
score = 0
# guesses and results specifically from this environment:
game_memory = []
# Each is given the number of guesses
# long plus one to garuentee no interrupts
for t in range(GUESSES+1):
# choose random guess
guess = ""
for _ in range(GUESS_LENGTH):
guess += random.choice(colours)
#Check guess
observation, reward, done, info = env.step(guess)
score += reward
if done:
#Memory is saved after game's completion
game_memory = observation
break
# If our score is positive it means that the answer was
# correctly guessed at which point we want to save the score
# and the game memory
if 10 > score > 0:
accepted_scores.append(score)
training_data.append(game_memory)
# reset env to play again
env.reset()
# save overall scores
scores.append(score)
# just in case you wanted to reference later
training_data_save = np.array(training_data)
np.save('saved.npy',training_data_save)
#some statistics stuff
print('Average accepted score:',mean(accepted_scores))
print('total games won:', len(accepted_scores))
print(Counter(accepted_scores))
return training_data
model = keras.Sequential()
model.add(keras.layers.Dense(16, input_shape=(9, 3), activation='relu'))
model.add(keras.layers.Dense(32, activation='relu'))
model.add(keras.layers.Dense(32, activation='relu'))
model.add(keras.layers.Dense(16, activation='relu'))
model.add(keras.layers.Dense(COLOURS, activation='softmax'))
model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
def initial_train_model():
training_data = initial_games()
for index in range(GUESS_LENGTH):
training = []
targets = []
for observation in training_data:
obs = []
for i in range(len(observation)):
if i == len(observation)-1:
targets.append(ord(observation[i][0][index])-97)
else:
obs.append([ord(observation[i][0][index])-97,
ord(observation[i][1])-48,
ord(observation[i][2])-48])
i += 1
j = 10-len(observation)
while j > 0:
obs.append([-1, -1, -1])
j -= 1
training.append(np.array(obs))
print(training)
training = np.array(training)
print(keras.utils.to_categorical(targets, num_classes=COLOURS))
one_hot_targets = np.array(keras.utils.to_categorical(targets, num_classes=COLOURS))
#print(one_hot_targets)
model.fit(training, one_hot_targets, epochs=1)
initial_train_model()
和
Mastermind.py
import gym
from gym.utils import seeding
import numpy as np
import random
class MastermindEnv(gym.Env):
"""
Description:
A code guessing board game where a series of letters must be guessed
which gives small pieces of information to the player.
Observation:
Type: List of Lists
Guess Blacks Whites
String int int
Actions:
Type: Discrete(colours^guess_length)
String guess
A string of length guess_length where each character can be any colour.
Reward:
Reward is 10 on game completion with 1 additional
for each remaining guess.
Starting State:
An empty board with a target created
Episode Termination:
Remaining guesses reduced to 0
guess == target
Solved Requirements:
100% winrate over 20 games
"""
"""
metadata = {
'render.modes': ['human', 'rgb_array'],
'video.frames_per_second' : 50
}
"""
def __init__(self, guess_length=4, colours=6, guesses=10):
self.guess_length = guess_length
self.total_guesses = guesses
self.guesses = guesses
self.colours = []
for _ in range(colours):
self.colours.append(chr(_ + 97))
self.seed()
self.state = []
def seed(self, seed=None):
self.np_random, seed = seeding.np_random(seed)
return [seed]
def step(self, guess):
done = False
correct = False
self.guesses -= 1
if guess == self.target:
done = True
correct = True
blacks = 0
whites = 0
accounted = []
for i in range(len(guess)):
if guess[i] == self.target[i]:
blacks += 1
accounted.append(i)
continue
for j in range(len(self.target)):
if i != j and j not in accounted:
if guess[i] == self.target[j]:
whites += 1
accounted.append(j)
break
self.state.append([guess, blacks, whites])
if self.guesses == 0:
done = True
if not done:
reward = 0.0
else:
if correct:
reward = float(self.guesses+1)
else:
reward = 0.0
return np.array(self.state), reward, done, {}
def reset(self):
self.state = []
self.guesses = self.total_guesses
# Creating a target
target = ""
for _ in range(self.guess_length):
target += random.choice(self.colours)
#print(target)
self.target = target
return np.array(self.state)
def render(self, mode='human'):
print(self.state[-1])
def close(self):
self.state = []
self.guesses = self.total_guesses
主要来说,如果可能的话,我希望每个(9,3)数组都与目标数组的单行相关。
谢谢。
答案 0 :(得分:0)
问题可能出在模型的定义中。您的输入数据有太多尺寸(4个尺寸),无法直接拟合到Dense
图层中(输入1个尺寸,输出1个尺寸)。您应该在第一个Flatten
层之前添加一个Dense
层。在这种情况下,您不再需要Flatten
层,因为Dense
层的输出与它们的输入具有相同的尺寸。
此外,您还应将模型的input_shape
定义为input_shape=(9, 3, 3)
,因为模型是由3个大小均为9x3的数组组成的。
因此,您的示例代码应如下所示:
import tensorflow as tf
import numpy as np
from tensorflow import keras
model = keras.Sequential()
model.add(tf.keras.layers.Flatten())
model.add(keras.layers.Dense(16, input_shape=(9, 3, 3), activation='relu'))
model.add(keras.layers.Dense(32, activation='relu'))
model.add(keras.layers.Dense(32, activation='relu'))
model.add(keras.layers.Dense(16, activation='relu'))
model.add(keras.layers.Dense(6, activation='softmax'))
model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
example_array = np.array([
np.array([[ 5, 0, 1],
[ 2, 0, 1],
[ 4, 0, 1],
[-1, -1, -1],
[-1, -1, -1],
[-1, -1, -1],
[-1, -1, -1],
[-1, -1, -1],
[-1, -1, -1]]),
np.array([[ 4, 3, 0],
[ 4, 2, 2],
[-1, -1, -1],
[-1, -1, -1],
[-1, -1, -1],
[-1, -1, -1],
[-1, -1, -1],
[-1, -1, -1],
[-1, -1, -1]]),
np.array([[ 3, 0, 2],
[ 1, 1, 1],
[ 3, 2, 0],
[ 3, 0, 3],
[ 1, 0, 2],
[ 4, 1, 1],
[ 1, 1, 1],
[ 3, 1, 1],
[-1, -1, -1]])])
example_target = np.array([[1, 0, 0, 0, 0, 0,],
[0, 0, 0, 0, 1, 0,],
[0, 0, 0, 0, 0, 1,]])
model.fit(example_array, example_target, epochs=1)