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
Related
Is there a way to add nodes to a layer in an existing Keras model? if so, what is the most efficient way to do so?
Also, is it possible to do the same but with layers? i.e. add a new layer to an existing Keras model (for example, right after the input layer).
One way I know of is to use Keras functional API by iterating and cloning each layer of the model in order to create a "copy" of the original model with the desired changes, but is it the most efficient way to accomplish this task?
You can take the output of a layer in a model and build another model starting from it:
import tensorflow as tf
# One simple model
inputs = tf.keras.Input(shape=(3,))
x = tf.keras.layers.Dense(4, activation='relu')(inputs)
outputs = tf.keras.layers.Dense(5, activation='softmax')(x)
model = tf.keras.Model(inputs=inputs, outputs=outputs)
# Make a second model starting from layer in previous model
x2 = tf.keras.layers.Dense(8, activation='relu')(model.layers[1].output)
outputs2 = tf.keras.layers.Dense(7, activation='softmax')(x2)
model2 = tf.keras.Model(inputs=model.input, outputs=outputs2)
Note that in this case model and model2 share the same input layer and first dense layer objects (model.layers[0] is model2.layers[0] and model.layers[1] is model2.layers[1]).
I have a Keras LSTM multitask model that performs two tasks. One is a sequence tagging task (so I predict a label per token). The other is a global classification task over the whole sequence using a CNN that is stacked on the hidden states of the LSTM.
In my setup (don't ask why) I only need the CNN task during training, but the labels it predicts have no use on the final product. So, on Keras, one can train a LSTM model without especifiying the input sequence lenght. like this:
l_input = Input(shape=(None,), dtype="int32", name=input_name)
However, if I add the CNN stacked on the LSTM hidden states I need to set a fixed sequence length for the model.
l_input = Input(shape=(timesteps_size,), dtype="int32", name=input_name)
The problem is that once I have trained the model with a fixed timestep_size I can no longer use it to predict longer sequences.
In other frameworks this is not a problem. But in Keras, I cannot get rid of the CNN and change the expected input shape of the model once it has been trained.
Here is a simplified version of the model
l_input = Input(shape=(timesteps_size,), dtype="int32")
l_embs = Embedding(len(input.keys()), 100)(l_input)
l_blstm = Bidirectional(GRU(300, return_sequences=True))(l_embs)
# Sequential output
l_out1 = TimeDistributed(Dense(len(labels.keys()),
activation="softmax"))(l_blstm)
# Global output
conv1 = Conv1D( filters=5 , kernel_size=10 )( l_embs )
conv1 = Flatten()(MaxPooling1D(pool_size=2)( conv1 ))
conv2 = Conv1D( filters=5 , kernel_size=8 )( l_embs )
conv2 = Flatten()(MaxPooling1D(pool_size=2)( conv2 ))
conv = Concatenate()( [conv1,conv2] )
conv = Dense(50, activation="relu")(conv)
l_out2 = Dense( len(global_labels.keys()) ,activation='softmax')(conv)
model = Model(input=input, output=[l_out1, l_out2])
optimizer = Adam()
model.compile(optimizer=optimizer,
loss="categorical_crossentropy",
metrics=["accuracy"])
I would like to know if anyone here has faced this issue, and if there are any solutions to delete layers from a model after training and, more important, how to reshape input layer sizes after training.
Thanks
Variable timesteps length makes a problem not because of using convolution layers (actually the good thing about convolution layers is that they do not depend on the input size). Rather, using Flatten layers cause the problem here since they need an input with specified size. Instead, you can use Global Pooling layers. Further, I think stacking convolution and pooling layers on top of each other might give a better result instead of using two separate convolution layers and merging them (although this depends on the specific problem and dataset you are working on). So considering these two points it might be better to write your model like this:
# Global output
conv1 = Conv1D(filters=16, kernel_size=5)(l_embs)
conv1 = MaxPooling1D(pool_size=2)(conv1)
conv2 = Conv1D(filters=32, kernel_size=5)(conv1)
conv2 = MaxPooling1D(pool_size=2)(conv2)
gpool = GlobalAveragePooling1D()(conv2)
x = Dense(50, activation="relu")(gpool)
l_out2 = Dense(len(global_labels.keys()), activation='softmax')(x)
model = Model(inputs=l_input, outputs=[l_out1, l_out2])
You may need to tune the number of conv+maxpool layers, number of filters, kernel size and even add dropout or batch normalization layers.
As a side note, using TimeDistributed on a Dense layer is redundant as the Dense layer is applied on the last axis.
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 ...
I want to modify the resnet_v2.resnet_v2_50 model so that I concatenate a number to the pool5 layer.
After I import the network I can see the layers in the end_points variable.
with slim.arg_scope(resnet_v2.resnet_arg_scope()):
net, end_points = resnet_v2.resnet_v2_50(self.imageIn, num_classes = numClasses)
So I have access to the different layers
curr_conv1 = end_points['resnet_v2_50/conv1']
curr_pred = end_points['resnet_v2_50/predictions']
curr_block4 = end_points['mainQN/resnet_v2_50/block4/unit_3/bottleneck_v2']
But I don't have access to the last part of the network after the pooling layer.
curr_pool5 = end_points['resnet_v2_50/pool5']
But I can see in Tensorboard and in the code of resnet_v2_50 that there is some kind of pool5 layer. How can I get access to it, so I can modify it and concatenate a number to it?
end_points['global_pool']
is what you want. That immediately follows the global pooling layer called pool5 in the code.
https://github.com/tensorflow/models/blob/master/research/slim/nets/resnet_v2.py#L214
I want to use vgg16 pre-trained model of keras. I have notice some strange behavior when trying to change the model.
1) I have add some layers of the per-trained model. My problem is that tensorboard is showing the layers of the model that I didn't add into the sequence model. This is strange because I have also deleted the imported model. I think this have to do with the dependency between layers so I want to remove this dependencies. How can I do this?
For example in this picture there is two layers that I didn't add but they are showing in the graph
vgg16_model = keras.applications.vgg16.VGG16()
cnnModel = keras.models.Sequential()
for layer in vgg16_model.layers[0:13]:
cnnModel.add(layer)
for layer in vgg16_model.layers[14:16]:
cnnModel.add(layer)
for layer in vgg16_model.layers[17:21]:
cnnModel.add(layer)
cnnModel.add(keras.layers.Dense(2048, name="compress_1"))
cnnModel.add(keras.layers.Dense(1024, name="compress_2"))
cnnModel.add(keras.layers.Dense(512, name="compress_3"))
for layer in cnnModel.layers[0:4]:
layer.trainable = False
del vgg16_model
2) the second problem occurs when using cnnModel.pop(). In fact I have add all the layers but I do a pop to the layer I don't want before adding the next one this is the error I get.
Layer block4_conv2 has multiple inbound nodes, hence the notion of "layer output" is ill-defined. Use `get_output_at(node_index)` instead.
And this is the code I am using:
for layer in vgg16_model.layers[0:14]:
cnnModel.add(layer)
cnnModel.pop()
for layer in vgg16_model.layers[14:17]:
cnnModel.add(layer)
cnnModel.pop()
for layer in vgg16_model.layers[17:21]:
cnnModel.add(layer)
cnnModel.pop() is working the problem only occurs when trying to add the next layer.
Thank you for your help.
You can try using Model instead of Sequential, like:
vgg16_model = keras.applications.vgg16.VGG16()
drop_layers = [13, 16]
input_layer = x = vgg16_model.input
for i, layer in enumerate(vgg16_model.layers[1:], 1):
if i not in drop_layers:
x = layer(x)
x = keras.layers.Dense(2048, name="compress_1")(x)
x = keras.layers.Dense(1024, name="compress_2")(x)
x = keras.layers.Dense(512, name="compress_3")(x)
cnnModel = keras.models.Model(inputs = input_layer, outputs = x)
for layer in cnnModel.layers[0:4]:
layer.trainable = False
del vgg16_model