Basic classification in tensorflow tutorial - python-3.x

I just started learning tensorflow and am working on the basic classification tutorial in their official page.
Basic Classification Tutorial
From the below piece of code
def plot_image(i, predictions_array, true_label, img):
predictions_array, true_label, img = predictions_array[i], true_label[i], img[i]
plt.grid(False)
plt.xticks([])
plt.yticks([])
plt.imshow(img, cmap=plt.cm.binary)
predicted_label = np.argmax(predictions_array)
if predicted_label == true_label:
color = 'blue'
else:
color = 'red'
plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
100*np.max(predictions_array),
class_names[true_label]),
color=color)
def plot_value_array(i, predictions_array, true_label):
predictions_array, true_label = predictions_array[i], true_label[i]
plt.grid(False)
plt.xticks([])
plt.yticks([])
thisplot = plt.bar(range(10), predictions_array, color="#777777")
plt.ylim([0, 1])
predicted_label = np.argmax(predictions_array)
thisplot[predicted_label].set_color('red')
thisplot[true_label].set_color('blue')
The below are the sample results of the test data.
Case 1:
Case 2
Even though the system predicted it with 100%, then why did it displayed the results with the red color?
In the predicted label, it is not showing any other classes.

There is a bug in the code.
"i" will for predictions_array, take the first array element(which is an array). This part is ok, but it is always going to be index 0 you need for the prediction array. Two ways to fix this: either pass it as "predictions_array[0]" when calling like I did below. Or modify the function to include "predictions_array = predictions_array[0]"
Since "i" must be 0 for the predictions array it will in the original code always check test_labels[0]. This will then for all cases when you predict something else than 9 give a red (since it thinks its a wrong prediction). Therefore passing i as the index of the test image will give you the correct label.
Suggestion of a modified function:
def plot_value_array(i, predictions_array, true_label):
print(true_label)
true_label = true_label[i]
plt.grid(False)
plt.xticks([])
plt.yticks([])
thisplot = plt.bar(range(10), predictions_array, color="#777777")
plt.ylim([0, 1])
predicted_label = np.argmax(predictions_array)
thisplot[predicted_label].set_color('red')
thisplot[true_label].set_color('blue')
And modified calling where "1" is the image I am in this case testing (make this a variable so you dont have to type it twice when testing).
In other words: in case img = test_images[1] I have to pass 1 to the function.
plot_value_array(1, predictions_single[0], test_labels)
plt.xticks(range(10), class_names, rotation=45)
plt.show()

Related

Make one y-axis label bold in matplotlib

Goodmorning,
Question, I've got this script that creates a horizontal bar chart (see image)
I would like to have one label in the y-axis bold "Nederland".
I've searched an tried a lot, but I really have no idea how I can do this.
I found this solution:
Matplotlib - Changing the color of a single x-axis tick label
But I could not get it to work.
Any hint to a solution would be great.
def AVG_BarChart(self, data:dict=None, graph_file:str = None, datum:str=None, countries:dict=None, watermarktext:str="energieprijzenbot.nl", prijsper:str="kWh")->bool:
plt.figure(figsize=(9, 6))
plt.xlabel(f"Prijs per {prijsper}")
plt.title(f"Gemiddelde {prijsper} inkoopprijs per land {datum}")
colors = ["#FE8000", "#EFBD76", "#FFA52B", "#FF9D3C", "#FFF858", "#FCFFCB", "#07EEB2", "#FF4179","#E05B4B", "#E09336", "#DAB552", "#DBD9A6", "#87B49C", "#4B8A7E", "#A5DD96", "#E1F3C9", "#0095AD", "#00D5E5", "#82E9F0", "#C0ED42", "#FFE301", "#FFF352", "#FF85DA", "#FF69B3","#A15AC4", "#3F7539", "#B8CBAD", "#E1E2C2", "#F84040", "#9D1E29"]
random.shuffle(colors)
values = 2 ** np.random.randint(2, 10, len(data))
max_value = values.max()
labels = list(data.keys())
values = list(data.values())
height = 0.9
plt.barh(y=labels, width=values, height=height, color=colors, align='center', alpha=0.8)
ax = plt.gca()
ax.xaxis.set_major_formatter('€ {x:n}')
plt.bar_label(ax.containers[0], labels=[f'€ {x:n}' for x in ax.containers[0].datavalues], label_type="edge", padding=-50)
ax.text(0.5, 0.5, watermarktext, transform=ax.transAxes,
fontsize=40, color='gray', alpha=0.3,
ha='center', va='center', rotation='30')
for i, (label, value) in enumerate(zip(labels, values)):
country_iso = self.get_key(val=label, my_dict=countries).lower()
self.offset_image(x=value, y=i, flag=country_iso, bar_is_too_short=value < max_value / 10, ax=ax)
plt.subplots_adjust(left=0.15)
plt.savefig(graph_file, bbox_inches='tight', width = 0.4)
return True
I tried looping thru the labels like this
i = 0
for w in ax.get_yticklabels():
country = ax.get_yticklabels()[i].get_text()
if country == "Nederland":
ax.get_yticklabels()[i].set_color('red')
ax.get_yticklabels()[i].set_fontweight('bold')
i += 1
When debugging I actually get a country name back, but when running the script normal, all country labels are empty...
So, I was close to the answer. But somehow I got back empty .get_text() string.
# ... some code
labels = list(data.keys())
# ... more code
ax.set_yticklabels(labels)
for lab in ax.get_yticklabels():
if lab.get_text() == "Nederland":
lab.set_fontweight('bold')
I just hope by setting the labels again, It does not mix up anything :-)

