Skip to content

Commit

Permalink
input images are stored locally
Browse files Browse the repository at this point in the history
  • Loading branch information
arun477 committed Sep 16, 2023
1 parent 9c06ef3 commit 9490409
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 22 deletions.
86 changes: 84 additions & 2 deletions mnist_classifier.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@
},
{
"cell_type": "code",
"execution_count": 59,
"execution_count": 60,
"metadata": {
"tags": [
"exclude"
Expand All @@ -547,14 +547,96 @@
"name": "stdout",
"output_type": "stream",
"text": [
"[NbConvertApp] Converting notebook mnist_classifier.ipynb to script\n"
"[NbConvertApp] Converting notebook mnist_classifier.ipynb to script\n",
"[NbConvertApp] Writing 3568 bytes to mnist_classifier.py\n"
]
}
],
"source": [
"!jupyter nbconvert --to script --TagRemovePreprocessor.remove_cell_tags=\"exclude\" --TemplateExporter.exclude_input_prompt=True mnist_classifier.ipynb\n"
]
},
{
"cell_type": "code",
"execution_count": 78,
"metadata": {
"tags": [
"exclude"
]
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tensor(0.1046) tensor(1.) tensor(0.) tensor(0.3062)\n",
"tensor(0.1435) tensor(1.) tensor(0.) tensor(0.3220)\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAI4AAACOCAYAAADn/TAIAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFjklEQVR4nO3dz6tUdRjH8fcn8wfZJsvCVNKFRK4KJItaBCHd3Ngm0CBcCG4KClqk9Q+4atdGSHQRRlRgC0FKiggilJDS5KoF5k3JhCBXofC4mENM0713zjxn5syZOZ8XXGbOd+5wvosPz/me78x9riICs0HdNe4J2GRycCzFwbEUB8dSHBxLcXAspVJwJM1ImpV0SdK+YU3Kmk/ZfRxJS4ALwDZgDjgF7IqIn4c3PWuquyu890ngUkT8CiDpI2AHsGBwlml5rGBlhVNa3W7y142IWN07XiU4a4ErXcdzwNbF3rCClWzV8xVOaXX7Mj65PN94leBonrH/Xfck7QX2AqzgngqnsyapsjieA9Z3Ha8Drvb+UkQcjIgtEbFlKcsrnM6apErFOQVskrQR+B3YCbwylFlNmRNXzyz6+gsPP17LPIYpHZyIuC3pdeAEsAQ4FBHnhjYza7QqFYeIOA4cH9JcbIJ459hSKlUcm1+/Nc00cMWxFAfHUhwcS/EaZwwmcd+mlyuOpTg4luLgWIrXOEMwjZ9F9eOKYykOjqX4UpXUho8VFuOKYykOjqU4OJbiNU5Jg6xppvH2u5crjqU4OJbi4FiK1zhD0IY1TS9XHEtxcCzFwbEUr3EW0MavSgzCFcdSHBxLcXAsxWucQtu/XzMoVxxL6RscSYckXZd0tmtslaQvJF0sHu8b7TStacpUnMPATM/YPuBkRGwCThbH1iJ91zgR8Y2kDT3DO4DniudHgK+Bt4c5saZp+75Nr+wa56GIuAZQPD44vCnZJBj5XZXb1U6nbMX5Q9IagOLx+kK/6Ha10ykbnM+B3cXz3cCx4UzHJkWZ2/GjwHfAo5LmJO0BDgDbJF2k809ADox2mtY0Ze6qdi3wkv8pQ4t559hS/FlVUtv/zsoVx1IcHEtxcCzFa5ySqnxfp/e907DmccWxFAfHUnypGoLeS08bvobqimMpDo6lODiW4jVO0mK31P3WPNNwe+6KYykOjqU4OJbi4FiKg2MpDo6lODiW4n2ckiZxr2WUXHEsxcGxFAfHUhwcS3FwLMXBsRQHx1K8j1PwPs1gXHEspUx/nPWSvpJ0XtI5SW8U425Z22JlKs5t4K2IeAx4CnhN0mbcsrbV+gYnIq5FxA/F85vAeWAtnZa1R4pfOwK8NKI5WgMNtMYp+h0/AXyPW9a2WungSLoX+BR4MyL+HuB9eyWdlnT6Fv9k5mgNVCo4kpbSCc2HEfFZMVyqZa3b1U6nMndVAj4AzkfEe10vuWVti5XZAHwGeBX4SdKZYuwdOi1qPy7a1/4GvDySGVojlWlX+y2gBV52y9qW8s6xpTg4luLgWIqDYykOjqU4OJbi4FiKg2Mp/uroCLhdrdkCHBxLcXAsxWucMZiGP8VxxbEUB8dSHBxL8RpnCPrt20zDmqaXK46lODiW4uBYitc4SW34PGoxrjiW4uBYioNjKYqI+k4m/QlcBh4AbtR24sF4bv/1SESs7h2sNTj/nlQ6HRFbaj9xCZ5bOb5UWYqDYynjCs7BMZ23DM+thLGscWzy+VJlKbUGR9KMpFlJlySNtb2tpEOSrks62zXWiN7Nk9BburbgSFoCvA+8CGwGdhX9ksflMDDTM9aU3s3N7y0dEbX8AE8DJ7qO9wP76zr/AnPaAJztOp4F1hTP1wCz45xf17yOAduaNL86L1VrgStdx3PFWJM0rndzU3tL1xmc+foI+pZuEdne0nWoMzhzwPqu43XA1RrPX0ap3s11qNJbug51BucUsEnSRknLgJ10eiU3SSN6N09Eb+maF3nbgQvAL8C7Y15wHgWuAbfoVMM9wP107lYuFo+rxjS3Z+lcxn8EzhQ/25syv4jwzrHleOfYUhwcS3FwLMXBsRQHx1IcHEtxcCzFwbGUO+5QVpdhOxaLAAAAAElFTkSuQmCC",
"text/plain": [
"<Figure size 144x144 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"from PIL import Image\n",
"import numpy as np\n",
"import glob\n",
"import os\n",
"png_files = glob.glob(os.path.join('./uploads', '*png'))\n",
"img = png_files[1]\n",
"image = Image.open(img)\n",
"image = TF.to_tensor(image).permute(1, 2, 0)\n",
"print(image.mean(), image.max(), image.min(), image.std())\n",
"print(xb[0].mean(), xb[0].max(), xb[0].min(), xb[0].std())\n",
"plt.imshow(image);\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 75,
"metadata": {
"tags": [
"exclude"
]
},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x7ff734b20fd0>"
]
},
"execution_count": 75,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAI4AAACOCAYAAADn/TAIAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAAAI70lEQVR4nO3df2yU9R0H8PenpaURcR2MKhRSmrQguoUxGwpO0f1gqYyMzc1Ig8RtZGwB58RlQZmzJiabmWZsjE3jImEowS2gwzmMkc7JfhiBTTYQrDAIcqWzdmOuwlZ77Wd/9Gjv89Ber5/79dz1/UrI3ee55+l9Y95+73vPPfc5UVUQjVRRrgdA+YnBIRcGh1wYHHJhcMiFwSGXlIIjIg0i0iIix0TkrnQNisJPvOdxRKQYwBsAFgKIANgHoFFVD6dveBRWY1I4di6AY6p6HABE5EkASwAMGZxSGatlGJfCU1K2deJMh6pOCm5PJTiVAE7F1REA9YkOKMM41MsnUnhKyrbduv3kYNtTCY4Msu2C1z0RWQlgJQCU4aIUno7CJJXFcQTAtLh6KoDTwZ1U9VFVrVPVuhKMTeHpKExSCc4+ALUiUi0ipQCWAngmPcOisHO/VKlqVERuA/A8gGIAm1T1tbSNjEItlTUOVHUXgF1pGgvlEZ45JhcGh1wYHHJhcMiFwSEXBodcGBxyYXDIhcEhFwaHXBgccmFwyIXBIRcGh1wYHHJhcMglpQu5aHAdX51v6s6PnTX1znmPmHpWqb2If853V5m6YuOf0ji69OCMQy4MDrkwOOTCNU6Szt1ov6Ta8aHi/vvLP99sHvtS+YOmrii2a5jewPfLurXH1Gu/vs3UW5o/aQfT+pb9e+fOmVqjUWQaZxxyYXDIhcEhF65xYsZMrTR1ZOMlpt5T90NTXywD65TeQK+F585VmLpp/RcTPvfZBe+aekPdL+xYbrBdRn67ZrOp5+25zdQ1tx7sv5+p9Q5nHHJhcMiFwSEXdw9Aj0tkgoalI5dePdvU7933jqmbr3wq4fGvd3f137/xiTvNYzWPvGnqaKQ14d8qKisz9fjdtt3dtuoXEh7/z97/mnrZLQNrnqKXXk147HB26/Y/q2pdcDtnHHIZNjgisklE2kXkUNy2CSLygogcjd2+P7PDpLBJZsbZDKAhsO0uAM2qWgugOVbTKDLseRxV3SMi0wOblwC4Pnb/5wB+B2BtOgeWbsE1zdrHnzD1grL3AkfY3phz/7LU1Jd9beDcy/TWl81jw505kbH2s6rWJ6tN/Wr1VlMHzxO19dg1zU33fMvU5S/Z8WSCd41zqaq2AUDstmKY/anAZPzMMdvVFibvjPOWiEwGgNht+1A7sl1tYfLOOM8AuBXAA7HbnWkbUYa019lzIxeuaaw1bfb6m4qbI6aOBq6BiVc8cYKpOxbPNPVDTQ+bev7Y4DXFdn21t8vWX95q1zTTt2R+TROUzNvxbQBeBjBTRCIisgJ9gVkoIkfR9yMgD2R2mBQ2ybyrahzioXCcAqac4JljcinY63HGVE0z9YY7fjqi4/e2V5m6e/kFv7zT71/13aa+s95+trSqfLepg+dlgtp77PqpacXtpp7+YvbXNEGccciFwSEXBodcCnaNoxfZa1zGSfC8TTES+f1se90v7EddKIo71zLcmmXw34Qb2nWB8zTVIVjTBHHGIRcGh1wK9qWq58hRUzedXGLqnbW/SenvP955Wf/9//WWmMe+8r5Twd2Nd3u7TH3V02tMPfP+v5q61zPADOOMQy4MDrkwOORSsGucoO6P20uGPl08L+H+ZxqvMvXEX9nfqe25fOAjiXfus5dyrphtvx4TidrHm04vMnXt7a+YOoxrmiDOOOTC4JALg0Muo2aNg17bLk0DdVB54HJMqZxi6mVbnuu/3zjetlYL+k7rYlO/ffW/E+6fDzjjkAuDQy4MDrmMnjVOij747GlTLxsff17IXjZx8/FPmbrz2o5MDStnOOOQC4NDLgwOuXCNc16RvZT0+PfmmvrpST8KHDDwn65LbWOTll/PMPUUcI1DBIDBIScGh1y4xonpaviIqQ/fsjGwh10DxX8l5spnbUv8Gd8P308hphtnHHJJpj/ONBF5UUSOiMhrIvKN2Ha2rB3FkplxogC+qaqzAMwDsFpErgBb1o5qyTRWagNwvsNop4gcAVCJPGxZG+/sF2yrtp89tN7URbBfIQ6qv3d1//1ZT71uHkt8pU9hGNEaJ9bveA6AV8CWtaNa0sERkYsB7ABwh6r+ZwTHrRSR/SKyvxtdwx9AeSGp4IhICfpCs1VVz/+sSlIta9mutjANu8YREQHwGIAjqvqDuIfyqmVt7zUfNvX8dXtNXVNiQx1sXbIqssDUl+460X8/euZMGkaYX5I5AfhRAMsBHBSRA7Ft69AXmF/G2te+CeCmjIyQQimZd1V/wNCdgdiydpTimWNyKdjPqnqut5893fPYZlNfWxb8cSA7qV6+dbWpa+4/ZOrezn+kNL58xxmHXBgccmFwyKVg1jhSUmrqGQ8eNvWFaxrrj132/6EZ60+YOtrZmcLoCg9nHHJhcMilYF6qOj87x9Q/nvLwEHv22XHWXne2YZ39ld9xbba9GlmccciFwSEXBodcCmaNU77ffgTwuWO2JeyOGtuC/94DnzF11XauaUaCMw65MDjkwuCQS8GscaInTtr6Ovv4YtgW+1U4mOkhFTTOOOTC4JALg0MuDA65MDjkwuCQC4NDLqKqw++VricTeRvASQAfAELbw5Vjs6pUdVJwY1aD0/+kIvtVtS7rT5wEji05fKkiFwaHXHIVnEdz9LzJ4NiSkJM1DuU/vlSRS1aDIyINItIiIsdEJKftbUVkk4i0i8ihuG2h6N2cD72lsxYcESkG8BMANwC4AkBjrF9yrmwG0BDYFpbezeHvLa2qWfkHYD6A5+PquwHcna3nH2JM0wEciqtbAEyO3Z8MoCWX44sb104AC8M0vmy+VFUCOBVXR2LbwiR0vZvD2ls6m8EZrI8g39Il4O0tnQ3ZDE4EwLS4eiqA00PsmytJ9W7OhlR6S2dDNoOzD0CtiFSLSCmApejrlRwm53s3Azns3ZxEb2kg172ls7zIWwTgDQB/B/DtHC84t6Hvx0260TcbrgAwEX3vVo7GbifkaGzXoO9l/G8ADsT+LQrL+FSVZ47Jh2eOyYXBIRcGh1wYHHJhcMiFwSEXBodcGBxy+T+hXTkLJRIRbwAAAABJRU5ErkJggg==",
"text/plain": [
"<Figure size 144x144 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plt.imshow(xb[0].permute(1,2,0))"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down
23 changes: 17 additions & 6 deletions mnist_classifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def conv(ni, nf, ks=3, s=2, act=nn.ReLU, norm=None):

def _conv_block(ni, nf, ks=3, s=2, act=nn.ReLU, norm=None):
return nn.Sequential(
conv(ni, nf, ks=ks, s=1, norm=norm, act=act),
conv(ni, nf, ks=ks, s=1, norm=None, act=act),
conv(nf, nf, ks=ks, s=s, norm=norm, act=act),
)

Expand Down Expand Up @@ -77,15 +77,26 @@ def forward(self, x):

def cnn_classifier():
return nn.Sequential(
ResBlock(1, 8,),
ResBlock(8, 16, ),
ResBlock(16, 32,),
ResBlock(32, 64, ),
ResBlock(64, 64,),
ResBlock(1, 8, norm=nn.LayerNorm([8, 14, 14])),
ResBlock(8, 16, norm=nn.LayerNorm([16, 7, 7])),
ResBlock(16, 32, norm=nn.LayerNorm([32, 4, 4])),
ResBlock(32, 64, norm=nn.LayerNorm([64, 2, 2])),
ResBlock(64, 64, norm=nn.LayerNorm([64, 1, 1])),
conv(64, 10, act=False),
nn.Flatten(),
)

# def cnn_classifier():
# return nn.Sequential(
# ResBlock(1, 8,),
# ResBlock(8, 16, ),
# ResBlock(16, 32,),
# ResBlock(32, 64, ),
# ResBlock(64, 64,),
# conv(64, 10, act=False),
# nn.Flatten(),
# )


def kaiming_init(m):
if isinstance(m, (nn.Conv1d, nn.Conv2d, nn.Conv3d)):
Expand Down
38 changes: 24 additions & 14 deletions server.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from fastapi import FastAPI, File, UploadFile
import io
from fastapi import FastAPI, UploadFile
from PIL import Image
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
from pathlib import Path
import torchvision.transforms as transforms
import mnist_classifier
import torch
from pathlib import Path
import datetime
import numpy as np

app = FastAPI()

Expand All @@ -15,20 +16,29 @@
async def root():
return FileResponse("static/index.html")

def process_image(file: UploadFile):
image_bytes = file.file.read()
pil_image = Image.open(io.BytesIO(image_bytes))
transform = transforms.Compose([
transforms.Resize((28, 28)),
transforms.Grayscale(num_output_channels=1),
transforms.ToTensor(),
])
tensor_image = transform(pil_image)
return tensor_image
upload_dir = Path("uploads")
upload_dir.mkdir(parents=True, exist_ok=True)

def process_image(file):
image = Image.open(file.file)
image = image.resize((28, 28)) # Resize to MNIST image size
image = image.convert("L") # Convert to grayscale
raw_image = image
image = np.array(image)
image = image / 255.0 # Normalize pixel values
return torch.from_numpy(image).float().reshape(1, 28, 28), raw_image

def store_img(image):
timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
unique_filename = f"{timestamp}.png"
output_path = upload_dir / unique_filename
image.save(output_path)

@app.post("/predict")
async def predict(image: UploadFile):
tensor_image = process_image(image)
tensor_image, raw_image = process_image(image)
print(tensor_image.shape)
prediction = mnist_classifier.predict(tensor_image)
store_img(raw_image)
return {"prediction": prediction}

Binary file added uploads/20230916173519.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added uploads/20230916173549.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 9490409

Please sign in to comment.