I am starting to use caffe for deep learning. I have the .caffemodel file with my trained weights and a particular neural network. I am using python interface.
I've seen that I can load my network and my weights by doing this:
solver=caffe.get_solver('prototxtfile.prototxt')
solver.net.copy_from('weights.caffemodel')
But I do not want to fine-tuned my application. I just want to use those weights. I want to execute the network and for each image from the Imagenet data set I want to obtain the result of the classification (not the accuracy of an entire batch). How can I do that?
Thank you very much.
Try to understand the attached lines of python code and adjust them to your needs. It's not my code but I wrote a similar piece to test my models.
The source is:
https://www.cc.gatech.edu/~zk15/deep_learning/classify_test.py
If you don't want to fine-tune a pre-trained model, it's obvious that you don't need a solver. The solver is what optimizes the model. If you want to predict the class probability for an image, you actually just have to do a forward pass. Keep in mind that your deploy.prototxt must have a proper last layer which uses either a softmax or sigmoid function (depending on the architecture). You can't use the loss function from the train_val.prototxt for this.
import numpy as np
import matplotlib.pyplot as plt
# Make sure that caffe is on the python path:
caffe_root = '../' # this file is expected to be in {caffe_root}/examples
import sys
sys.path.insert(0, caffe_root + 'python')
import caffe
# Set the right path to your model definition file, pretrained model weights,
# and the image you would like to classify.
MODEL_FILE = '../models/bvlc_reference_caffenet/deploy.prototxt'
PRETRAINED = '../models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel'
IMAGE_FILE = 'images/cat.jpg'
caffe.set_mode_cpu()
net = caffe.Classifier(MODEL_FILE, PRETRAINED,
mean=np.load(caffe_root + 'python/caffe/imagenet/ilsvrc_2012_mean.npy').mean(1).mean(1),
channel_swap=(2,1,0),
raw_scale=255,
image_dims=(256, 256))
input_image = caffe.io.load_image(IMAGE_FILE)
plt.imshow(input_image)
prediction = net.predict([input_image]) # predict takes any number of images, and formats them for the Caffe net automatically
print 'prediction shape:', prediction[0].shape
plt.plot(prediction[0])
print 'predicted class:', prediction[0].argmax()
plt.show()
This is the code I use when I need to forward an image through my network:
import caffe
caffe.set_mode_cpu() #If you are using CPU
#caffe.set_mode_gpu() #or if you are using GPU
model_def = "path/to/deploy.prototxt" #architecture
model_weights = "path/to/weights.caffemodel" #weights
net = caffe.Net(model_def, # defines the structure of the model
model_weights,
caffe.TEST) # use test mode (e.g., don't perform dropout)
#Let's forward a single image (let's say inputImg)
#'data' is the name of my input blob
net.blobs["data"].data[0] = inputImg
out = net.forward()
# to get the final softmax probability
# in my case, 'prob' is the name of our last blob
# a softmax layer that will output the score/probability for our problem
outputScore = net.blobs["prob"].data[0] #[0] here because we forwarded a single image
In this example, the inputImg dimensions must match the dimensions of the images used during training, as well as all preprocessing done.
Related
I'm using Tensorflow Lite to train an image classifier. I now have a bunch of *.tflite models stored, and I'm trying to write some code that allows me to pick a tflite model file, pick a dataset, and test that model on that dataset (inference).
When I train a model using:
model = image_classifier.create(trainData, validation_data=valData, shuffle=True, use_augmentation=False)
I am able to easily test this model on a test dataset right away because the model is actually stored in the variable 'model', by using:
model.evaluate_tflite('model.tflite', test_data)
or
loss, accuracy = model.evaluate(test_data)
However, if I simply want to load an already existing *.tflite model, without having trained it in the same run, I can't figure out a simple way to do that.
Following these instructions, it seems to be a lot of steps for what I'm trying to do. In other Machine Learning libraries (like PyTorch), you are able to define the model and then quickly load the saved weights and then get to testing, like:
model = models.densenet201(progress=True, pretrained=pretrained)
model.load_state_dict(torch.load("models/model.pt"))
Is there a simple way for me to initialise the model into the 'model' variable, load the saved weights from a *.tflite file, and then run inference?
Thank you for your help
A simple example of image classification:
import tensorflow as tf
import numpy as np
import cv2
class TFLiteModel:
def __init__(self, model_path: str):
self.interpreter = tf.lite.Interpreter(model_path)
self.interpreter.allocate_tensors()
self.input_details = self.interpreter.get_input_details()
self.output_details = self.interpreter.get_output_details()
def predict(self, *data_args):
assert len(data_args) == len(self.input_details)
for data, details in zip(data_args, self.input_details):
self.interpreter.set_tensor(details["index"], data)
self.interpreter.invoke()
return self.interpreter.get_tensor(self.output_details[0]["index"])
model = TFLiteModel("mobilenet_v2_1.0_224_1_default_1.tflite")
image = cv2.imread("hand_blower.png")
image = cv2.resize(image, (224, 224))
image = image.astype(np.float32)[np.newaxis]
image = (image - 127.5) / 127.5
label = model.predict(image)[0].argmax()
print(label)
Please refer to the official documentation for detailed information:
https://www.tensorflow.org/api_docs/python/tf/lite/Interpreter
The model was loaded from:
https://tfhub.dev/tensorflow/lite-model/mobilenet_v2_1.0_224/1/default/1
I have trained a fastai model using Kaggle notebook, it has saved the model but how to load the model is the problem, i have tried different methods like the method given below. Even it does load the model it doesn't have any predict function only thing I can see is model.eval().
The second problem is when the model was trained on google collab it didn't even get the single image, I did try to convert the image to NumPy way and another way but both didn't work out.
I am attaching the kaggle link of model training, the saved model and the test images in last after this code
#Code for Loading model
from fastai import *
from fastai.vision import *
import torch
loc = torch.load('/content/gdrive/MyDrive/Data Exports/35k data/stage-1.pth')
body = create_body(models.resnet18, True, None)
data_classes = 4
nf = callbacks.hooks.num_features_model(body) * 2
head = create_head(nf, data_classes, None, ps=0.5, bn_final=False)
model = nn.Sequential(body, head)
Kaggle Model
Test Images From Kaggle Dataset
Saved Model
How to load pytorch models:
loc = torch.load('/content/gdrive/MyDrive/Data Exports/35k data/stage-1.pth')
model = ... # build your model
model.load_state_dict(loc)
model.eval()
Now you should be able to simply use the forward pass to generate your predictions:
input = ... # your input image
pred = model(input) # your class predictions
Don't forget to convert your inputs to torch tensors first, you might want to use a DataLoader for ease of use.
I am using python 3.6.10 and tensorflow 1.5 on a cpu. I have trained a cnn and saved it as a .onnx file. I am now trying to make a binary classification of my images using the code below:
import onnx
import warnings
from onnx_tf.backend import prepare
import numpy as np
from numpy import array
from IPython.display import display
from PIL import Image
warnings.filterwarnings('ignore')
onnx_model = onnx.load("trainednet.onnx") # load onnx model
tf_rep = prepare(onnx_model) # Import the ONNX model to Tensorflow
img = Image.open('Im025.jpg').resize((224, 224))
img = array(img).reshape(1,3, 224,224)
classification = tf_rep.run(img)
print(classification)
The print(classification) gives me an output like this:
Outputs(fc1000_softmax=array([[9.9967182e-01, 3.2823894e-04]], dtype=float32))
What does this output mean and how can I use it to understand what tensorflow classified my image as?
Well, what you have is the array of the output of the softmax layer of your model. This output can be interpreted as a probability assigned to each class ( in your case 2). You can also see it as "how confident the model is for each class".
So to have the final classification you need to take the max value of this array and map it to your label map { 0 -> class_one, 1-> class_two}.
Yes exactly, so after you model is not perfect (ie the model doesn't have 100% of accuracy). You should test on more images of class two and you will see the second number will be higher .
You should run it on a test set or refer to the metrics of the trained model.
I am using Chainer's pertained model vgg (here named net). Every time I run the following code, I get a different result:
img = Image.open("/Users/macintosh/Desktop/Code/Ger.jpg")
img = Variable(vgg.prepare(img))
img = img.reshape((1,) + img.shape)
print(net(img,layers=['prob'])['prob'])
I have checked vgg.prepare() several times but its output is the same, and there is no random initialization here (net is a pre-trained vgg network). So why is this happening?
As you can see VGG implementation, it has dropout function. I think this causes the randomness.
When you want to forward the computation in evaluation mode (instead of training mode), you can set chainer config 'train' to False as follows:
with chainer.no_backprop_mode(), chainer.using_config('train', False):
result = net(img,layers=['prob'])['prob']
when train flag is False, dropout is not executed (and some other function behaviors also change, e.g., BatchNormalization uses trained statistics).
I think I'm losing my mind at this point.
I'm using Lasagne for a small convolutional neural network. It trains perfectly, I can compute the error on training and validation set as well, but I cannot save the trained model on the disk. Better, I can save it and load it, but I cannot use it to predict for new data.
This is what I do after training
model = {'network': network, 'params': get_all_params(network), 'params_values': get_all_param_values(network)}
pickle.dump(model, open('models/model_1.pkl', 'wb'), protocol=pickle.HIGHEST_PROTOCOL)
And this is what I do to load the model
with open('models/model.pkl', 'rb') as pickle_file:
model = pickle.load(pickle_file)
network = model['network']
values = model['params_values']
set_all_param_values(network, values)
T_input = T.tensor4('input', dtype='float32')
T_target = T.ivector('target')
predictions = get_output(network, deterministic=True)
loss = (cross_entropy(predictions, T_target)).mean()
acc = T.mean(T.eq(T.argmax(predictions, axis=1), T_target), dtype=config.floatX)
test_fn = function([T_input, T_target], [loss, acc])
I cannot even pass the real numpy input, that I get this error
theano.compile.function_module.UnusedInputError: theano.function was asked to create a
function computing outputs given certain inputs, but the provided input variable at index 0
is not part of the computational graph needed to compute the outputs: input.
To make this error into a warning, you can pass the parameter
on_unused_input='warn' to theano.function. To disable it completely, use
on_unused_input='ignore'.
I tried to set the parameter on_unused_input='warn' then, and this is the result
theano.gof.fg.MissingInputError: An input of the graph, used to compute (..)
was not provided and not given a value.Use the Theano flag
exception_verbosity='high',for more information on this error.
The problem is that your T_input is not tied to the input layer and hence theano can't compile it
T_input = lasagne.layers.get_all_layers(network)[0].input_var