How to print prediction by category inside a loop

I'm having a problem with printing pictures with labels of prediction in my project.
i = 1
for image in DATADIR:
prediction = model.predict
([prepare(r'MY_DIR\manual_testing\{}.jpg'.format(i))])
img = mpimg.imread(r'MY_DIR\manual_testing\{}.jpg'.format(i))
imgplot = plt.imshow(img)
plt.show()
print(CATEGORIES[int(prediction[0][0])])
i += 1
Here MY_DIR replaces the actual directory.
I'm having the following error: TypeError: 'method' object is not subscriptable
I don't really understand what should be changed. If I try to put print('Hello world') in the for loop everything is working.
p.s. If you have an example of how to make the output look more beautiful you are welcome.
Thank you in advance.
I found the solution:
i = 1
for item in os.listdir(DATADIR):
prediction = model.predict([prepare(r'MY_DIR\manual_testing\{}.jpg'.format(i))])
img = mpimg.imread(r'MY_DIR\manual_testing\{}.jpg'.format(i))
imgplot = plt.imshow(img)
plt.show()
print(CATEGORIES[int(prediction[0][0])])
i += 1

How to print the detected classes after performing object detection on an image?

I am following the object_detection_tutorial.ipynb tutorial.
Here is the code ( I only put parts which are needed, the rest of the code is the same as the notebook):
my_results = [] # I added this, a list to hold the detected classes
PATH_TO_LABELS = 'D:\\TensorFlow\\models\\research\\object_detection\\data\\oid_v4_label_map.pbtxt'
category_index = label_map_util.create_category_index_from_labelmap(PATH_TO_LABELS, use_display_name=True)
PATH_TO_TEST_IMAGES_DIR = pathlib.Path('C:\\Users\\Bhavin\\Desktop\\objects')
TEST_IMAGE_PATHS = sorted(list(PATH_TO_TEST_IMAGES_DIR.glob("*.jpg")))
TEST_IMAGE_PATHS
model = load_model()
def run_inference_for_single_image(model, image):
image = np.asarray(image)
# The input needs to be a tensor, convert it using `tf.convert_to_tensor`.
input_tensor = tf.convert_to_tensor(image)
# The model expects a batch of images, so add an axis with `tf.newaxis`.
input_tensor = input_tensor[tf.newaxis,...]
# Run inference
output_dict = model(input_tensor)
# All outputs are batches tensors.
# Convert to numpy arrays, and take index [0] to remove the batch dimension.
# We're only interested in the first num_detections.
num_detections = int(output_dict.pop('num_detections'))
output_dict = {key:value[0, :num_detections].numpy()
for key,value in output_dict.items()}
output_dict['num_detections'] = num_detections
# detection_classes should be ints.
output_dict['detection_classes'] = output_dict['detection_classes'].astype(np.int64)
# Handle models with masks:
if 'detection_masks' in output_dict:
# Reframe the the bbox mask to the image size.
detection_masks_reframed = utils_ops.reframe_box_masks_to_image_masks(
output_dict['detection_masks'], output_dict['detection_boxes'],
image.shape[0], image.shape[1])
detection_masks_reframed = tf.cast(detection_masks_reframed > 0.5,
tf.uint8)
output_dict['detection_masks_reframed'] = detection_masks_reframed.numpy()
return output_dict
def show_inference(model, image_path):
# the array based representation of the image will be used later in order to prepare the
# result image with boxes and labels on it.
image_np = np.array(Image.open(image_path))
# Actual detection.
output_dict = run_inference_for_single_image(model, image_np)
# Visualization of the results of a detection.
vis_util.visualize_boxes_and_labels_on_image_array(
image_np,
output_dict['detection_boxes'],
output_dict['detection_classes'],
output_dict['detection_scores'],
category_index,
instance_masks=output_dict.get('detection_masks_reframed', None),
use_normalized_coordinates=True,
line_thickness=8)
name = "Image" + str(i) + ".jpg"
img = Image.fromarray(image_np)
plt.imsave(name,image_np)
my_results.append(output_dict['detection_classes']) # I added this
print(my_results) # I added this
#img.show()
i = 1
for image_path in TEST_IMAGE_PATHS:
show_inference(model, image_path)
i += 1
I checked some related stack overflow questions and the answer had something to do with category index. But the code and examples used are very different from the tutorial I am following.
The line : my_results.append(output_dict['detection_classes'])
Gives me output: [array([55], dtype=int64)]
How do I extract the classes of the detected objects?
First import six
Add get_classes_name_and_scores method, before def show_inference(model, image_path):
get_classes_name_and_scores method returns {'name': 'person', 'score': '91%'}
def get_classes_name_and_scores(
boxes,
classes,
scores,
category_index,
max_boxes_to_draw=20,
min_score_thresh=.9): # returns bigger than 90% precision
display_str = {}
if not max_boxes_to_draw:
max_boxes_to_draw = boxes.shape[0]
for i in range(min(max_boxes_to_draw, boxes.shape[0])):
if scores is None or scores[i] > min_score_thresh:
if classes[i] in six.viewkeys(category_index):
display_str['name'] = category_index[classes[i]]['name']
display_str['score'] = '{}%'.format(int(100 * scores[i]))
return display_str
Then add after vis_util.visualize_boxes_and_labels_on_image_array
print(get_classes_name_and_scores(
output_dict['detection_boxes'],
output_dict['detection_classes'],
output_dict['detection_scores'],
category_index))

