Image Classifier with Tensorflow and Keras - python

I'm trying to get an Image Classifier to work. So far the model does seem to work but now every time I want to test an image to see if it is being recognized appropriately I have to do the whole training all over. I'm very new to this but I suppose there should be another way to only test the images without the training right?
I also have one further question concerning the code itself.
if result [0][0] >= 0.5:
prediction = "cogwheel"
else:
prediction = "not a cogwheel"
print(prediction)
I am trying to differentiate between images that represent cogwheels and those that don't. I understand that if the probability is > 0,5 it is a cogwheel and else it is not. But what does [0][0] here mean?
Thank you so much for your help!

Since you are a beginner, you may not know that you actually do not need to retrain the model in order to test :D. Your hunch is right, and we will see down below how you can do that.
You can save the weights of your model in a specific file format. In Keras, it is a file with the extension .hdf5.
from tensorflow.keras.models import load_model
##Do some stuff, train model
model.save(model_name)
##Do some stuff
loaded_model = load_model(model_name)
Please make sure that "model_name" includes .hdf5. For example, "my_model.hdf5".
Although it is not clear what you used to get the result (I assume result = model.predict(sample), where sample is a test sample), the first index corresponds to the class(label) and the second label corresponds to the probability of that specific class.
Test to see result[0][0] (probability of class 0), result[1][0] (probability of class 1).

Related

Tensorflow Flower Classifier consistent predictions with varied input

I am following this tensorflow tutorial notebook to classify images of flowers:
https://colab.research.google.com/github/tensorflow/docs/blob/master/site/en/tutorials/images/classification.ipynb#scrollTo=U-e-XzMeyH2O
Everything seems OK until the final cell in the notebook where the trained model is used to predict the class of a new image. I am getting identical predictions for all inputs.
I tried adding:
print(predictions)
print(score)
Then predicting on the sample image (of a sunflower):
sunflower_url = "https://storage.googleapis.com/download.tensorflow.org/example_images/592px-Red_sunflower.jpg"
outputs:
[[-2.1131027 -1.3355725 0.29224062 3.8924832 1.3749899 ]]
tf.Tensor([0.00220911 0.00480723 0.02448191 0.896212 0.07228985], shape=(5,), dtype=float32)
This image most likely belongs to sunflowers with a 89.62 percent confidence.
But if I just change the input to a picture of a rose, like:
sunflower_url = "https://images.photowall.com/products/64377/rose-flower.jpg"
outputs:
[[-2.1131027 -1.3355725 0.29224062 3.8924832 1.3749899 ]]
tf.Tensor([0.00220911 0.00480723 0.02448191 0.896212 0.07228985], shape=(5,), dtype=float32)
This image most likely belongs to sunflowers with a 89.62 percent confidence.
I have seen that there can be many model related issues (scaling / overfitting etc) which can cause identical outputs, however it seems strange that a tutorial example would fail in this way. So I suspect there is something more obvious that I am missing.
The issue here was related to the line
sunflower_path = tf.keras.utils.get_file('Red_sunflower', origin=sunflower_url)
When downloading a new image, it was NOT overwriting the stored image. So the model was making a prediction against the same input every time.
I manually defined the save location and made sure to get the input from that, then it worked.
Note that you do not need to rescale the image, this is handled within the predict() function from keras as already defined in the model.

CNTK evaluation for image classification

I built an image classifier using CNTK. The images are grayscale. Therefore, I entered the number of channels as 1. So, the model requires (1x64x64) data (64 being the image height and width).
The problem is, when I try to predict the class of a new image, it is seen as (64x64) only. So, the code errors out due to data mismatch.
Therefore, I reshaped the image using:
image_data = image_data.reshape((1, image_data.shape[0], image_data.shape[1]))
This generated (1x64x64) - which worked. Though the predictions are coming the same class for every image I select. I wonder if it is because of this reshaping or not. Can someone chime in? Thanks!
Reshaping your input would not affect the output of the model. If it is only predicting one class for every image, it is an issue with model training. I would suggest you try predicting on your training data to see if it only predicts one class on the training data. If that is the case, it is definitely a model training issue.

How to add regularization in CNN autoencoder model_Based on Keras

