I'm attempting to create an ensemble of a custom CNN and pre-trained inceptionV3,MobileNetV2 and Xception for a medical image classification task using Keras with Tensorflow. The code is given below for loaded models after saved:
def load_all_models():
all_models = []
model_names = ['model1.h5', 'model2.h5', 'model3.h5']
for model_name in model_names:
filename = os.path.join('models', model_name)
model = tf.keras.models.load_model(filename)
predictsDepth = np.argmax(model.predict(X_test), axis=1)
all_models.append(model)
print('loaded:', filename)
labels = np.array(labels)
return all_models
models = load_all_models()
for i, model in enumerate(models):
for layer in model.layers:
if layer._name == "Flatten":
layer._name = "Flatten_{}".format( i )
layer.trainable = False
and after load the models I am try to build an ensemble model using voting. The code is given below for voting:
from sklearn.ensemble import RandomForestClassifier , VotingClassifier
model = VotingClassifier(estimators=[('InceptionV3_Accuracy', model1), ('MobileNetV2_Accuracy',
model2), ('Xception_Accuracy', model3)], voting='hard')
model.fit(X_train, y_train)
When fit the ensemble I get the following error:
Blockquote
Scikit does not ensemble pre-trained models. Scikit voting ensemble (and stacking ensemble) object requires un-trained models ('estimators') as the input and a final meta model ('final estimator'). Calling the .fit function then trains the 'estimators' and the 'final estimator'.
Since you are using trained models, you can refer to the below article which provides 2 coded examples of how to ensemble trained models.
For each example, the output from each the trained model is required as input for the final meta model.
https://machinelearningmastery.com/stacking-ensemble-for-deep-learning-neural-networks/
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 was wondering what is the correct way of uploading saved weights for a trained model at inference.
As an FYI, I train my model using pretrained coco weights and pretrained imagenet weights:
model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True, pretrained_backbone=True)
num_classes = 2
# get number of input features for the classifier
in_features = model.roi_heads.box_predictor.cls_score.in_features
# replace the pre-trained head with a new one
model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)
model.to(device)
I then save the model dict in a dictionary where the state is saved like:
'state_dict': model.state_dict()
Once trained, I upload the weights like:
# set up model
model_test = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True, pretrained_backbone=True)
num_classes = 2
# get number of input features for the classifier
in_features = model_test.roi_heads.box_predictor.cls_score.in_features
# replace the pre-trained head with a new one
model_test.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)
model_test.to(device)
bestmodel = get_best_model(args.best)
bestmodel = torch.load(bestmodel)
model_test.load_state_dict(bestmodel['state_dict'])
As you can see, I also upload the pretrained weights at inference (test time). However, you can see that I then upload the weights from my saved model (bestmodel).
I thought by uploading weights, that this would override the initial pretrained weights uploaded. However, when I set the test model to :
model_test = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=False, pretrained_backbone= False)
And continue to upload my best model, I get slightly worse performance (marginally).
Is there a correct way to upload these weights? And if it shouldn't matter, why do I get a difference?
I'm trying to train a neural network and I would like to know how can I retrieve the values of the label calculated by the neural network, when I call the function evaluate.
I have search in the keras documentation for a parameter which does that but I find nothing.
import tensorflow as tf
from tensorflow import keras
import numpy as np
# Create the array of data
train_data = [[1.0,2.0,3.0],[4.0,5.0,6.0]]
train_data_np = np.asarray(train_data)
train_label = [[1,2,3],[4,5,6]]
train_label_np = np.asarray(train_data)
### Build the model
model = keras.Sequential([
keras.layers.Dense(3,input_shape =(3,2)),
keras.layers.Dense(3,activation=tf.nn.sigmoid)
])
model.compile(optimizer='sgd',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
#Train the model
model.fit(train_data_np,train_label_np,epochs=10)
#test the model
restest = model.evaluate(test_data_np,test_label_np)
before evaluate your model you should predict the labels of your test set :
#predicting
predict_labels = model.predict(test_data_np)
#evaluate
restest = model.evaluate(test_label_np,predict_labels)
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)
Let suppose I have a keras model and a function train_model(data) to train it on some data.
I would like to know if it is possible to combine/merge identical architecture, identical hyperparam models that have been trained separately/independently?
python train_model( data1 ) ### one one epoch
python train_model( data2 ) ### one one epoch
...
then
load( model1 )
load( model2 )
model3 = combine( model1, model2 )
### model3 equivalent to 2 epochs of learning.
I try to understand/find a way to distribute the learning.
Have you already tried this?
from keras.models import load_model
# load models - it is just the architecture
model1 = load_model('path/to/trained/model1.h5')
model2 = load_model('path/to/trained/model2.h5')
# load trained weights
model1.load_weights('path/to/weights/from/model1.hdf5')
model2.load_weights('path/to/weights/from/model2.hdf5')
# create a model that will merge both 1 and 2
model = Sequential()
model.add(Merge([model1, model2], mode = 'concat'))
model.add(Dense(1)) # for regression, use you last Dense layer here
model.compile(#your compiling parameters)
# use your merged model
model.predict(dataset_to_be_predicted)
The idea is from here