Проблема с размерами входного массива в Керасе (TF) с CNN для игры в шахматы
Я хочу передать ноль-массив в CNN, который содержит 2 шахматные позиции, одну перед ходом и вторую после определенного хода. Я хочу научить CNN оценивать оценку этого хода по обычной шахматной программе. Эти оценки являются значениями int.
Формы x
а также y
являются: x: (2000000, 8, 8, 2) , y: (2000000,)
Код модели:
#define model
model = Sequential()
#model.add(Dense(1024, activation='relu', input_dim=864))
model.add(Conv2D(128, kernel_size=(3, 3), strides=(1, 1), activation='relu', input_shape=(8,8,2)))
model.add(Conv2D(128, kernel_size=(3, 3), strides=(1, 1), activation='relu'))
model.add(Dense(128, activation='relu', init='uniform'))
model.add(BatchNormalization())
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam',metrics=['mae'])
print(model.summary())
Обучение проводится с:
history = model.fit(x, y, validation_split=0.1, epochs=5, batch_size=20000, verbose=2)
Это дает мне следующую ошибку:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-7-619de3f1be1b> in <module>()
171 for i in range(5):
172 print("Fitting begins", x.shape, y.shape)
--> 173 history = model.fit(x, y, validation_split=0.1, epochs=5, batch_size=20000, verbose=2)
174 #score = model.evaluate(x, y, verbose=2)
175 #print(score)
/usr/local/lib/python3.6/site-packages/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)
950 sample_weight=sample_weight,
951 class_weight=class_weight,
--> 952 batch_size=batch_size)
953 # Prepare validation data.
954 do_validation = False
/usr/local/lib/python3.6/site-packages/keras/engine/training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size)
787 feed_output_shapes,
788 check_batch_axis=False, # Don't enforce the batch size.
--> 789 exception_prefix='target')
790
791 # Generate sample-wise weight values given the `sample_weight` and
/usr/local/lib/python3.6/site-packages/keras/engine/training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
126 ': expected ' + names[i] + ' to have ' +
127 str(len(shape)) + ' dimensions, but got array '
--> 128 'with shape ' + str(data_shape))
129 if not check_batch_axis:
130 data_shape = data_shape[1:]
ValueError: Error when checking target: expected dense_10 to have 4 dimensions, but got array with shape (2000000, 1)
Что я делаю не так? Как я могу это исправить?
Хорошо, я понял, что проблема связана с формой вывода последнего слоя:
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_13 (Conv2D) (None, 6, 6, 128) 2432
_________________________________________________________________
conv2d_14 (Conv2D) (None, 4, 4, 128) 147584
_________________________________________________________________
dense_14 (Dense) (None, 4, 4, 128) 16512
_________________________________________________________________
batch_normalization_7 (Batch (None, 4, 4, 128) 512
_________________________________________________________________
dense_15 (Dense) (None, 4, 4, 1) 129
=================================================================
Но почему это (None, 4, 4, 1)
? Не должно ли это быть (None, 1)
? Это один нейрон с 1 значением!
1 ответ
Но почему это (None, 4, 4, 1)? Разве это не должно быть (None, 1)???
Нет, не должно. Потому что плотный слой применяется на последней оси его ввода, и, следовательно, так как в этом случае он применяется на выходе Conv2D
слой, который является 4D-тензором, выход Dense
слой также будет 4D тензор. Чтобы решить эту проблему, вы можете сначала сгладить вывод Conv2D
слой с помощью Flatten
слой, а затем использовать Dense
слой, как это:
model.add(Conv2D(128, kernel_size=(3, 3), strides=(1, 1), activation='relu'))
model.add(Flatten()) # flatten the output of `Conv2D` to a 2D tensor
model.add(Dense(128, activation='relu', init='uniform'))