diff --git a/.ruff.toml b/.ruff.toml new file mode 100644 index 0000000..afc4ae5 --- /dev/null +++ b/.ruff.toml @@ -0,0 +1,18 @@ +line-length = 100 +target-version = "py310" +lint.select = [ + # pycodestyle + "E", + "W", + # Pyflakes + "F", + # pyupgrade + "UP", + # flake8-bugbear + "B", + # flake8-simplify + "SIM", + # isort + "I", +] +extend-include = ["*.ipynb"] diff --git a/Deep Learning MNIST prediction model with Keras.ipynb b/Deep Learning MNIST prediction model with Keras.ipynb index 9009963..49fbfba 100644 --- a/Deep Learning MNIST prediction model with Keras.ipynb +++ b/Deep Learning MNIST prediction model with Keras.ipynb @@ -22,17 +22,15 @@ "metadata": {}, "outputs": [], "source": [ - "from tensorflow.keras.datasets import mnist # mnist dataset\n", - "from tensorflow.keras import models\n", - "from tensorflow.keras import layers\n", - "from tensorflow.keras.models import load_model\n", - "from tensorflow.keras.utils import to_categorical\n", - "\n", - "from skimage import io, transform, util\n", "import os\n", "\n", - "import matplotlib.pyplot as plt # plotting\n", - "import numpy as np # linear algebra" + "import matplotlib.pyplot as plt # plotting\n", + "import numpy as np # linear algebra\n", + "from skimage import io, transform, util\n", + "from tensorflow.keras import layers, models\n", + "from tensorflow.keras.datasets import mnist # mnist dataset\n", + "from tensorflow.keras.models import load_model\n", + "from tensorflow.keras.utils import to_categorical" ] }, { @@ -112,8 +110,8 @@ "outputs": [], "source": [ "model = models.Sequential()\n", - "model.add(layers.Dense(512, activation='relu', input_shape=(28 * 28,)))\n", - "model.add(layers.Dense(10, activation='softmax'))" + "model.add(layers.Dense(512, activation=\"relu\", input_shape=(28 * 28,)))\n", + "model.add(layers.Dense(10, activation=\"softmax\"))" ] }, { @@ -136,7 +134,7 @@ "metadata": {}, "outputs": [], "source": [ - "model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])" + "model.compile(optimizer=\"rmsprop\", loss=\"categorical_crossentropy\", metrics=[\"accuracy\"])" ] }, { @@ -153,10 +151,10 @@ "outputs": [], "source": [ "train_images_prepared = train_images.reshape((60000, 28 * 28))\n", - "train_images_prepared = train_images_prepared.astype('float32') / 255\n", + "train_images_prepared = train_images_prepared.astype(\"float32\") / 255\n", "\n", "test_images_prepared = test_images.reshape((10000, 28 * 28))\n", - "test_images_prepared = test_images_prepared.astype('float32') / 255" + "test_images_prepared = test_images_prepared.astype(\"float32\") / 255" ] }, { @@ -230,7 +228,13 @@ } ], "source": [ - "history = model.fit(train_images_partial, train_labels_partial, epochs=10, batch_size=128, validation_data=(train_images_val, train_labels_val))" + "history = model.fit(\n", + " train_images_partial,\n", + " train_labels_partial,\n", + " epochs=10,\n", + " batch_size=128,\n", + " validation_data=(train_images_val, train_labels_val),\n", + ")" ] }, { @@ -247,7 +251,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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", "text/plain": [ "
" ] @@ -259,14 +263,14 @@ } ], "source": [ - "loss = history.history['loss']\n", - "validation_loss = history.history['val_loss']\n", + "loss = history.history[\"loss\"]\n", + "validation_loss = history.history[\"val_loss\"]\n", "epochs = range(1, len(loss) + 1)\n", - "plt.plot(epochs, loss, 'bo', label='Training loss')\n", - "plt.plot(epochs, validation_loss, 'b', label='Validation loss')\n", - "plt.title('Training and validation loss')\n", - "plt.xlabel('Epochs')\n", - "plt.ylabel('Loss')\n", + "plt.plot(epochs, loss, \"bo\", label=\"Training loss\")\n", + "plt.plot(epochs, validation_loss, \"b\", label=\"Validation loss\")\n", + "plt.title(\"Training and validation loss\")\n", + "plt.xlabel(\"Epochs\")\n", + "plt.ylabel(\"Loss\")\n", "plt.legend()\n", "\n", "plt.show()" @@ -286,7 +290,7 @@ "outputs": [ { "data": { - "image/png": "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VQwX8sgjjzB06FCKioo4/vjjgeT5HjfccEPFPgcMGMDy5ctZvnw5hxxyCOeeey4DBgxgxYoV1X4+gNmzZ/OJT3yCoqIihg8fzttvv80xxxxTaej1o446itLS0tr/UPXg+yzMrMHttddeDB8+nIcffpixY8cyffp0zjzzTCTRunVr7r//fjp06MDatWs5/PDDOeWUU2p8RvStt95K27ZtWbx4MfPnz2fo0KEV6yZNmsRee+3F1q1bOf7445k/fz6XX345P/3pT5k5cyZdu3attK85c+Zw++23869//YuIYMSIEYwcOZLOnTvz4osvctddd/HrX/+aM888k/vuu49zzjmn0vZHHXUUzz77LJK47bbb+PGPf8yNN97I9773PTp27MiCBcmoRBs2bKCsrIyLL76YWbNm0adPn0rjPNXkxRdf5M477+Twww+v8fP17duXs846i7vvvpthw4bx1ltv0aZNG77whS9wxx13cNNNN7F06VLef/99ioqK6vV3q42ThdluLv3x3OjKm6LKk8VvfvMbIGli+da3vsWsWbNo1qwZq1at4vXXX2efffapdj+zZs3i8ssvB2DQoEEMGjSoYt0999zD5MmT2bJlC2vWrGHRokWV1lf11FNPceqpp1aMADtu3Dj+8Y9/cMopp9CnTx8GDx4M1DwM+sqVKznrrLNYs2YNH3zwAX369AHg8ccfr9Ts1rlzZx566CGOOeaYijJ1Gca8V69eFYmips8niX333Zdhw4YB0KFDBwDOOOMMvve97/GTn/yEKVOmcP7552c9Xn00+Waohn72sJklxo4dy4wZM5g7dy6bNm3isMMOA5KB+crKypgzZw7z5s2je/fuOzQc+H/+8x9uuOEGZsyYwfz58znppJN2aD/lyoc3h5qHOL/sssu49NJLWbBgAb/61a92ehhzqDyUeeYw5vX9fG3btmX06NH86U9/4p577mFCA48G2aSTRfmzh195BSKS94kTnTDMGkK7du049thjufDCCyt1bJcPz92yZUtmzpzJK6+8Uut+jjnmGH7/+98D8PzzzzN//nwgGd58zz33pGPHjrz++us8/PDDFdu0b9+et99+e7t9HX300TzwwANs2rSJd999l/vvv5+jj677o3I2btxIjx7JAz/vvPPOiuWjR4/mlltuqZjfsGEDhx9+OLNmzeI///kPUHkY87lz5wIw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\n", + "image/png": "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VQwX8sgjjzB06FCKioo4/vjjgeT5HjfccEPFPgcMGMDy5ctZvnw5hxxyCOeeey4DBgxgxYoV1X4+gNmzZ/OJT3yCoqIihg8fzttvv80xxxxTaej1o446itLS0tr/UPXg+yzMrMHttddeDB8+nIcffpixY8cyffp0zjzzTCTRunVr7r//fjp06MDatWs5/PDDOeWUU2p8RvStt95K27ZtWbx4MfPnz2fo0KEV6yZNmsRee+3F1q1bOf7445k/fz6XX345P/3pT5k5cyZdu3attK85c+Zw++23869//YuIYMSIEYwcOZLOnTvz4osvctddd/HrX/+aM888k/vuu49zzjmn0vZHHXUUzz77LJK47bbb+PGPf8yNN97I9773PTp27MiCBcmoRBs2bKCsrIyLL76YWbNm0adPn0rjPNXkxRdf5M477+Twww+v8fP17duXs846i7vvvpthw4bx1ltv0aZNG77whS9wxx13cNNNN7F06VLef/99ioqK6vV3q42ThdluLv3x3OjKm6LKk8VvfvMbIGli+da3vsWsWbNo1qwZq1at4vXXX2efffapdj+zZs3i8ssvB2DQoEEMGjSoYt0999zD5MmT2bJlC2vWrGHRokWV1lf11FNPceqpp1aMADtu3Dj+8Y9/cMopp9CnTx8GDx4M1DwM+sqVKznrrLNYs2YNH3zwAX369AHg8ccfr9Ts1rlzZx566CGOOeaYijJ1Gca8V69eFYmips8niX333Zdhw4YB0KFDBwDOOOMMvve97/GTn/yEKVOmcP7552c9Xn00+Waohn72sJklxo4dy4wZM5g7dy6bNm3isMMOA5KB+crKypgzZw7z5s2je/fuOzQc+H/+8x9uuOEGZsyYwfz58znppJN2aD/lyoc3h5qHOL/sssu49NJLWbBgAb/61a92ehhzqDyUeeYw5vX9fG3btmX06NH86U9/4p577mFCA48G2aSTRfmzh195BSKS94kTnTDMGkK7du049thjufDCCyt1bJcPz92yZUtmzpzJK6+8Uut+jjnmGH7/+98D8PzzzzN//nwgGd58zz33pGPHjrz++us8/PDDFdu0b9+et99+e7t9HX300TzwwANs2rSJd999l/vvv5+jj677o3I2btxIjx7JAz/vvPPOiuWjR4/mlltuqZjfsGEDhx9+OLNmzeI///kPUHkY87lz5wIw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", "text/plain": [ "
" ] @@ -298,14 +302,14 @@ } ], "source": [ - "acc = history.history['acc']\n", - "validation_acc = history.history['val_acc']\n", + "acc = history.history[\"acc\"]\n", + "validation_acc = history.history[\"val_acc\"]\n", "\n", - "plt.plot(epochs, acc, 'bo', label='Training accuracy')\n", - "plt.plot(epochs, validation_acc, 'b', label='Validation accuracy')\n", - "plt.title('Training and validation accuracy')\n", - "plt.xlabel('Epochs')\n", - "plt.ylabel('Loss')\n", + "plt.plot(epochs, acc, \"bo\", label=\"Training accuracy\")\n", + "plt.plot(epochs, validation_acc, \"b\", label=\"Validation accuracy\")\n", + "plt.title(\"Training and validation accuracy\")\n", + "plt.xlabel(\"Epochs\")\n", + "plt.ylabel(\"Loss\")\n", "plt.legend()\n", "\n", "plt.show()" @@ -349,9 +353,9 @@ ], "source": [ "model = models.Sequential()\n", - "model.add(layers.Dense(512, activation='relu', input_shape=(28 * 28,)))\n", - "model.add(layers.Dense(10, activation='softmax'))\n", - "model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])\n", + "model.add(layers.Dense(512, activation=\"relu\", input_shape=(28 * 28,)))\n", + "model.add(layers.Dense(10, activation=\"softmax\"))\n", + "model.compile(optimizer=\"rmsprop\", loss=\"categorical_crossentropy\", metrics=[\"accuracy\"])\n", "history = model.fit(train_images_prepared, train_labels_one_hot, epochs=5, batch_size=128)" ] }, @@ -368,9 +372,9 @@ "metadata": {}, "outputs": [], "source": [ - "model.save('app/mnist_model.h5')\n", + "model.save(\"app/mnist_model.h5\")\n", "del model\n", - "model = load_model('app/mnist_model.h5')" + "model = load_model(\"app/mnist_model.h5\")" ] }, { @@ -419,8 +423,8 @@ } ], "source": [ - "print('Final loss: {0}'.format(final_loss))\n", - "print('Final accuracy: {0}'.format(final_acc))" + "print(f\"Final loss: {final_loss}\")\n", + "print(f\"Final accuracy: {final_acc}\")" ] }, { @@ -444,7 +448,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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", "text/plain": [ "
" ] @@ -522,11 +526,11 @@ "outputs": [], "source": [ "APP_ROOT = os.path.dirname(os.path.abspath(\"Deep Learning MNIST prediction model with Keras.ipynb\"))\n", - "APP_STATIC = os.path.join(APP_ROOT, 'app/static')\n", + "APP_STATIC = os.path.join(APP_ROOT, \"app/static\")\n", "\n", "filename = \"4.jpg\"\n", "path_to_file = os.path.join(APP_STATIC, filename)\n", - "image = io.imread(path_to_file, as_gray=True) # read as grayscale" + "image = io.imread(path_to_file, as_gray=True) # read as grayscale" ] }, { @@ -539,11 +543,11 @@ " # invert grayscale image\n", " image = util.invert(image)\n", " # resize image and prepare it for model\n", - " image = transform.resize(image, (28,28), anti_aliasing=True, mode=\"constant\")\n", + " image = transform.resize(image, (28, 28), anti_aliasing=True, mode=\"constant\")\n", " image = np.array(image)\n", " plt.imshow(image, cmap=plt.cm.binary)\n", " plt.show()\n", - " image = image.reshape((1,28*28))\n", + " image = image.reshape((1, 28 * 28))\n", "\n", " return image" ] @@ -555,7 +559,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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", "text/plain": [ "
" ] @@ -567,7 +571,7 @@ } ], "source": [ - "preprocessed_image=preprocess_image(image)" + "preprocessed_image = preprocess_image(image)" ] }, { diff --git a/app/app/__init__.py b/app/app/__init__.py index 005e9d4..7c3f050 100644 --- a/app/app/__init__.py +++ b/app/app/__init__.py @@ -6,9 +6,9 @@ __copyright__ = "Copyright 2018-2024" +from config import config from flask import Flask, render_template -from config import config from .model import init_model diff --git a/app/app/api.py b/app/app/api.py index a7abea7..be588fd 100644 --- a/app/app/api.py +++ b/app/app/api.py @@ -7,10 +7,11 @@ import io + from flask import Blueprint, jsonify, request from skimage.io import imread -from .model import current_app, np, preprocess_image +from .model import current_app, np, preprocess_image api = Blueprint("api", __name__) @@ -21,31 +22,30 @@ def predict(): result = {"success": False} # ensure an image was properly uploaded to our endpoint - if request.method == "POST": - if request.files.get("file"): - # read image as grayscale - image_req = request.files["file"].read() - request.files["file"].close() - image = imread(io.BytesIO(image_req), as_gray=True) + if request.method == "POST" and request.files.get("file"): + # read image as grayscale + image_req = request.files["file"].read() + request.files["file"].close() + image = imread(io.BytesIO(image_req), as_gray=True) - # preprocess the image for model - preprocessed_image = preprocess_image(image) + # preprocess the image for model + preprocessed_image = preprocess_image(image) - # classify the input image generating a list of predictions - model = current_app.config["model"] - preds = model.predict(preprocessed_image) + # classify the input image generating a list of predictions + model = current_app.config["model"] + preds = model.predict(preprocessed_image) - # add generated predictions to result - result["predictions"] = [] + # add generated predictions to result + result["predictions"] = [] - for i in range(0, 10): - pred = {"label": str(i), "probability": str(preds[0][i])} - result["predictions"].append(pred) + for i in range(0, 10): + pred = {"label": str(i), "probability": str(preds[0][i])} + result["predictions"].append(pred) - result["most_probable_label"] = str(np.argmax(preds[0])) + result["most_probable_label"] = str(np.argmax(preds[0])) - # indicate that the request was a success - result["success"] = True + # indicate that the request was a success + result["success"] = True # return result dictionary as JSON response to client return jsonify(result) diff --git a/app/app/model.py b/app/app/model.py index 400597c..1b204b0 100644 --- a/app/app/model.py +++ b/app/app/model.py @@ -6,11 +6,10 @@ __copyright__ = "Copyright 2018-2024" -from tensorflow.keras.models import load_model -from skimage import transform, util import numpy as np - from flask import current_app +from skimage import transform, util +from tensorflow.keras.models import load_model def init_model(): diff --git a/app/tests/conftest.py b/app/tests/conftest.py index c4ce0f7..6a7b69f 100644 --- a/app/tests/conftest.py +++ b/app/tests/conftest.py @@ -6,9 +6,10 @@ __copyright__ = "Copyright 2018-2024" -from app import create_app import pytest +from app import create_app + @pytest.fixture def app(): diff --git a/app/tests/test_app.py b/app/tests/test_app.py index abb4d4f..6cdbfe8 100644 --- a/app/tests/test_app.py +++ b/app/tests/test_app.py @@ -22,29 +22,29 @@ def test_api(client): IMAGE_PATH = "../app/static/4.jpg" # create payload with image for request - image = open(IMAGE_PATH, "rb") - payload = {"file": image} - response = client.post(SERVER_URL, data=payload) - - # check response - assert response.status_code == 200 - - # JSON format - try: - json_response = json.loads(response.data.decode("utf8")) - except ValueError as e: - print(e) - assert False - - # successful - if json_response["success"]: - # most probable label - print(json_response["most_probable_label"]) - # predictions - for dic in json_response["predictions"]: - print(f"label {dic['label']} probability: {dic['probability']}") - - assert json_response["most_probable_label"] == "4" - # failed - else: - assert False + with open(IMAGE_PATH, "rb") as image: + payload = {"file": image} + response = client.post(SERVER_URL, data=payload) + + # check response + assert response.status_code == 200 + + # JSON format + try: + json_response = json.loads(response.data.decode("utf8")) + except ValueError as e: + print(e) + exit(1) + + # successful + if json_response["success"]: + # most probable label + print(json_response["most_probable_label"]) + # predictions + for dic in json_response["predictions"]: + print(f"label {dic['label']} probability: {dic['probability']}") + + assert json_response["most_probable_label"] == "4" + # failed + else: + raise AssertionError()