Testing image classification model on new images - tensorflow

I am still a bit new to deep learning.
def predictionrelease(preds):
arr=[]
for i in range(0,len(preds)):
ans=np.argmax(preds[i])
arr.append(ans)
len(arr)
return arr
dir_path = 'predict'
for i in os.listdir(dir_path):
img = image.load_img(dir_path+ '\\' + i, target_size = (200,200,3))
plt.imshow(img)
plt.show()
X = image.img_to_array(img)
X = np.expand_dims(X, axis = 0)
images = np.vstack([X])
val = predictionrelease(model.predict(images))
print(val)
I was able to train a model on image classification. Now i try to predict new images in a single file using the model, but it's end up predicting only one of the images, whereas i want it to give prediction for all the of the images in the file. I iterated over the images, but it's seems not to be working. There is the code:

As a workaround you can use the code below to predict on all images present in a folder.
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import os
dir_path = path_to_the_folder
images=[]
for i in os.listdir(dir_path):
img = tf.keras.utils.load_img(dir_path + i, target_size = (200,200,3))
plt.imshow(img)
plt.show()
X = tf.keras.utils.img_to_array(img)
X = np.expand_dims(X, axis = 0)
images.append(X)
arr=[]
pred=[]
for i in range(len(images)):
pred.append(model.predict(images[i],))
ans=np.argmax(pred)
arr.append(ans)
print(arr)

Related

Different results in tensorflow prediction

I cannot understand why the following codes gives different results. I'm printing the first 3 components of the prediction array to compare results. my_features and feat have totally different results, but they should be the same, given the model and the data are the same. There should be something wrong in the loading and image preprocessing, but I cannot find it. Any help will be appreciated.
import tensorflow as tf
import os
import numpy as np
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications import MobileNetV3Small
from tensorflow.keras.applications.imagenet_utils import preprocess_input
model= MobileNetV3Small(weights='imagenet', include_top=False, pooling='avg')
DatasetPath= "DB"
imagePathList= sorted(os.listdir(DatasetPath))
imagePathList= [os.path.join(DatasetPath, imagePath) for imagePath in imagePathList]
def read_image(filename):
image_string = tf.io.read_file(filename)
image = tf.image.decode_jpeg(image_string, channels=3)
image = tf.image.convert_image_dtype(image, tf.float32)
image = tf.image.resize(image, [224,224])
image = tf.keras.applications.mobilenet_v3.preprocess_input(image)
return image
ds_imagePathList= tf.data.Dataset.from_tensor_slices(imagePathList)
dataset = ds_imagePathList.map(read_image, num_parallel_calls=tf.data.AUTOTUNE)
dataset = dataset.batch(32, drop_remainder=False)
dataset = dataset.prefetch(tf.data.AUTOTUNE)
my_features = model.predict(dataset)
my_features[0][:3]
Second snippet
def loadProcessedImage(path):
#img = image.load_img(path, target_size=model.input_shape[1:3])
img = image.load_img(path, target_size= (224,224,3))
imgP = image.img_to_array(img)
imgP = np.expand_dims(imgP, axis=0)
imgP = preprocess_input(imgP)
return img, imgP
img, x = loadProcessedImage(imagePathList[0])
feat = model.predict(x)
feat = feat.flatten()
feat[:3]
The problem is related to the image resize. In the second snippet there is a call to load_img which internally uses pillow to load and resize the image. The problem is that tf.image.resize is not correct see here, and even this a 2018 blog post, the problem is still there

OpenCV and Tensorflow Colour issue (Most probably due to channels maybe?)

I was using this pytorch model for real-ESRGAN. It was giving good results:
Now I converted this model to tensorflow one. Now when I use this, I am getting image super resoluted (I reached to that conclusion due to image size of output) but its color channels are in very weird condition:
I am using opencv to take input and then model to process it. I feel issue is with BGR and RGB of OpenCV and Tensorflow but using cv2.COLOR_BGRTORGB not helping.
Any idea how to solve this?
This is my code:
from pyexpat import model
import tensorflow as tf
import os.path as osp
import glob
import cv2
import numpy as np
import torch
test_img_folder = './images/*'
model = tf.saved_model.load("./RealESRGAN_1/")
idx = 0
for path in glob.glob(test_img_folder):
idx += 1
base = osp.splitext(osp.basename(path))[0]
print(idx, base)
# read images
img = cv2.imread(path, cv2.IMREAD_COLOR)
print(img.shape)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
cv2.imshow('Input',img)
cv2.waitKey(0)
img = np.transpose(img, (2,0,1))
img = np.expand_dims(img, axis=0)
img = tf.dtypes.cast(img, tf.float32)
with torch.no_grad():
output = model(x = img)
output = output['sum'].numpy()
output = output[0, :, :, :]
output = np.transpose(output, (1,2,0))
cv2.imwrite('./results/{:s}_rlt.png'.format(base), output)

Get a sample of one image per class with image_dataset_from_directory