HSV OpenCv colour range [duplicate]

This question already has answers here:
OpenCV: Choosing HSV thresholds for color filtering
(2 answers)
Closed 10 months ago.
Can anyone please tell me a name of a website or any place from where I can get the upper and lower range of HSV of basic colours like
yellow,green,red,blue,black,white,orange
Actually I was making a bot which would at first follow black coloured line and then in the middle of the line there would be another colour given from where 3 different lines of different colour gets divided.The bot needs to decide which line to follow.
For that I need the proper range of hsv colours
Inspired from the answer at answers.opencv link.
According to docs here
the HSV ranges like H from 0-179, S and V from 0-255,
so as for your requirements for lower range and upper range example you can do for any given [h, s, v] to
[h-10, s-40, v-40] for lower
and
[h+10, s+10, v+40] for upper
for the yellow,green,red,blue,black,white,orange rgb values.
Copied code from the example :
import cv2
import numpy as np
image_hsv = None # global ;(
pixel = (20,60,80) # some stupid default
# mouse callback function
def pick_color(event,x,y,flags,param):
if event == cv2.EVENT_LBUTTONDOWN:
pixel = image_hsv[y,x]
#you might want to adjust the ranges(+-10, etc):
upper = np.array([pixel[0] + 10, pixel[1] + 10, pixel[2] + 40])
lower = np.array([pixel[0] - 10, pixel[1] - 10, pixel[2] - 40])
print(pixel, lower, upper)
image_mask = cv2.inRange(image_hsv,lower,upper)
cv2.imshow("mask",image_mask)
def main():
import sys
global image_hsv, pixel # so we can use it in mouse callback
image_src = cv2.imread(sys.argv[1]) # pick.py my.png
if image_src is None:
print ("the image read is None............")
return
cv2.imshow("bgr",image_src)
## NEW ##
cv2.namedWindow('hsv')
cv2.setMouseCallback('hsv', pick_color)
# now click into the hsv img , and look at values:
image_hsv = cv2.cvtColor(image_src,cv2.COLOR_BGR2HSV)
cv2.imshow("hsv",image_hsv)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__=='__main__':
main()
Above code is for when you want to directly select the HSV range from the image or video you are capturing, by clicking on the desired color.
If you want to predefine your ranges you can just use write simple code snippet using inbuilt python library colorsys to convert rbg to hsv using colorsys.rgb_to_hsv function
example in docs
Note this function accepts rgb values in range of 0 to 1 only and gives hsv values also in 0 to 1 range so to use the same values you will need to normalize it for opencv
code snippet
import colorsys
'''
convert given rgb to hsv opencv format
'''
def rgb_hsv_converter(rgb):
(r,g,b) = rgb_normalizer(rgb)
hsv = colorsys.rgb_to_hsv(r,g,b)
(h,s,v) = hsv_normalizer(hsv)
upper_band = [h+10, s+40, v+40]
lower_band = [h-10, s-40, v-40]
return {
'upper_band': upper_band,
'lower_band': lower_band
}
def rgb_normalizer(rgb):
(r,g,b) = rgb
return (r/255, g/255, b/255)
def hsv_normalizer(hsv):
(h,s,v) = hsv
return (h*360, s*255, v*255)
rgb_hsv_converter((255, 165, 0))
will return
{'upper_band': [48.82352941176471, 295.0, 295.0], 'lower_band': [28.82352941176471, 215.0, 215.0]}
which is your orange hsv bands.

