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.
Related
I'm trying to obtain output of an intermediate layer in Keras, Following is my code:
XX = model.input # Keras Sequential() model object
YY = model.layers[0].output
F = K.function([XX], [YY]) # K refers to keras.backend
Xaug = X_train[:9]
Xresult = F([Xaug.astype('float32')])
Running this, I got an Error :
InvalidArgumentError (see above for traceback): You must feed a value for placeholder tensor 'dropout_1/keras_learning_phase' with dtype bool
i came to know that because I'm using dropout layer in my model, I have to specify a learning_phase() flag to my function as per keras documentation.
I changed my code to the following:
XX = model.input
YY = model.layers[0].output
F = K.function([XX, K.learning_phase()], [YY])
Xaug = X_train[:9]
Xresult = F([Xaug.astype('float32'), 0])
Now I'm getting a new Error that I'm unable to figure out:
TypeError: Cannot interpret feed_dict key as Tensor: Can not convert a int into a Tensor.
Any help would be appreciated.
PS : I'm new to TensorFlow and Keras.
Edit 1 :
Following is the complete code that I'm using. I'm using Spatial Transformer Network as discussed in this NIPS paper and it's Kera's implementation here
input_shape = X_train.shape[1:]
# initial weights
b = np.zeros((2, 3), dtype='float32')
b[0, 0] = 1
b[1, 1] = 1
W = np.zeros((100, 6), dtype='float32')
weights = [W, b.flatten()]
locnet = Sequential()
locnet.add(Convolution2D(64, (3, 3), input_shape=input_shape, padding='same'))
locnet.add(Activation('relu'))
locnet.add(Convolution2D(64, (3, 3), padding='same'))
locnet.add(Activation('relu'))
locnet.add(MaxPooling2D(pool_size=(2, 2)))
locnet.add(Convolution2D(128, (3, 3), padding='same'))
locnet.add(Activation('relu'))
locnet.add(Convolution2D(128, (3, 3), padding='same'))
locnet.add(Activation('relu'))
locnet.add(MaxPooling2D(pool_size=(2, 2)))
locnet.add(Convolution2D(256, (3, 3), padding='same'))
locnet.add(Activation('relu'))
locnet.add(Convolution2D(256, (3, 3), padding='same'))
locnet.add(Activation('relu'))
locnet.add(MaxPooling2D(pool_size=(2, 2)))
locnet.add(Dropout(0.5))
locnet.add(Flatten())
locnet.add(Dense(100))
locnet.add(Activation('relu'))
locnet.add(Dense(6, weights=weights))
model = Sequential()
model.add(SpatialTransformer(localization_net=locnet,
output_size=(128, 128), input_shape=input_shape))
model.add(Convolution2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Convolution2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(128, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Convolution2D(128, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(256, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Convolution2D(256, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(256, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Convolution2D(256, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(256))
model.add(Activation('relu'))
model.add(Dense(num_classes))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
#==============================================================================
# Start Training
#==============================================================================
#define training results logger callback
csv_logger = keras.callbacks.CSVLogger(training_logs_path+'.csv')
model.fit(X_train, y_train,
batch_size=batch_size,
epochs=20,
validation_data=(X_valid, y_valid),
shuffle=True,
callbacks=[SaveModelCallback(), csv_logger])
#==============================================================================
# Visualize what Transformer layer has learned
#==============================================================================
XX = model.input
YY = model.layers[0].output
F = K.function([XX, K.learning_phase()], [YY])
Xaug = X_train[:9]
Xresult = F([Xaug.astype('float32'), 0])
# input
for i in range(9):
plt.subplot(3, 3, i+1)
plt.imshow(np.squeeze(Xaug[i]))
plt.axis('off')
for i in range(9):
plt.subplot(3, 3, i + 1)
plt.imshow(np.squeeze(Xresult[0][i]))
plt.axis('off')
The easiest way is to create a new model in Keras, without calling the backend. You'll need the functional model API for this:
from keras.models import Model
XX = model.input
YY = model.layers[0].output
new_model = Model(XX, YY)
Xaug = X_train[:9]
Xresult = new_model.predict(Xaug)
You could try:
model1 = tf.keras.models.Sequential(base_model.layers[:1])
model2 = tf.keras.models.Sequential(base_model.layers[1:])
Xaug = X_train[:9]
out = model1(Xaug)
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.
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'm trying to train a 3D CNN model in Keras, but i'm getting this error when I execute the cell:
ValueError: Input 0 of layer conv3d_8 is incompatible with the layer: : expected min_ndim=5, found ndim=4. Full shape received: [None, 4, 150, 150]
My input data is a numpy array with image data. Here are the shapes (I know that 53 is too few, but it's just for studying purposes):
Training data shape: (53, 4, 150, 150)
Training labels shape: (53, 1)
Validation data shape: (14, 4, 150, 150)
Validation labels shape: (14, 1)
The model I'm trying to use is:
# Create the model
model = Sequential()
model.add(Conv3D(32, kernel_size=(3, 3, 3), activation='relu', kernel_initializer='he_uniform', input_shape=(4,150,150)))
model.add(MaxPooling3D(pool_size=(2, 2, 2)))
model.add(BatchNormalization(center=True, scale=True))
model.add(Dropout(0.5))
model.add(Conv3D(64, kernel_size=(3, 3, 3), activation='relu', kernel_initializer='he_uniform'))
model.add(MaxPooling3D(pool_size=(2, 2, 2)))
model.add(BatchNormalization(center=True, scale=True))
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(256, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(256, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(4, activation='softmax'))
# Compile the model
model.compile(loss='categorical_crossentropy',
optimizer=keras.optimizers.Adam(lr=0.001),
metrics=['accuracy'])
model.summary()
# Fit data to model
history = model.fit(treino3d, treino3d_labels,
epochs=40)
Can someone help, please?
Thanks a lot!
It doesn't seem like you need Conv3D layers for this task. Use Conv2D instead, and use only 1 or 2 values in kernel_size and pool_size.
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu',
kernel_initializer='he_uniform',
input_shape=(4,150,150)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(BatchNormalization(center=True, scale=True))
model.add(Dropout(0.5))
model.add(Conv2D(64, kernel_size=(3, 3), activation='relu',
kernel_initializer='he_uniform'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(BatchNormalization(center=True, scale=True))
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(256, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(256, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(4, activation='softmax'))
Your channel dimension comes first so you will need to tell Keras. Use this line:
tf.keras.backend.set_image_data_format('channels_first')
Or set this parameter in every Conv2D or MaxPooling2D layer:
data_format='channels_first'
Or permute the dimensions of the input tensor to have shape (54, 150, 150, 4):
np.transpose(x, (0, 2, 3, 1))
Full functioning, corrected example:
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
from tensorflow.keras.layers import *
import numpy as np
from tensorflow.keras.models import Sequential
xtrain = np.random.rand(53, 4, 150, 150)
ytrain = np.random.randint(0, 4, (53, 1))
xtrain = np.transpose(xtrain, (0, 2, 3, 1))
model = Sequential()
model.add(Conv2D(8, kernel_size=(3, 3), activation='relu',
kernel_initializer='he_uniform', input_shape=xtrain.shape[1:]))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(BatchNormalization(center=True, scale=True))
model.add(Dropout(0.5))
model.add(Conv2D(8, kernel_size=(3, 3), activation='relu',
kernel_initializer='he_uniform'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(BatchNormalization(center=True, scale=True))
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(32, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(32, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(4, activation='softmax'))
model.compile(loss='sparse_categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
model.summary()
history = model.fit(xtrain, ytrain, epochs=1)
32/53 [=================>............] - ETA: 2s - loss: 1.8215 - acc: 0.2812
53/53 [==============================] - 5s 91ms/sample - loss: 1.9651 - acc: 0.2264
The first answer is correct. As I can recall (I didn't work with MRI for a couple of years), each slice is represented by 4 channels and each voxel in channel contains an information about the same physical position. Therefore, it would be correct approach to apply 2D-convolution for the image of 4 channels.
For 2D convolution I would recommend to define your input with input_shape=(150,150,4), or even as input_shape=(None, None, 4) - it is more generic. So you don't need to play with channel_first or channel_last configuration. channel_last is default format, as I remember
If you insist to use Conv3d, your input shape should be: input_shape=(150,150,4,1) or (None, None, None, 1)
and trainset should follow shape like: np.random.rand(53, 150, 150, 4, 1)
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.