I am trying to visualize Skin Cancer Images using Keras. I have imported the images in my notebook and have created batch datasets using Keras.image_dataset_from_directory. The code is as follows:
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="training",
seed=1337,
image_size=image_size,
batch_size=batch_size)
Now, I have been trying to visualize the images. However, I want one image from each class (there are 9 classes in the dataset). I have used the below code:
plt.figure(figsize = (10,10))
for images, labels in train_ds.take(1):
for i in range(9):
ax = plt.subplot(3,3,i+1)
plt.imshow(images[i].numpy().astype("uint8"))
plt.title(class_names[labels[i]])
plt.axis("off")
This code gets me a lot of duplicate classes. How do I get one value for each class (in this case I have 9 classes. I want one plot for each of those 9 classes). I am not sure how to fetch unique images and their labels from a BatchDataset!
for i in range(len(class_names)):
filtered_ds = train_ds.filter(lambda x, l: tf.math.equal(l[0], i))
for image, label in filtered_ds.take(1):
ax = plt.subplot(3, 3, i+1)
plt.imshow(image[0].numpy().astype('uint8'))
plt.title(class_names[label.numpy()[0]])
plt.axis('off')
You could loop through and filter on each label.
Example:
import tensorflow as tf
# fake images
imgs = tf.random.normal([100, 64, 64, 3])
# fake labels
labels = tf.random.uniform([100], minval=0, maxval=10, dtype=tf.int32)
# make dataset
ds = tf.data.Dataset.from_tensor_slices((imgs, labels))
for i in range(9):
filtered = ds.filter(lambda _, l: tf.math.equal(l, i))
for img, label in filtered.take(1):
assert label.numpy() == i
# plot image
Try Following Code - This works perfectly to display one image from each of the 10 categories of cifar10:
import numpy as np
import matplotlib.pyplot as plt
from tensorflow import keras
(x_train, y_train), (x_test, y_test)= keras.datasets.cifar10.load_data()
fig, ax= plt.subplots(nrows= 2, ncols= 5, figsize= (18,5))
plt.suptitle('displaying one image of each category in train set'.upper(),
y= 1.05, fontsize= 16)
i= 0
for j in range(2):
for k in range(5):
ax[j,k].imshow(x_train[list(y_train).index(i)])
ax[j,k].axis('off')
ax[j,k].set_title(i)
i+=1
plt.tight_layout()
plt.show()

Simple custom layer in keras, tensorflow confusion

First before I explain, here's the relevant code snippet:
input = Input(shape=(784, ))
hidden1 = Dense(784, activation='relu')(input)
hidden2 = Dense(784, activation='relu')(hidden1)
hidden3 = Dense(1568, activation='relu')(hidden2)
hidden4 = Lambda(lambda x: makeComplex(x))(hidden3)
hidden5 = Reshape((1, 28, 28))(hidden4)
hidden6 = Lambda(lambda x: ifft2(x))(hidden5)
hidden7 = Flatten()(hidden6)
output = Dense(train_targets.shape[1], activation='linear')(hidden7)
model = Model(inputs=input, outputs=output)
print(model.summary())
where ifft2(x) is
def ifft2(x):
import tensorflow as tf
return tf.cast(tf.spectral.ifft2d(tf.cast(x,dtype=tf.complex64)),tf.float32)
My goal now is to implement the makeComplex method.
Basically, it gets a vector of size 1568, and I want it to return a vector of size 784 in the following very simple fashion:
new[k] = old[k] + old[k + 1] * i where i is the imaginary unit
Here's my attempt:
def makeComplex(x):
y = np.zeros((1, 784))
for i in range(784):
y[i] = np.complex(x[i], x[i + 1])
return y
ofcourse this doesnt work because x is not actually a vector but rather a tensorflow tensor. Something I know nothing about. How can I make this work?
An example of tensor [1.,2.,3.,4.], what you want is [1.+2.j,3.+4.j]. I think you can use tf.gather to get two tensors [1.,2.] and [3.,4.], then use tf.complex to get the answer.
import tensorflow as tf
import numpy as np
a = tf.constant([1.,2.,3.,4.])
real = tf.gather(a,np.arange(0,a.get_shape().as_list()[0],2))
imag = tf.gather(a,np.arange(1,a.get_shape().as_list()[0],2))
res = tf.complex(real, imag)

How to import a model using pb file in tensorflow

I have been assigned a task to fine tune deeplab V3+ using tensorflow and python. For that purpose I download the frozen model from deeplab github page. !
I downloaded this file.
Then I searched through the web on how to create a model using these files
There are method only to create model using .ckpt files and .meta files but i don't have any of those file
There are only methods available to create graph from the .pb file. I don't know what to do after creating a graph using the .pb file. I to import the frozen model using these files. Thank you in advance
This should work
import os
from matplotlib import gridspec
from matplotlib import pyplot as plt
import numpy as np
from PIL import Image
import tensorflow as tf
INPUT_TENSOR_NAME = 'ImageTensor:0'
OUTPUT_TENSOR_NAME = 'SemanticPredictions:0'
INPUT_SIZE = 513
with tf.gfile.FastGFile('model/frozen_inference_graph.pb', "rb") as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
g_in = tf.import_graph_def(graph_def, name="")
sess = tf.Session(graph=g_in)
def run(image):
width, height = image.size
resize_ratio = 1.0 * INPUT_SIZE / max(width, height)
target_size = (int(resize_ratio * width), int(resize_ratio * height))
resized_image = image.convert('RGB').resize(target_size, Image.ANTIALIAS)
batch_seg_map = sess.run(
OUTPUT_TENSOR_NAME,
feed_dict={INPUT_TENSOR_NAME: [np.asarray(resized_image)]})
seg_map = batch_seg_map[0]
return resized_image, seg_map
input_image = Image.open('test.jpg')
resized_im, seg_map = run(input_image)
fig = plt.figure()
fig.add_subplot(1, 2, 1)
plt.imshow(resized_im)
fig.add_subplot(1, 2, 2)
plt.imshow(np.ma.masked_equal(seg_map, 0))