I got this error message when declaring the input layer in Keras.
ValueError: Negative dimension size caused by subtracting 3 from 1 for
'conv2d_2/convolution' (op: 'Conv2D') with input shapes: [?,1,28,28],
[3,3,28,32].
My code is like this
model.add(Convolution2D(32, 3, 3, activation='relu', input_shape=(1,28,28)))
Sample application: https://github.com/IntellijSys/tensorflow/blob/master/Keras.ipynb
By default, Convolution2D (https://keras.io/layers/convolutional/) expects the input to be in the format (samples, rows, cols, channels), which is "channels-last". Your data seems to be in the format (samples, channels, rows, cols). You should be able to fix this using the optional keyword data_format = 'channels_first' when declaring the Convolution2D layer.
model.add(Convolution2D(32, (3, 3), activation='relu', input_shape=(1,28,28), data_format='channels_first'))
I had the same problem, however the solution provided in this thread did not help me.
In my case it was a different problem that caused this error:
Code
imageSize=32
classifier=Sequential()
classifier.add(Conv2D(64, (3, 3), input_shape = (imageSize, imageSize, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Conv2D(64, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Conv2D(64, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Conv2D(64, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Conv2D(64, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Flatten())
Error
The image size is 32 by 32. After the first convolutional layer, we reduced it to 30 by 30. (If I understood convolution correctly)
Then the pooling layer divides it, so 15 by 15.
Then another convolutional layer reduces it to 13 by 13...
I hope you can see where this is going:
In the end, my feature map is so small that my pooling layer (or convolution layer) is too big to go over it - and that causes the error
Solution
The easy solution to this error is to either make the image size bigger or use less convolutional or pooling layers.
Keras is available with following backend compatibility:
TensorFlow : By google,
Theano : Developed by LISA lab,
CNTK : By Microsoft
Whenever you see a error with [?,X,X,X], [X,Y,Z,X], its a channel issue to fix this use auto mode of Keras:
Import
from keras import backend as K
K.set_image_dim_ordering('th')
"tf" format means that the convolutional kernels will have the shape (rows, cols, input_depth, depth)
This will always work ...
You can instead preserve spatial dimensions of the volume such that the output volume size matches the input volume size, by setting the value to “same”.
use padding='same'
Use the following:
from keras import backend
backend.set_image_data_format('channels_last')
Depending on your preference, you can use 'channels_first' or 'channels_last' to set the image data format. (Source)
If this does not work and your image size is small, try reducing the architecture of your CNN, as previous posters mentioned.
Hope it helps!
# define the model as a class
class LeNet:
'''
In a sequential model, we stack layers sequentially.
So, each layer has unique input and output, and those inputs and outputs
then also come with a unique input shape and output shape.
'''
#staticmethod ## class can instantiated only once
def init(numChannels, imgRows, imgCols , numClasses, weightsPath=None):
# if we are using channel first we have update the input size
if backend.image_data_format() == "channels_first":
inputShape = (numChannels , imgRows , imgCols)
else:
inputShape = (imgRows , imgCols , numChannels)
# initilize the model
model = models.Sequential()
# Define the first set of CONV => ACTIVATION => POOL LAYERS
model.add(layers.Conv2D( filters=6,kernel_size=(5,5),strides=(1,1),
padding="valid",activation='relu',kernel_initializer='he_uniform',input_shape=inputShape))
model.add(layers.AveragePooling2D(pool_size=(2,2),strides=(2,2)))
I hope it would help :)
See code : Fashion_Mnist_Using_LeNet_CNN
Related
My main input feature is 60x256x256 numpy array that is meant to generate a 60x256x256 binary mask (also in the form of a numpy array). The binary mask functions as a label, but I do not know how to generate a 3D numpy array or tensor output from my neural network. This is my current code:
model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(32, kernel_size=(5, 5), strides=(1, 1),
activation='relu',
input_shape=(60, 256, 256)))
model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(tf.keras.layers.Conv2D(64, (5, 5), activation='relu'))
model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(1000, activation='relu'))
model.add(tf.keras.layers.Dense(256, activation='softmax'))
model.compile(
optimizer=tf.keras.optimizers.Adam(0.001),
loss=tf.keras.losses.CosineSimilarity(),
metrics=[tf.keras.metrics.CosineSimilarity()],
)
model.fit(
train,
epochs=6,
validation_data=ds_valid,
)
In short, I want the output of the last layer to match the input layer so that it can work with the CosineSimilarity loss function. Any suggestions other than this CNN-based approach will also be very helpful, as it seems CNNs are mostly used for classification.
At the most basic level you can use tf.keras.layers.Reshape. See https://www.tensorflow.org/tutorials/generative/autoencoder
So your last two layers could be:
model.add(tf.keras.layers.Dense(60*256*256))
model.add(tf.keras.layers.Reshape(60, 256, 256))
However I think what you're looking for is an autoencoder type network and to usetf.keras.layers.Conv2DTranspose layers.
The above link is an intro to Autoencoders and should be a good starting point I think.
Not sure about your use case but I think it's very likely you do want to use a convolution based approach because when you flatten the convolution you are forcing your network to forget all the information about the symmetry of the problem (i.e that it is a picture in 2D space). I don't think the fact that your problem is a regression problem affects this.
I got this error message when declaring the input layer in Keras.
ValueError: Negative dimension size caused by subtracting 3 from 1 for
'conv2d_2/convolution' (op: 'Conv2D') with input shapes: [?,1,28,28],
[3,3,28,32].
My code is like this
model.add(Convolution2D(32, 3, 3, activation='relu', input_shape=(1,28,28)))
Sample application: https://github.com/IntellijSys/tensorflow/blob/master/Keras.ipynb
By default, Convolution2D (https://keras.io/layers/convolutional/) expects the input to be in the format (samples, rows, cols, channels), which is "channels-last". Your data seems to be in the format (samples, channels, rows, cols). You should be able to fix this using the optional keyword data_format = 'channels_first' when declaring the Convolution2D layer.
model.add(Convolution2D(32, (3, 3), activation='relu', input_shape=(1,28,28), data_format='channels_first'))
I had the same problem, however the solution provided in this thread did not help me.
In my case it was a different problem that caused this error:
Code
imageSize=32
classifier=Sequential()
classifier.add(Conv2D(64, (3, 3), input_shape = (imageSize, imageSize, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Conv2D(64, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Conv2D(64, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Conv2D(64, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Conv2D(64, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Flatten())
Error
The image size is 32 by 32. After the first convolutional layer, we reduced it to 30 by 30. (If I understood convolution correctly)
Then the pooling layer divides it, so 15 by 15.
Then another convolutional layer reduces it to 13 by 13...
I hope you can see where this is going:
In the end, my feature map is so small that my pooling layer (or convolution layer) is too big to go over it - and that causes the error
Solution
The easy solution to this error is to either make the image size bigger or use less convolutional or pooling layers.
Keras is available with following backend compatibility:
TensorFlow : By google,
Theano : Developed by LISA lab,
CNTK : By Microsoft
Whenever you see a error with [?,X,X,X], [X,Y,Z,X], its a channel issue to fix this use auto mode of Keras:
Import
from keras import backend as K
K.set_image_dim_ordering('th')
"tf" format means that the convolutional kernels will have the shape (rows, cols, input_depth, depth)
This will always work ...
You can instead preserve spatial dimensions of the volume such that the output volume size matches the input volume size, by setting the value to “same”.
use padding='same'
Use the following:
from keras import backend
backend.set_image_data_format('channels_last')
Depending on your preference, you can use 'channels_first' or 'channels_last' to set the image data format. (Source)
If this does not work and your image size is small, try reducing the architecture of your CNN, as previous posters mentioned.
Hope it helps!
# define the model as a class
class LeNet:
'''
In a sequential model, we stack layers sequentially.
So, each layer has unique input and output, and those inputs and outputs
then also come with a unique input shape and output shape.
'''
#staticmethod ## class can instantiated only once
def init(numChannels, imgRows, imgCols , numClasses, weightsPath=None):
# if we are using channel first we have update the input size
if backend.image_data_format() == "channels_first":
inputShape = (numChannels , imgRows , imgCols)
else:
inputShape = (imgRows , imgCols , numChannels)
# initilize the model
model = models.Sequential()
# Define the first set of CONV => ACTIVATION => POOL LAYERS
model.add(layers.Conv2D( filters=6,kernel_size=(5,5),strides=(1,1),
padding="valid",activation='relu',kernel_initializer='he_uniform',input_shape=inputShape))
model.add(layers.AveragePooling2D(pool_size=(2,2),strides=(2,2)))
I hope it would help :)
See code : Fashion_Mnist_Using_LeNet_CNN
I have a binary classification problem. I want to detect raindrops on the image. I trained a simple model, but my prediction is not good. I want to have a prediction between 0 and 1.
For my first try, i used relu for all layers accept the final(I used softmax). As the optimizer, i used binary_crossentropy and i changed it into the categorical_crossentropy. Both of them didn't work.
opt = Adam(lr=LEARNING_RATE, decay=LEARNING_RATE / EPOCHS)
cnNetwork.compile(loss='categorical_crossentropy',
optimizer=optimizers.RMSprop(lr=lr),
metrics=['accuracy'])
inputShape = (height, width, depth)
# if we are using "channels first", update the input shape
if K.image_data_format() == "channels_first":
inputShape = (depth, height, width)
# First layer is a convolution with 20 functions and a kernel size of 5x5 (2 neighbor pixels on each side)
model.add(Conv2D(20, (5, 5), padding="same",
input_shape=inputShape))
# our activation function is ReLU (Rectifier Linear Units)
model.add(Activation("relu"))
# second layer is maxpooling 2x2 that reduces our image resolution by half
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
# Third Layer - Convolution, twice the size of the first convoltion
model.add(Conv2D(40, (5, 5), padding="same"))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
# Fifth Layer is Full connected flattened layer that makes our 3D images into 1D arrays
model.add(Flatten())
model.add(Dense(500))
model.add(Activation("relu"))
# softmax classifier
model.add(Dense(classes))
model.add(Activation("softmax"))
I expect to get for ex .1 for the first class and .9 for the second. In the result, i get 1 , 1.3987518e-35. The main problem is that i always get 1 as a prediction.
You should be using binary_crossentropy and there is nothing wrong in the output you have got. The output 1 , 1.3987518e-35 means the probability of first class is almost 1 and probability of second class is very close to 0 (1e-35).
# Importing the Keras libraries and packages
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
from keras.layers import Dropout
# Initialising the CNN
chars74k_classifier = Sequential()
# Adding the first convolutional layer
chars74k_classifier.add(Conv2D(32, (3, 3), activation = 'relu', input_shape = (64, 64, 3)))
# Adding the max pooling layer
chars74k_classifier.add(MaxPooling2D(pool_size = (2, 2)))
chars74k_classifier.add(Dropout(0.25))
# Adding the second convolutional layer
chars74k_classifier.add(Conv2D(32, (3, 3), activation='relu'))
# Adding a second max pooling layer
chars74k_classifier.add(MaxPooling2D(pool_size = (2, 2)))
# Adding the third convolutional layer
chars74k_classifier.add(Conv2D(64, (3, 3), activation='relu'))
# Adding a third max pooling layer
chars74k_classifier.add(MaxPooling2D(pool_size = (2, 2)))
chars74k_classifier.add(Dropout(0.50))
# Adding the fourth convolutional layer
chars74k_classifier.add(Conv2D(128, (3, 3), activation='relu'))
# Adding a fourth max pooling layer
chars74k_classifier.add(MaxPooling2D(pool_size = (2, 2)))
# Adding the flattening layer
chars74k_classifier.add(Flatten())
# Adding the fully connected layers (Normal ANN)
chars74k_classifier.add(Dense(activation = 'relu', units = 128))
chars74k_classifier.add(Dense(activation = 'relu', units = 128))
chars74k_classifier.add(Dense(activation = 'softmax', units = 26))
# Compiling the CNN
chars74k_classifier.compile(optimizer='Adadelta',
loss='categorical_crossentropy',
metrics=['accuracy'])
This is the code I wrote for my Keras Convolutional neural network, and in keras when training with keras 2.0.6 and tensorflow 1.1.0 it gets a great accuracy of 86% on the test set. When I export this model to an CoreML model, the input is not an image, but a multiarray? How do I fix this as the input of the network is actually a 64x64 image with colors?
In your coremltools conversion script, specify the input_image_names="input" parameter.
I'm a student in acoustics and really new at deep learning. My goal is to get a good understanding in how a CNN exactly works. There is one part that I don't understand. I can't find any precise information about that.
My model is something like this:
model = Sequential()
model.add(Conv2D(32, (3, 3), padding='same', activation='relu', input_shape = input_shape))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Conv2D(48, (3, 3), padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(ndim, activation='relu', use_bias=True, batch_size=batchSize, kernel_initializer='glorot_uniform', kernel_regularizer=None))
model.add(Dense(nclasses, activation='softmax', kernel_regularizer=l2(1e-2)))
model.compile(loss='categorical_crossentropy', optimizer=opt)
It works, that's not the problem. I know, that the input of second conv-layer consists of 32 feature maps (output of first pooling-layer).
What is every single kernels of the second conv-layer exactly convoluted with?
Thank you for your time and help!
As my knowledge, if your input image is M*N, then the output for the first Conv2D is M*N with depth 32, that is M*N*32. And (M/2)*(N/2)*32 after the first max pooling. So the input for the second Conv2D is the (M/2)*(N/2)*32 matrix (tensor). Then the second Conv2D convolution the 32 (M/2)*(N/2) 2D matrix (tensor) to (M/2)*(N/2) * 64 matrix.
To specify how the convolution behave. I used tensorflow for deep learning, the statement below will also help you understand CNN.
Input image size [M, N, 3], 3 for image deepth (RGB for example), with this size of image the first convolution should have size [3, 3, 3, 32], first two 3s for convolution window size, the third 3 for the depth, 32 for output depth as your example. Then to do a second convolution should have size [3, 3, 32, 64], the third number 32 must be the same as the first conv output depth.
For this we can see, convolution is done with multiply 3*3 windows, that is one depth to one convolution window. In your example, the second conv should have 3*3*32 parameters to conv your M*N*32 output from the first conv.
Hope this is what you want and that I have state it clearly.