1

I'm using this code:

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)

And I'm getting this error:

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

I've tried looking up this solution: Keras Model giving TypeError: only size-1 arrays can be converted to Python scalars But, as you can see I have used the .shape method in my output layer and still it doesn't work. I don't see where an array is being created which needs to be a size 1 array in the line

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

because that's where the error is being triggered.

EDIT: I tried to set an integral value for 'filters' as suggested by @TavoGLC as:

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

and I added a data_format='channels_last' to overcome a negative values problem. That made this line of code run properly, but then the 2nd Convolutional layer started giving me problems.

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

Error:

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].

Again, I've tried the solutions given here: Negative dimension size caused by subtracting 3 from 1 for 'conv2d_2/convolution' Nothing just seems to work.

GFTW
  • 145
  • 1
  • 1
  • 14
  • I guess, the problem is with this line `output_node=109 # Output Layer model.add(Dense(output_node.shape, activation='softmax'))`. output_node is just an integer and not an array to apply shape. – nag Jul 01 '19 at 04:42
  • Thanks but I tried converting output_node to [109] and it doesn't work still. Same error. – GFTW Jul 01 '19 at 04:45
  • It seems to me that you should remove `.shape`. – gmds Jul 01 '19 at 05:16
  • Nope, still the same. – GFTW Jul 01 '19 at 05:28
  • Try changing `filters=11` over the first layer. From the documentation a `Conv2D` layer in keras takes an integer as argument in `filters`https://keras.io/layers/convolutional/ – TavoGLC Jul 01 '19 at 05:55
  • @TavoGLC I changed it to a tuple because I was facing an error which got fixed by doing so. Now I put filters=11 and this comes up again: `ValueError: Negative dimension size caused by subtracting 96 from 64 for 'conv2d_26/convolution' (op: 'Conv2D') with input shapes: [?,64,64,3], [96,96,64,11].` And I've tried so many things regarding this like changing the data format to channels first and all, nothing worked except making filters a tuple. – GFTW Jul 01 '19 at 06:08
  • @GFTW your image is (64x64) then how can you have a kernel of size (96X96) and that is the reason for `Negative dimension size` error. Are you sure about your kernel size and no:of filters? – mujjiga Jul 01 '19 at 08:23

1 Answers1

0

Change these:

  • filter - use a single integer (number of output filters for the convolution).
  • kernel_size - use the smaller size as the kernel has to move in the input shape(The shape could decrease for deeper layer so you have to understand the shape of the layer input to get the size)
  • other convolution layers - you have to use tuple (like Conv2D(256, (11, 11))) else it will be considered as another variable, follow the previous procedure on filter and kernel_size for all Conv2D layers.
  • for output shape use
output_node=109
# Output Layer
model.add(Dense(output_node, activation='softmax'))
Ramesh Kamath
  • 189
  • 1
  • 6