How to print the values of tensors inside a while loop?

I'm very new to tensorflow, and I couldn't figure this one out.
I have this while loop:
def process_tree_tf(n_child, reprs, weights, bias, embed_dim, activation = tf.nn.relu):
n_child, reprs = n_child, reprs
parent_idxs = generate_parents_numpy(n_child)
loop_idx = reprs.shape[0] - 1
loop_vars = loop_idx, reprs, parent_idxs, weights, embed_dim
def loop_condition(loop_ind, *_):
return tf.greater(0, loop_idx)
def loop_body(loop_ind, reprs, parent_idxs, weights, embed_dim):
x = reprs[loop_ind]
x_expanded = tf.expand_dims(x, axis=-1)
w = weights
out = tf.squeeze(tf.add(tf.matmul(x_expanded,w,transpose_a=True), bias))
activated = activation(out)
par_idx = parent_idxs[loop_ind]
reprs = update_parent(reprs, par_idx, embed_dim, activated)
reprs = tf.Print(reprs, [reprs]) #This doesn't work
loop_ind = loop_ind-1
return loop_ind, reprs, parent_idxs, weights, embed_dim
return tf.while_loop(loop_condition, loop_body, loop_vars)
And I'm evaluating it this way:
embed_dim = 2
hidden_dim = 2
n_nodes = 4
batch = 2
reprs = np.ones((n_nodes, embed_dim+hidden_dim))
n_child = np.array([1, 1, 1, 0])
weights = np.ones((embed_dim+hidden_dim, hidden_dim))
bias = np.ones(hidden_dim)
with tf.Session() as sess:
_, r, *_ = process_tree_tf(n_child, reprs, weights, bias, embed_dim, activation=tf.nn.relu)
print(r.eval())
I want to check the value of reprs inside the while loop, but tf.Print doesn't seem to work, and print just tells me it's a tensor and gives me its shape.
How do I go about doing this?
Thank you so much!
Take a look at this webpage: https://www.tensorflow.org/api_docs/python/tf/Print
You can see that tf.Print is an identity operator with the side effect of printing data when evaluating. You should therefore use this line to print:
reprs = tf.Print(reprs, [reprs])
Hope this helps, and good luck!
The approach suggested by rmeertens is the one I think is correct. I would just add (as a response to your comments) that if something is printing "Tensor("while/update_parent:0, ...... " then that implies that that value in the graph is not being evaluated.
You are likely seeing that as the output of your "print(r.eval())" statement, NOT the tf.Print() statement.
Note that the output of tf.Print() appears in PyCharm (the IDE I am using) in red, while the output of a normal python print operation appears in black. So the tf.Print() output looks like a warning message. It could be that it is indeed printing out, but you are simply overlooking it.

Resources