Hello I have created a MobileNetV2 model i want to add layers onto it.
However, i kept getting this error:
"One of the dimensions in the output is <= 0 due to downsampling in conv2d_22. Consider increasing the input size. Received input shape [None, 3, 3, 1280] which would produce output shape with a zero or negative value in a dimension."
this is my code so far:
base_model = tf.keras.applications.MobileNetV2(input_shape=(96,96,3),
include_top=False,
weights='imagenet')
model = tf.keras.Sequential()
model.add(base_model)
model.add(layers.Conv2D(60, kernel_size=(5, 5), strides=(1, 1),
activation='relu',
input_shape=(96,96,3))) #error was highlighted on this line
model.add(layers.MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(layers.Conv2D(64, kernel_size=(5, 5), strides=(1, 1), activation='relu'))
model.add(layers.MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(layers.Flatten())
model.add(layers.Dense(500, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))
i have tried changing the channel first and last ((96,96,3) and (3,96,96)) on the line that has problem and both produced the same error error.
Appreciate anyone who can help with this thanks.
You cannot downsample a tensor (None, 3, 3, 1280) with a kernel size of (5, 5). Think about what a 2D convolutional layer is actually doing. You could try first flattening the output of the base model and then reshaping the output with the dense and reshape layers:
import tensorflow as tf
base_model = tf.keras.applications.MobileNetV2(input_shape=(96,96,3),
include_top=False,
weights='imagenet')
model = tf.keras.Sequential()
model.add(base_model)
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(64 * 64 * 3)) # just an example --> choose what you want
model.add(tf.keras.layers.Reshape((64, 64, 3)))
model.add(tf.keras.layers.Conv2D(60, kernel_size=(5, 5), strides=(1, 1),
activation='relu',
input_shape=(96,96,3))) #error was highlighted on this line
model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(tf.keras.layers.Conv2D(64, kernel_size=(5, 5), strides=(1, 1), activation='relu'))
model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(500, activation='relu'))
model.add(tf.keras.layers.Dense(10, activation='softmax'))
You also use an Upsampling layer to get the dimensions you want, but that is up to you.
Related
Consider the following model
def create_model():
x_1=tf.Variable(24)
bias_initializer = tf.keras.initializers.HeNormal()
model = Sequential()
model.add(Conv2D(64, (5, 5), input_shape=(28,28,1),activation="relu", name='conv2d_1', use_bias=True,bias_initializer=bias_initializer))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (5, 5), activation="relu",name='conv2d_2', use_bias=True,bias_initializer=bias_initializer))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(120, name='dense_1',activation="relu", use_bias=True,bias_initializer=bias_initializer),)
model.add(Dense(10, name='dense_2', activation="softmax", use_bias=True,bias_initializer=bias_initializer),)
Is there any way I can get the shape/size/dimensions of the all the layer(s) of a model ?
For example in the above model, 'conv2d_1' has shape of (64,1,5,5) while 'conv2d_2' has shape of (32,64,5,5)?
You can use model.summary(). Or you can loop through all layers and print the output shape:
for layer in model.layers:
print(f'{layer.name} {layer.output_shape}')
I have pretrained weights as np.array of shape (3, 3, 3, 64). I want to initialize this Tensorflow CNN with those weights using set_weights() like I show below.
However, when I try that, the following error pops up: ValueError: You called set_weights(weights) on layer "conv2d_3" with a weight list of length 3, but the layer was expecting 2 weights. Provided weights: [[[[-0.15836713 -0.178757 0.16782044 ...
model = models.Sequential()
model.add(layers.Conv2D(64, (3, 3), activation='relu', input_shape=(224, 224, 3)))
model.layers[0].set_weights(weights)
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(256, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(256, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(512, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(512, (3, 3), activation='relu'))
model.add(layers.GlobalAveragePooling2D())
model.add(layers.Dense(4, activation='softmax'))
print(model.summary())
adam = optimizers.Adam(learning_rate=0.0001, amsgrad=False)
model.compile(loss='categorical_crossentropy',
optimizer=adam,
metrics=['accuracy'])
history = model.fit_generator(
train_generator,
steps_per_epoch=np.ceil(nb_train_samples/batch_size),
epochs=epochs,
validation_data=validation_generator,
validation_steps=np.ceil(nb_validation_samples / batch_size),
class_weight=class_weight
)
My question is: how do I pass those (3, 3, 3, 64) shaped weights to initialize that CNN? I have already checked the weight shapes required for each layer and the shapes I am trying to pass and the required shape match.
You could just use kernel_initializer and bias_initializer arguments like this:
import numpy as np
# init_kernel and init_bias are initialization weights that you have
init_kernel = np.random.normal(0, 1, (3, 3, 3, 64))
init_bias = np.zeros((64,))
kernel_initializer = tf.keras.initializers.constant(init_kernel)
bias_initializer = tf.keras.initializers.constant(init_bias)
conv_layer = tf.keras.layers.Conv2D(64, (3, 3),
activation='relu',
input_shape=(224, 224, 3),
kernel_initializer=kernel_initializer,
bias_initializer=bias_initializer)
Note the kernel's and bias' shapes that I've chosen. The values with which you initialise your layer must have the exact same shapes.
I have train & test image data for which Shapes are given below.
X_test.shape , y_test.shape , X_train.shape , y_train.shape
((277, 128, 128, 3), (277, 1), (1157, 128, 128, 3), (1157, 1))
I am training a model
def baseline_model():
filters = 100
model = Sequential()
model.add(Conv2D(filters, (3, 3), input_shape=(128, 128, 3), padding='same', activation='relu'))
#model.add(Dropout(0.2))
model.add(BatchNormalization())
model.add(Conv2D(filters, (3, 3), activation='relu', padding='same'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2)))
#model.add(Flatten())
model.add(Conv2D(filters, (3, 3), activation='relu', padding='same'))
model.add(BatchNormalization())
model.add(Conv2D(filters, (3, 3), activation='relu', padding='same'))
model.add(Activation('linear'))
model.add(BatchNormalization())
model.add(Dense(512, activation='relu'))
model.add(Dense(num_classes, activation='softmax'))
# Compile model
lrate = 0.01
epochs = 10
decay = lrate/epochs
sgd = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False)
model.compile(loss='sparse_categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
print(model.summary())
return model
But I am getting an error Given below
Error when checking target: expected dense_35 to have 4 dimensions,
but got array with shape (1157, 1)
Please tell me what mistake I am making and how to fix this. I have attached snapshot of model summary
One thing you have probably forgotten to do is adding a Flatten layer right before the first Dense layer:
model.add(BatchNormalization())
model.add(Flatten()) # flatten the output of previous layer before feeding it to Dense layer
model.add(Dense(512, activation='relu'))
You need it because Dense layer does not flatten its input; rather, it is applied on the last dimension.
Although dense_35 needs to feed with 4 dimension data, according to the error, the network feed with 2 dimension data which is the label vector.
I'm using this code to train a DCGAN model to generate images. DCGAN
I want to be able to output (predict) images at a greater resolution than the model was trained at, and I'm told this is possible if convolution is used. In the following code, which describes the generator model, if I change the stride on the Conv2DTranspose layers I can increase the output shape (therefore image resolution). How can I set the stride to a different value during training than prediction? Or is there a different way to do what I want?
# Creates the generator model. This model has an input of random noise and
# generates an image that will try mislead the discriminator.
def construct_generator():
generator = Sequential()
generator.add(Dense(units=4 * 4 * 512,
kernel_initializer='glorot_uniform',
input_shape=(1, 1, 100)))
generator.add(Reshape(target_shape=(4, 4, 512)))
generator.add(BatchNormalization(momentum=0.5))
generator.add(Activation('relu'))
generator.add(Conv2DTranspose(filters=256, kernel_size=(5, 5),
strides=(2, 2), padding='same',
data_format='channels_last',
kernel_initializer='glorot_uniform'))
generator.add(BatchNormalization(momentum=0.5))
generator.add(Activation('relu'))
generator.add(Conv2DTranspose(filters=128, kernel_size=(5, 5),
strides=(2, 2), padding='same',
data_format='channels_last',
kernel_initializer='glorot_uniform'))
generator.add(BatchNormalization(momentum=0.5))
generator.add(Activation('relu'))
generator.add(Conv2DTranspose(filters=64, kernel_size=(5, 5),
strides=(2, 2), padding='same',
data_format='channels_last',
kernel_initializer='glorot_uniform'))
generator.add(BatchNormalization(momentum=0.5))
generator.add(Activation('relu'))
generator.add(Conv2DTranspose(filters=3, kernel_size=(5, 5),
strides=(2, 2), padding='same',
data_format='channels_last',
kernel_initializer='glorot_uniform'))
generator.add(Activation('tanh'))
optimizer = Adam(lr=0.00015, beta_1=0.5)
generator.compile(loss='binary_crossentropy',
optimizer=optimizer,
metrics=None)
return generator
I have a simple convolutional autoencoder in keras. My original inputs are flat arrays from a csv, so I want to reshape them from (196,) to (14,14,1). Following the keras docs, I did:
autoencoder = Sequential()
# first, reshape our (csv) inputs from (196,) to (14,14,1)
autoencoder.add(Reshape((14,14,1), input_shape=(196,)))
# encoding stage
autoencoder.add(Conv2D(16, (3,3), activation='relu', padding='same'))
autoencoder.add(MaxPooling2D((2, 2), padding='same'))
autoencoder.add(Conv2D(8, (3, 3), activation='relu', padding='same'))
autoencoder.add(MaxPooling2D((2, 2), padding='same'))
autoencoder.add(Conv2D(8, (3, 3), activation='relu', padding='same'))
autoencoder.add(MaxPooling2D((2, 2), padding='same'))
# decoding stage
autoencoder.add(Conv2D(8, (3, 3), activation='relu', padding='same'))
autoencoder.add(UpSampling2D((2, 2)))
autoencoder.add(Conv2D(8, (3, 3), activation='relu', padding='same'))
autoencoder.add(UpSampling2D((2, 2)))
autoencoder.add(Conv2D(16, (2, 2), activation='relu'))
autoencoder.add(UpSampling2D((2, 2)))
autoencoder.add(Conv2D(1, (3, 3), activation='sigmoid', padding='same'))
optimizer = optimizers.Adagrad(lr=0.01, epsilon=None, decay=0.001)
autoencoder.compile(optimizer=optimizer, loss='binary_crossentropy')
But I get the error: ValueError: Error when checking target: expected conv2d_35 to have 4 dimensions, but got array with shape (2870, 196)
So it seems to be ignoring the Reshape entirely. Am I making some obvious mistake?
The problem is not the input but the target so the y values you give are not reshaped. The final output of your network is a 4D tensor where you give instead (2870, 196).
Double check the your target array (y values) that you pass onto fit function.