I am a freshman in Keras and deep learning, I am not quite sure the right way to add the regularization, I wrote a CNN autoencoder using the API model class, right now I add the regularizer in each of the "Conv2D" Keras function,I am not sure if this is the right place to add regularization, could anyone please give me some suggestions?
(I tried to run the training and check the reconstructed test images, it is OK, but not very good, I use MNIST to test, the line of the reconstructed MNIST number is thicker than the original one.)
In my problem, the input image is an impaired one, and the original good image is used as a training label, by comparing the output image of the CNN with the training label image, I use the "mean absolute error" to define the loss , and also use it as the metric.
I defined three functions first, one downsampling function (the one below), one upsampling function, and one function to squeeze the third dimension of the matrix to get a two-dimensional matrix as the output.
My code is too long, just to help illustrate the problem, part of my code is as follow:
After having three defined functions, I defined the model as follow (not in detail, just part of it to help explain my problem)
load all necessary parameters to the model,then define the optimizer parameters, and compile the model

Functional API Keras alternate solution for predict_classes()

Please refer here for my previous question for background information. As per answer suggested by Nassim Ben. I trained model of two-path architecture using functional API. Now I feel stuck as I need to predict the class of each pixel. here is the code for the same:
imgs = io.imread(test_img).astype('float').reshape(5,240,240)
plist = []
# create patches from an entire slice
for img in imgs[:-1]:
if np.max(img) != 0:
img /= np.max(img)
p = extract_patches_2d(img, (33,33))
plist.append(p)
patches = np.array(zip(np.array(plist[0]), np.array(plist[1]), np.array(plist[2]), np.array(plist[3])))
# predict classes of each pixel based on model
full_pred = self.model_comp.predict_classes(patches)
fp1 = full_pred.reshape(208,208)
But according to the github-link predict_classes() is unavailable. So my question is there any other alternative that I can try?
Nassim answer is great but I want to share with you the experience I have with similiar tasks:
Never use predict_proba Keras for version. Here you could find why.
Most of methods used for turning predictions into classes doesn't take into account your data statistics. In case of image segmentation - very often detecting an object is more important then detecting a background. For this reason I advise you to use a threshold obtained from a precision-recall curve for each class. In this case - you need to set a threshold value for which precision == recall (or it's as close as possible). After you obtain the thresholds - you need to write your custom function for a class prediction.
Indeed, predict_classes is not available for functionnal models as it might not make sense to use it in some cases.
However, a "one liner" solution exists to this :
y_classes = keras.utils.np_utils.probas_to_classes(self.model_comp.predict(patches))
This works in keras 1.2.2, not sure about keras 2.0, I couldn't find the function in the source code. But there is really nothing shady about this, your model outputs a vector of probabilities to belonging to each class. What the function does is just take the argmax and outputs the class coresponding to the highest probability.
I hope this helps.

Alex-Net for feature extraction

I try to get reliable features for ImageNet to do further classification on them. To achieve that I would like to use tensorflow with Alexnet, for feature extraction. That means I would like to get the values from the last layer in the CNN. Could someone write a piece of Python code that explains how that works?
As jonrsharpe mentioned, that's not really stackoverflow's MO, but in practice, many people do choose to write code to help explain answers (because it's often easier).
So I'm going to assume that this was just miscommunication, and you really intended to ask one of the following two questions:
How does one grab the values of the last layer of Alexnet in TensorFlow?
How does feature extraction from the last layer of a deep convolutional network like alexnet work?
The answer to the first question is actually very easy. I'll use the cifar10 example code in TensorFlow (which is loosely based on AlexNet) as an example. The forward pass of the network is built in the inference function, which returns a variable representing the output of the softmax layer. To actually get predicted image labels, you just argmax the logits, like this: (I've left out some of the setup code, but if you're already running alexnet, you already have that working)
logits = cifar10.inference(images)
predictions = tf.argmax(logits,1)
# Actually run the computation
labels = session.run([predictions])
So grabbing just the last layer features is literally just as easy as asking for them. The only wrinkle is that, in this case, cifar10 doesn't natively expose them, so you need to modify the cifar10.inference function to return both:
# old code in cifar10.inference:
# return softmax_linear
# new code in cifar10.inference:
return softmax_linear, local4
And then modify all the calls to cifar10.inference, like the one we just showed:
logits,local4 = cifar10.inference(images)
predictions = tf.argmax(logits,1)
# Actually run the computation, this time asking for both answers
labels,last_layer = session.run([predictions, local4])
And that's it. last_layer contains the last layer for all of the inputs you gave the model.
As for the second question, that's a much deeper question, but I'm guessing that's why you want to work on it. I'd suggest starting by reading up on some of the papers published in this area. I'm not an expert here, but I do like Bolei Zhou's work. For instance, try looking at Figure 2 in "Learning Deep Features for Discriminative Localization". It's a localization paper, but it's using very similar techniques (and several of Bolei's papers use it).

Categories

Resources