Narsil HF staff commited on
Commit
5e11988
1 Parent(s): 403cb06

Initial commit.

Browse files
.gitattributes CHANGED
@@ -25,3 +25,6 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
25
  *.zip filter=lfs diff=lfs merge=lfs -text
26
  *.zstandard filter=lfs diff=lfs merge=lfs -text
27
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
25
  *.zip filter=lfs diff=lfs merge=lfs -text
26
  *.zstandard filter=lfs diff=lfs merge=lfs -text
27
  *tfevents* filter=lfs diff=lfs merge=lfs -text
28
+ keras_metadata.pb filter=lfs diff=lfs merge=lfs -text
29
+ variables/ filter=lfs diff=lfs merge=lfs -text
30
+ variables/variables.data-00000-of-00001 filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ tags:
3
+ - image-segmentation
4
+ - generic
5
+ library_name: generic
6
+ dataset:
7
+ - oxfort-iit pets
8
+ license: apache-2.0
9
+ ---
10
+ ## Keras semantic segmentation models on the 🤗Hub! 🐶 🐕 🐩
11
+
12
+ Image classification task tells us about a class assigned to an image, and object detection task creates a boundary box on an object in an image. But what if we want to know about the shape of the image? Segmentation models helps us segment images and reveal their shapes. It has many variants. You can host your Keras segmentation models on the Hub.
13
+ Semantic segmentation models classify pixels, meaning, they assign a class (can be cat or dog) to each pixel. The output of a model looks like following.
14
+ ![Raw Output](./raw_output.jpg)
15
+ We need to get the best prediction for every pixel.
16
+ ![Mask](./mask.jpg)
17
+ This is still not readable. We have to convert this into different binary masks for each class and convert to a readable format by converting each mask into base64. We will return a list of dicts, and for each dictionary, we have the label itself, the base64 code and a score (semantic segmentation models don't return a score, so we have to return 1.0 for this case). You can find the full implementation in ```pipeline.py```.
18
+ ![Binary Mask](./binary_mask.jpg)
19
+ Now that you know the expected output by the model, you can host your Keras segmentation models (and other semantic segmentation models) in the similar fashion. Try it yourself and host your segmentation models!
20
+ ![Segmented Cat](./hircin_the_cat.png)
binary_mask.jpg ADDED
config.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ {
2
+ "id2label": {
3
+ "0": 0,
4
+ "1": 1,
5
+ "2": 2
6
+ }
7
+ }
hircin_the_cat.png ADDED
image/.DS_Store ADDED
Binary file (6.15 kB). View file
image/binary_mask.jpg ADDED
image/mask.jpg ADDED
image/raw_output.jpg ADDED
keras_metadata.pb ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e7844f7cdd94bacbd2dceb2000b172c07e3a3db345cd29ea0d51d66107ff28e9
3
+ size 563033
mask.jpg ADDED
pipeline.py ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from typing import Any, Dict, List
3
+
4
+ import tensorflow as tf
5
+ from tensorflow import keras
6
+ import base64
7
+ import io
8
+ import os
9
+ import numpy as np
10
+ from PIL import Image
11
+
12
+
13
+
14
+ class PreTrainedPipeline():
15
+ def __init__(self, path: str):
16
+ # load the model
17
+ self.model = keras.models.load_model(os.path.join(path, "tf_model.h5"))
18
+
19
+ def __call__(self, inputs: "Image.Image")-> List[Dict[str, Any]]:
20
+
21
+ # convert img to numpy array, resize and normalize to make the prediction
22
+ #with Image.open(inputs) as img:
23
+ img = np.array(inputs)
24
+
25
+ im = tf.image.resize(img, (128, 128))
26
+ im = tf.cast(im, tf.float32) / 255.0
27
+ pred_mask = model.predict(im[tf.newaxis, ...])
28
+
29
+ # take the best performing class for each pixel
30
+ # the output of argmax looks like this [[1, 2, 0], ...]
31
+ pred_mask_arg = tf.argmax(pred_mask, axis=-1)
32
+
33
+ labels = []
34
+
35
+ # convert the prediction mask into binary masks for each class
36
+ binary_masks = {}
37
+ mask_codes = {}
38
+
39
+ # when we take tf.argmax() over pred_mask, it becomes a tensor object
40
+ # the shape becomes TensorShape object, looking like this TensorShape([128])
41
+ # we need to take get shape, convert to list and take the best one
42
+
43
+ rows = pred_mask_arg[0][1].get_shape().as_list()[0]
44
+ cols = pred_mask_arg[0][2].get_shape().as_list()[0]
45
+
46
+ for cls in range(pred_mask.shape[-1]):
47
+
48
+ binary_masks[f"mask_{cls}"] = np.zeros(shape = (pred_mask.shape[1], pred_mask.shape[2])) #create masks for each class
49
+
50
+ for row in range(rows):
51
+
52
+ for col in range(cols):
53
+
54
+ if pred_mask_arg[0][row][col] == cls:
55
+
56
+ binary_masks[f"mask_{cls}"][row][col] = 1
57
+ else:
58
+ binary_masks[f"mask_{cls}"][row][col] = 0
59
+
60
+ mask = binary_masks[f"mask_{cls}"]
61
+ mask *= 255
62
+ img = Image.fromarray(mask.astype(np.int8), mode="L")
63
+
64
+ # we need to make it readable for the widget
65
+ with io.BytesIO() as out:
66
+ img.save(out, format="PNG")
67
+ png_string = out.getvalue()
68
+ mask = base64.b64encode(png_string).decode("utf-8")
69
+
70
+ mask_codes[f"mask_{cls}"] = mask
71
+
72
+
73
+ # widget needs the below format, for each class we return label and mask string
74
+ labels.append({
75
+ "label": f"LABEL_{cls}",
76
+ "mask": mask_codes[f"mask_{cls}"],
77
+ "score": 1.0,
78
+ })
79
+ return labels
raw_output.jpg ADDED
tf_model.h5 ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0258ea75c11d977fae78f747902e48541c5e6996d3d5c700175454ffeb42aa0f
3
+ size 63661584
variables/variables.data-00000-of-00001 ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e3c27336aaecafd070749d833780e6603b9c25caf01a037c0ef9a93ff3b0c36c
3
+ size 63405929
variables/variables.index ADDED
Binary file (17.9 kB). View file