-# TODO
+from PIL import Image
+from io import BytesIO
+import base64
+import tensorflow as tf
+from tensorflow import keras
+from sklearn.preprocessing import LabelEncoder
+
+def load_image(contents):
+ """
+ Given a base64 decoded image from a POST request to /result, return a tensorflow tensor
+ representation of the image data.
+
+ Parameters
+ ----------
+ contents : bytes
+ Output from UploadFile.read()
+
+ Returns
+ -------
+ image : tf.Tensor
+ Tensor representation of the image data
+ """
+ bytes_image = BytesIO(contents)
+
+ # Load image as batch tensor
+ # https://www.tensorflow.org/api_docs/python/tf/keras/utils/load_img
+ pil_image = keras.utils.load_img(bytes_image)
+ array_image = keras.utils.img_to_array(pil_image)
+ image = tf.convert_to_tensor(array_image)
+
+ return image
+
+def preprocess_image(image):
+ """
+ Normalize pixel values, reshape image if necessary, and convert to greyscale.
+ """
+ # Normalize pixel values
+ image = image/255
+ image = tf.cast(image, tf.float32)
+
+ # Reshape
+ if image.shape != (400, 400, 3):
+ image = tf.image.resize(image, [400, 400])
+
+ # Convert to greyscale
+ image = tf.tensordot(image, tf.constant([0.299, 0.587, 0.114]), axes=[[2], [0]])
+ # grey_image = tf.expand_dims(grey_image, -1)
+
+ return image
\ No newline at end of file
-# TODO
+from datasets import load_dataset
+from tensorflow import keras
+import tensorflow as tf
+import numpy as np
+from sklearn.preprocessing import LabelEncoder
+from params import DATASET_REPO_ID, label_names_to_english
+
+
+def get_label_encoder():
+ """
+ Create LabelEncoder object to translate integers to text.
+ """
+ dataset_info = load_dataset(DATASET_REPO_ID, split="train", streaming=True)._info
+ labels = dataset_info.features['label'].names
+ labels = [label_names_to_english[l] for l in labels]
+ le = LabelEncoder()
+ le.fit(labels)
+
+ return le
+
+def make_prediction(model, input):
+ """
+ Make prediction for image and return the label and associated probability.
+
+ Parameters
+ ----------
+ model : keras.Sequential
+ The cloud identifier model
+ input : tf.Tensor
+ Output from preproceess_data()
+
+ Returns
+ -------
+ predicted_label_name : str
+ Name of the most likely label
+ predicted_proba : np.float64
+ Probability of the most likely label
+ """
+ batch = tf.expand_dims(input, axis=0)
+ probabilities = model.predict(batch)
+ predicted = np.argmax(probabilities)
+ predicted_proba = round(np.max(probabilities) * 100, 1)
+
+ le = get_label_encoder()
+ predicted_label_name = le.inverse_transform(predicted.reshape(1,))[0]
+
+ return predicted_label_name, predicted_proba
\ No newline at end of file
from tempfile import NamedTemporaryFile
import os
import base64
+from data import load_image, preprocess_image
+from model import get_model
+from inference import make_prediction, get_label_encoder
app = FastAPI()
templates = Jinja2Templates("templates")
-@app.get("/", response_class=HTMLResponse)
+@app.get("/", response_class = HTMLResponse)
def index(request: Request):
context = {"request": request}
response = templates.TemplateResponse("index.html", context)
def show_image(request: Request, background_tasks: BackgroundTasks, input_image: UploadFile = File(...)):
contents = input_image.file.read()
encoded_image = base64.b64encode(contents).decode("utf-8")
-
- context = {"request": request, "image": encoded_image}
+ raw_image = load_image(contents)
+ image = preprocess_image(raw_image)
+ model = get_model()
+ predicted_label, predicted_probability = make_prediction(model, image)
+
+ context = {
+ "request": request,
+ "image": encoded_image,
+ "predicted_label": predicted_label,
+ "predicted_probability": f"{predicted_probability}%"
+ }
response = templates.TemplateResponse("result.html", context)
return response
-# TODO
+from huggingface_hub import hf_hub_download
+from tensorflow import keras
+from params import MODEL_REPO_ID, MODEL_FILENAME
+def get_model():
+ """
+ Download and load the model from huggingface
+ """
+ model_path = hf_hub_download(repo_id=MODEL_REPO_ID, filename=MODEL_FILENAME)
+ model = keras.models.load_model(model_path)
+
+ return model
\ No newline at end of file
--- /dev/null
+DATASET_REPO_ID = "aduuuuuu/CCSN"
+MODEL_REPO_ID = "aduuuuuu/wu"
+MODEL_FILENAME = "model.h5"
+label_names_to_english = {
+ "Ac": "altocumulus",
+ "As": "altostratus",
+ "Cb": "cumulonimbus",
+ "Cc": "cumulus",
+ "Ci": "cirrus",
+ "Cs": "cirrostratuss",
+ "Ct": "contrail",
+ "Cu": "cumulus",
+ "Ns": "nimbostratus",
+ "Sc": "stratocumulus",
+ "St": "stratus"
+}
\ No newline at end of file
<!DOCTYPE html>
<html><body>
- <p>Wow what a lovely pic !!!</p>
+ <p>Wu say this is a {{ predicted_label }} with probability {{ predicted_probability }}</p>
<img src="data:image/jpeg;base64,{{image | safe}}" />
<a href="/">Do it again, do it again!</a>
</body></html>
\ No newline at end of file