get outputs of classifier layers from '.pt' pretrained AlexNet model - python

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)

Related

How to save an embedding layer which was created outside model?

I created a word embedding layer outside model and used it as input before fitting my model. Now I need to predict new sentences by this model, how can I save the pre-trained embedding layer and apply it to my new sentences?
Code example:
Before input to model and fitting:
embedding_sentence = tf.keras.layers.Embedding(vocab_size, model_dimension, trainable=True)
embedded_sentence = embedding_sentence(vectorized_sentence)
Model fitting:
model = tf.keras.Sequential()
model.add(tf.keras.layers.GlobalAveragePooling1D())
...
Now I need to predict new sentences, how can I apply the trained embedding to them?
The above information is insufficient to answer this question accurately but still, I will give it a try. In tensorflow, you can use a function named get_weights to get the weights of a pre-train embedding layer and save it in a numpy/hd5 file which can be used later as an embedding layer in a new architecture.
weights = embedding_sentence.get_weights()
np.save('embedding_weights.npy', weights)
# Now load the weights to the embedding layer again
new_embedding_sentence = tf.keras.layers.Embedding(vocab_size, model_dimension, trainable=True)
new_embedding_sentence.build((None,)) # required to set the weights
new_embedding_sentence.set_weights(weights)
new_sentence = "This a dummy sentence"
new_sentence_embedding = new_embedding_sentence(new_sentence )
predictions = model(new_sentence_embedding)

Extract the output of cnn

I have trained a cnn model to classify images of dog and cat
it is giving 98% accuracy
But I want to visualize the output of cnn layer i.e the features from which my cnn is predicting whether it is a dog or a cat
If there any way to visualize the output of cnn?
You can divide your model into two models:
Previous Model:
input = Input(...)
# Your Layers
output = Dense(1)
old_model = Model(inputs=[input], output)
New Model:
input = Input(...)
#Add the first layers and the CNN here
cnn_layer = Conv2D(...)
feature_extraction_model = Model(inputs=[input], outputs=cnn_layer)
input_cnn = Input(...) # The shape of your CNN output
# Add the classification layer here
output = Dense(1)
classifier_model = Model(inputs=[input_cnn], outputs=output)
Now you define the new model as a combination of: feature_extraction_model and classifier_model
new_model = Model(inputs=[input], outputs=classifier_model(input_cnn))
# Train the model
new_model.fit(x, y)
Now you can have access to the CNNlayer post training:
cnn_output = feature_extraction_model.predict(x)

PyTorch transfer learning with pre-trained ImageNet model

I want to create an image classifier using transfer learning on a model already trained on ImageNet.
How do I replace the final layer of a torchvision.models ImageNet classifier with my own custom classifier?
Get a pre-trained ImageNet model (resnet152 has the best accuracy):
from torchvision import models
# https://pytorch.org/docs/stable/torchvision/models.html
model = models.resnet152(pretrained=True)
Print out its structure so we can compare to the final state:
print(model)
Remove the last module (generally a single fully connected layer) from model:
classifier_name, old_classifier = model._modules.popitem()
Freeze the parameters of the feature detector part of the model so that they are not adjusted by back-propagation:
for param in model.parameters():
param.requires_grad = False
Create a new classifier:
classifier_input_size = old_classifier.in_features
classifier = nn.Sequential(OrderedDict([
('fc1', nn.Linear(classifier_input_size, hidden_layer_size)),
('activation', nn.SELU()),
('dropout', nn.Dropout(p=0.5)),
('fc2', nn.Linear(hidden_layer_size, output_layer_size)),
('output', nn.LogSoftmax(dim=1))
]))
The module name for our classifier needs to be the same as the one which was removed. Add our new classifier to the end of the feature detector:
model.add_module(classifier_name, classifier)
Finally, print out the structure of the new network:
print(model)

Delete last layer and insert three Conv2D layers in Keras

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 ...

How do I finetune ResNet50 Keras to only classify images in 2 classes (cats vs. dogs) instead of all 1000 imagenet classes?

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

Categories