keras: ValueError: Error when checking model target: expected activation_1 to have shape (None, 60) but got array with shape (10, 100)

keras: ValueError: Error when checking model target: expected activation_1 to have shape (None, 60) but got array with shape (10, 100)

我正在尝试移植 RocAlphaGo 来玩 Game of Amazons,在尝试实施监督策略训练器时出现问题。

from keras.models import Sequential, Model
from keras.layers.core import Activation, Flatten
from keras.layers import convolutional

defaults = {
            "board": 10,
            "filters_per_layer": 128,
            "layers": 12,
            "filter_width_1": 5
}
# copy defaults, but override with anything in kwargs
params = defaults
network = Sequential()
# create first layer
network.add(convolutional.Convolution2D(
      input_shape=(6, 10, 10),
      nb_filter=128,
      nb_row=5,
      nb_col=5,
      init='uniform',
      activation='relu',
      border_mode='same'))

# create all other layers
for i in range(2, 13):
     # use filter_width_K if it is there, otherwise use 3
     filter_key = "filter_width_%d" % i
     filter_width = params.get(filter_key, 3)

     # use filters_per_layer_K if it is there, otherwise use default value
     filter_count_key = "filters_per_layer_%d" % i
     filter_nb = params.get(filter_count_key, 128)

     network.add(convolutional.Convolution2D(
         nb_filter=filter_nb,
         nb_row=filter_width,
         nb_col=filter_width,
         init='uniform',
         activation='relu',
         border_mode='same'))

# the last layer maps each <filters_per_layer> feature to a number
network.add(convolutional.Convolution2D(
    nb_filter=1,
    nb_row=1,
    nb_col=1,
    init='uniform',
    border_mode='same'))
# reshape output to be board x board
network.add(Flatten())
# softmax makes it into a probability distribution
network.add(Activation('softmax'))

给出以下异常:

ValueError: Error when checking model target: expected activation_1 to have shape (None, 60) but got array with shape (10, 100)

训练数据集是一个(10, 6, 10, 10)数组,10 x 6层,每一层是一个10x10的数组(棋盘),为什么模型需要(None, 60) ? 如果从 input_shape=(6, 10, 10)input_shape=(10, 10, 10),将得到:

ValueError: Error when checking model input: expected convolution2d_input_1 to have shape (None, 10, 10, 10) but got array with shape (10, 6, 10, 10)

全部代码为here

正如 Matias 在评论中所说,如果您添加

network.summary() 

您可能会注意到您的卷积应用于输入数据的前两个维度(即 (6,10,10))。你这里的特征是第一维的。 Keras,默认情况下,当你使用 tensorflow 时,会假设你的特征所在的维度是第三个维度,而不是第一个维度。因此,当您在 (6,10,10) 数组上应用 128 个过滤器时,输出将是 (6,10,128) 如果我理解得很好,这不是您想要的。

因此,在最后一个卷积层的输出处,您得到一个 (6,10,1) 数组,它会展平为 (,60) 而不是您预期的 (,100)。

有两种方法可以修复您的网络。要么将输入数据更改为格式 (10,10,6)。或者你使用Convolution2D()层的data_format="channels_first"参数。

这是第二个选项的代码:

from keras.models import Sequential, Model
from keras.layers.core import Activation, Flatten
from keras.layers import convolutional

defaults = {
            "board": 10,
            "filters_per_layer": 128,
            "layers": 12,
            "filter_width_1": 5
}
# copy defaults, but override with anything in kwargs
params = defaults
network = Sequential()
# create first layer
network.add(convolutional.Convolution2D(
      input_shape=(6, 10, 10),
      nb_filter=128,
      nb_row=5,
      nb_col=5,
      init='uniform',
      activation='relu',
      border_mode='same',
      data_format='channels_first'
      ))

# create all other layers
for i in range(2, 13):
     # use filter_width_K if it is there, otherwise use 3
     filter_key = "filter_width_%d" % i
     filter_width = params.get(filter_key, 3)

     # use filters_per_layer_K if it is there, otherwise use default value
     filter_count_key = "filters_per_layer_%d" % i
     filter_nb = params.get(filter_count_key, 128)

     network.add(convolutional.Convolution2D(
         nb_filter=filter_nb,
         nb_row=filter_width,
         nb_col=filter_width,
         init='uniform',
         activation='relu',
         border_mode='same',
         data_format='channels_first'))

# the last layer maps each <filters_per_layer> feature to a number
network.add(convolutional.Convolution2D(
    nb_filter=1,
    nb_row=1,
    nb_col=1,
    init='uniform',
    border_mode='same',
    data_format='channels_first'))
# reshape output to be board x board
network.add(Flatten())
# softmax makes it into a probability distribution
network.add(Activation('softmax'))
# display your network summary
network.summary()

编辑

考虑到你的keras版本,你应该使用参数"dim_ordering"并将其设置为"th"。

我在 keras documentation

中找到了此信息
from keras.models import Sequential, Model
from keras.layers.core import Activation, Flatten
from keras.layers import convolutional

defaults = {
            "board": 10,
            "filters_per_layer": 128,
            "layers": 12,
            "filter_width_1": 5
}
# copy defaults, but override with anything in kwargs
params = defaults
network = Sequential()
# create first layer
network.add(convolutional.Convolution2D(
      input_shape=(6, 10, 10),
      nb_filter=128,
      nb_row=5,
      nb_col=5,
      init='uniform',
      activation='relu',
      border_mode='same',
      dim_ordering='th'
      ))

# create all other layers
for i in range(2, 13):
     # use filter_width_K if it is there, otherwise use 3
     filter_key = "filter_width_%d" % i
     filter_width = params.get(filter_key, 3)

     # use filters_per_layer_K if it is there, otherwise use default value
     filter_count_key = "filters_per_layer_%d" % i
     filter_nb = params.get(filter_count_key, 128)

     network.add(convolutional.Convolution2D(
         nb_filter=filter_nb,
         nb_row=filter_width,
         nb_col=filter_width,
         init='uniform',
         activation='relu',
         border_mode='same',
         dim_ordering='th'))

# the last layer maps each <filters_per_layer> feature to a number
network.add(convolutional.Convolution2D(
    nb_filter=1,
    nb_row=1,
    nb_col=1,
    init='uniform',
    border_mode='same',
    dim_ordering='th'))
# reshape output to be board x board
network.add(Flatten())
# softmax makes it into a probability distribution
network.add(Activation('softmax'))
# display your network summary
network.summary()