I have a model in Keras for classification that I trained on some dataset. Call that model "classification_model". That model is saved in "classification.h5". Model for detection is the same, except that we delete last convolutional layer, and add three Conv2D layers of size (3,3). So, our model for detection "detection_model" should look like this:
detection_model = classification_model[: last_conv_index] + Conv2d + Conv2d + Conv2d.
How can we implement that in Keras?
Well, load your classification model and use Keras functional API to construct your new model:
model = load_model("classification.h5")
last_conv_layer_output = model.layers[last_conv_index].output
conv = Conv2D(...)(last_conv_layer_output)
conv = Conv2D(...)(conv)
output = Conv2D(...)(conv)
new_model = Model(model.inputs, output)
# compile the new model and save it ...
Related
I have a '.pt' file that includes alexnet model which trained on my dataset. How I can get "out_features" of classifier layers (layers 1 & 4) after running my model for different dataset.
I needs this data for inputs of SVM.
I have tried:
Model(inputs, outputs=model.classifier[1].out_features)
model.classifier[1].out_features(inputs)
model.classifier[1].parameters(torch.tensor(inputs))
but they didn't work
at first you have to load model
model = torch.load(model.pt)
after that you have to remove the last layer
features = list(model.classifier.children())[:-4] # Remove last layer
model.classifier = nn.Sequential(*features)
then you can have the weights of last layer by applying model for inputs
out = model(inputs)
I am working on CNN model using Tensorflow frames in google collab. I am unable to extract the latent vectors from the convolutional layers. I want to extract the output of the convolutional layers, the layers before fully connected layer.
I have tried with the following code
a = dropout()(classifier_model.output)
print(a)
I am unable to understand the solution suggested on the link Stackoverflow solution to print the value of tensorflow object after applying a-conv-pool-layer
Anyone with any suggestion?
You can use get_layer method of the Model class to get a layer by its name, find bellow an example with a dummy 1D CNN and a binary classifier :
timesteps = 100
nfeatures = 2
# build the model using the functional API
# example of a 1D CNN inspired by the your stack overflow link, but using a model instead of successive *raw* layers
# the values of the Conv1D filters and kernels are different
input = Input((timesteps, nfeatures))
p = Conv1D(filters=16, kernel_size=10)(input)
p = ReLU()(p)
p = MaxPool1D(pool_size=2)(p)
p = Conv1D(filters=32, kernel_size=10)(p)
p = ReLU()(p)
p = MaxPool1D(pool_size=2)(p)
p = Conv1D(filters=64, kernel_size=10)(p)
p = ReLU()(p)
p = MaxPool1D(pool_size=2, name='conv1Dfeat')(p) # give a name to the CNN output
# fully connected part
p = Flatten()(p)
p = Dense(10)(p)
# could add a dropout layer to ease optimization
finaloutput = Dense(1, activation='sigmoid')(p)
# full model
model = Model(inputs=input, outputs=finaloutput)
# compile network, i.e. define optimizer, loss and metrics
model.compile(optimizer='Adam', loss='binary_crossentropy', metrics=['accuracy'])
model.summary()
You need to train the model using the fit method with some data. Then you can get the output of the layer which name is conv1Dfeat (the last layer of the convolutive part) by defining the model:
modelCNN = Model(inputs=input, outputs=model.get_layer('conv1Dfeat').output)
modelCNN.summary()
If you want to get the output of the convolutive part, let's say based on a single numpy input array of shape (timesteps, nfeatures), you can use the predict of the Model class on batched data:
data = np.random.normal(size=(timesteps, nfeatures)) # dummy data
data_tf = tf.expand_dims(data, axis=0) # convert to TF tensor and add batch dimension at the same time
cnn_out_np = modelCNN.predict(data_tf)
cnn_out_np = np.squeeze(cnn_out_np, axis=0) # remove batch dimension
print(cnn_out_np.shape)
(4, 64)
I want to use the Segmentation_Models UNet (with ResNet34 Backbone) for uncertainty estimation, so i want to add some Dropout Layers into the upsampling part. The Model is not Sequential, so i think i have to reconnect some outputs to the new Dropout Layers and the following layer inputs to the output of Dropout.
I'm not sure, whats the right way to do this. I'm currently trying this:
# create model
model = sm.Unet('resnet34', classes=1, activation='sigmoid', encoder_weights='imagenet')
# define optimizer, loss and metrics
optim = tf.keras.optimizers.Adam(0.001)
total_loss = sm.losses.binary_focal_dice_loss # or sm.losses.categorical_focal_dice_loss
metrics = ['accuracy', sm.metrics.IOUScore(threshold=0.5), sm.metrics.FScore(threshold=0.5)]
# get input layer
updated_model_layers = model.layers[0]
# iterate over old model and add Dropout after given Convolutions
for layer in model.layers[1:]:
# take old layer and add to new Model
updated_model_layers = layer(updated_model_layers.output)
# after some convolutions, add Dropout
if layer.name in ['decoder_stage0b_conv', 'decoder_stage0a_conv', 'decoder_stage1a_conv', 'decoder_stage1b_conv', 'decoder_stage2a_conv',
'decoder_stage2b_conv', 'decoder_stage3a_conv', 'decoder_stage3b_conv', 'decoder_stage4a_conv']:
if (uncertain):
# activate dropout in predictions
next_layer = Dropout(0.1) (updated_model_layers, training=True)
else:
# add dropout layer
next_layer = Dropout(0.1) (updated_model_layers)
# add reconnected Droput Layer
updated_model_layers = next_layer
model = Model(model.layers[0], updated_model_layers)
This throws the following Error: AttributeError: 'KerasTensor' object has no attribute 'output'
But I think I'm doing something wrong. Does anybody have a Solution for this?
There is a problem with the Resnet model you are using. It is complex and has Add and Concatenate layers (residual layers, I guess), which take as input a list of tensors from several "subnetworks". In other words, the network is not linear, so you can't walk through the model with a simple loop.
Regarding your error, in the loop of your code: layer is a layer and updated_model_layers is a tensor (functional API). Therefore, updated_model_layers.output does not exist. You confuse the two a bit
I am trying to develop an auto-encoder for compressing images using Keras. I was able to train it and to compress images, but I am struggling with the decoder part of it. Specifically, given a compressed image, I don't know how to use the model to de-compress it.
This is what I have:
input_layer = keras.layers.Input(shape=(64, 64, 3))
code_layer = build_encoder(input_layer, size_of_code) # add some convolution layers and max-pooling
output_layer = build_decoder(code_layer) # add some convolution layers and up-sampling
autoencoder_model = keras.models.Model(input_layer, output_layer)
encoder_model = keras.models.Model(input_layer, code_layer)
decoder_model = ??
autoencoder_model.compile(optimizer='adam', loss='binary_crossentropy')
using the code above I can train the autoencoder_model and compress the images using the encoder_model, but I don't know how to construct the decoder_model, mainly because I don't know how to insert a new input to the middle of the model.
Like this. Instead of the code_layer, need to define an input layer and build the decoder model with that input.
latent_inputs = keras.layers.Input(shape=(size_of_code))
output_layer = build_decoder(latent_inputs) # add some convolution layers and up-sampling
decoder_model = keras.models.Model(latent_inputs, output_layer)
You can refer this complete VAE example:
https://github.com/keras-team/keras/blob/master/examples/variational_autoencoder.py
How do I finetune ResNet50 Keras to only classify images in 2 classes (cats vs. dogs) instead of all 1000 imagenet classes? I used Python and was able to classify random images with ResNet50 and keras with the 1000 ImageNet classes. Now I want to fine tune my code so that it only classifies cats vs. dogs, using the Kaggle images instead of ImageNet. How do I go about doing that?
There are several ways of applying Transfer Learning and it's trial & error what works best. However, ImageNet includes multiple types of cats and dogs in its 1000 classes, which is why I would do the following:
Add a single Dense layer to your model with 2 outputs
Set only the last layer to trainable
Retrain the network using only images of cats and dogs
This will get solid results rather quickly because you're only training one layer. Meaning, you don't have to backpropagate through the entire network. In addition, your model only has to learn a rather linear mapping from the original cats and dogs subclasses to this binary output.
from tensorflow.keras.applications.resnet_v2 import ResNet50V2
import tensorflow.keras.layers as L
from tensorflow.keras.models import Model, load_model
def make_model():
base_model = ResNet50V2(weights='imagenet', include_top=False, input_shape=(512, 512, 3))
for layer in base_model.layers:
layer.trainable = False
xc1 = L.Conv2D(64, (3,3), padding="same")(base_model.output)
xc2 = L.BatchNormalization()(xc1)
xc3 = L.ReLU()(xc2)
xmp1 = L.AveragePooling2D(pool_size=(2, 2), strides=(2, 2))(xc3)
xf1 = L.Flatten()(xmp1)
xd1 = L.Dense(512, activation='relu')(xf1)
xd2 = L.Dense(128, activation='relu')(x3)
xd3 = L.Dense(256, activation='relu')(x5)
xd4 = L.Dense(32, activation='relu')(x7)
output = L.Dense(1, activation='sigmoid')(xd4)
model = Model(base_model.input, output)
return model
model = make_model()
model.summary()
You can make a transfer learning from ResNet, transferring the trained weights from convolutional layers and fine-tuning the fully connected layers accordingly (for a binary classification). 'include_top=False' parameter helps you to do that.
Inside the function, this code freezes the initial weights
for layer in base_model.layers:
layer.trainable = False