Получение «только массивов размера 1 может быть преобразовано в скаляры Python» в модели keras - PullRequest
1 голос
/ 01 июля 2019

Я использую этот код:

import keras
from keras.models import Sequential
from keras.layers import Dense, Activation, Dropout, Flatten,\
 Conv2D, MaxPooling2D
from keras.layers.normalization import BatchNormalization
import numpy as np
np.random.seed(1000)


# (3) Create a sequential model
model = Sequential()

# 1st Convolutional Layer

model.add(Conv2D(kernel_size=96, filters=(11, 11), input_shape=(64,64,3), activation='relu', strides=(4,4), padding='valid'))
# Pooling 
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='valid'))
# Batch Normalisation before passing it to the next layer
model.add(BatchNormalization())

# 2nd Convolutional Layer
model.add(Conv2D(256, 11, 11, activation='relu', strides=(1,1), padding='valid'))

# Pooling
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='valid'))
# Batch Normalisation
model.add(BatchNormalization())

# 3rd Convolutional Layer
model.add(Conv2D(384, 3, 3, activation='relu', strides=(1,1), padding='valid'))

# Batch Normalisation
model.add(BatchNormalization())

# 4th Convolutional Layer
model.add(Conv2D(384, 3, 3, activation='relu', strides=(1,1), padding='valid'))

# Batch Normalisation
model.add(BatchNormalization())

# 5th Convolutional Layer
model.add(Conv2D(256, 3, 3, activation='relu', strides=(1,1), padding='valid'))

# Pooling
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='valid'))
# Batch Normalisation
model.add(BatchNormalization())

# Passing it to a dense layer
model.add(Flatten())
# 1st Dense Layer
model.add(Dense(4096, input_shape=(224*224*3,)))
model.add(Activation('relu'))
# Add Dropout to prevent overfitting
model.add(Dropout(0.4))
# Batch Normalisation
model.add(BatchNormalization())

# 2nd Dense Layer
model.add(Dense(4096))
model.add(Activation('relu'))
# Add Dropout
model.add(Dropout(0.4))
# Batch Normalisation
model.add(BatchNormalization())

# 3rd Dense Layer
model.add(Dense(1000))
model.add(Activation('relu'))
# Add Dropout
model.add(Dropout(0.4))
# Batch Normalisation
model.add(BatchNormalization())

output_node=109
# Output Layer
model.add(Dense(output_node.shape, activation='softmax'))


model.summary()

# (4) Compile 
model.compile(loss='categorical_crossentropy', optimizer='adam',\
 metrics=['accuracy'])

#Fitting dataset

from keras.preprocessing.image import ImageDataGenerator

train_datagen = ImageDataGenerator(rescale = 1./255,
                                   shear_range = 0.2,
                                   zoom_range = 0.2,
                                   horizontal_flip = True)

test_datagen = ImageDataGenerator(rescale = 1./255)

training_set = train_datagen.flow_from_directory('dataset/training_set',
                                                 target_size = (64, 64),
                                                 batch_size = 32,
                                                 class_mode = 'categorical')

test_set = test_datagen.flow_from_directory('dataset/test_set',
                                            target_size = (64, 64),
                                            batch_size = 32,
                                            class_mode = 'categorical')
#steps_per_epoch = number of images in training set / batch size (which is 55839/32)
#validation_steps = number of images in test set / batch size (which is 18739/32)

classifier.fit_generator(
        training_set,
        steps_per_epoch=55839/32,
        epochs=5,
        validation_data=test_set,
        validation_steps=18739/32)

И я получаю эту ошибку:

TypeError: only size-1 arrays can be converted to Python scalars

Я пытался найти это решение: Модель Keras, предоставляющая TypeError: только массивы размера 1 могут быть преобразованы в скаляры Python Но, как вы можете видеть, я использовал метод .shape в своем выходном слое, и все же он не работает. Я не вижу, где создается массив, который должен быть массивом размера 1 в строке

model.add(Conv2D(kernel_size=96, filters=(11, 11), input_shape=(64,64,3), activation='relu', strides=(4,4), padding='valid'))

потому что именно здесь возникает ошибка.

РЕДАКТИРОВАТЬ: я пытался установить интегральное значение для «фильтров», как предложено @TavoGLC, как:

model.add(Conv2D(filters=11, kernel_size=96, input_shape=(224,224,3), activation='relu', strides=(4,4), padding='valid', data_format='channels_last'))

и я добавил data_format = 'channel_last', чтобы преодолеть проблему отрицательных значений. Это заставило эту строку кода работать правильно, но затем 2-й сверточный слой начал вызывать у меня проблемы.

# 2nd Convolutional Layer
model.add(Conv2D(filters=11, kernel_size=256, strides=(1,1), padding='valid', activation='relu'))

Ошибка:

ValueError: Negative dimension size caused by subtracting 256 from 16 for 'conv2d_77/convolution' (op: 'Conv2D') with input shapes: [?,33,16,5], [256,256,33,11].

Опять же, я попробовал решения, приведенные здесь: Отрицательный размер, вызванный вычитанием 3 из 1 для 'conv2d_2 / convolution' Кажется, ничего не работает.

1 Ответ

0 голосов
/ 01 июля 2019

Измените их:

  • filter - используйте одно целое число (количество выходных фильтров для свертки).
  • kernel_size - используйте меньший размер, поскольку ядро ​​должно перемещаться во входной форме (форма может уменьшиться для более глубокого слоя, поэтому вы должны понимать форму входного слоя, чтобы получить размер)
  • другая сверткаслои - вы должны использовать кортеж (например, Conv2D(256, (11, 11))), иначе он будет рассматриваться как другая переменная, следуйте предыдущей процедуре для фильтра и kernel_size для всех слоев Conv2D .
  • для выходной формы используйте
output_node=109
# Output Layer
model.add(Dense(output_node, activation='softmax'))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...