hydraadra112 commited on
Commit
26eaf37
Β·
1 Parent(s): 672dd30

create streamlit app with trained model

Browse files
src/logs/run_20250522_230935/output.jpg DELETED
Binary file (47.1 kB)
 
src/logs/run_20250522_230935/p1_e5_best_model.pth DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:d271617a9f958ec3b9b614a1d920695b564c9ed86514d1679f053ea4de7a6a4c
3
- size 9189835
 
 
 
 
src/logs/run_20250522_230935/p2_e6_best_model.pth DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:2e2c292d5b72b54983ff819f476a2b891ad3e3a9c156cb8d1ef2b972ce4f7cc3
3
- size 9189835
 
 
 
 
src/logs/run_20250522_230935/p2_e7_best_model.pth DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:d3c1a2cac7bd19542439919716124b7b34dfe70d4beaca42dd95bc187b26c50a
3
- size 9189835
 
 
 
 
src/logs/run_20250522_230935/p2_e8_best_model.pth DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:c24995e93cd70e7f7982334ccff3464200a4310a85987be17e2d5259f5832296
3
- size 9189835
 
 
 
 
src/logs/run_20250522_230935/p2_e9_best_model.pth DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:49e9c41f1d018fd6ca68b24d2647914d42d2107df050b3d681793d1a3e88d93d
3
- size 9189835
 
 
 
 
src/logs/run_20250522_230935/training_log.csv DELETED
@@ -1,21 +0,0 @@
1
- epoch,phase,train_loss,train_acc,val_loss,val_acc,lr
2
- 1,phase1,2.303510929922989,0.1406423034330011,2.318585231240872,0.11504424778761062,0.0003
3
- 2,phase1,2.2458471942977654,0.15282392026578073,2.2849610632499764,0.14601769911504425,0.0003
4
- 3,phase1,2.162792288715789,0.20930232558139536,2.246608354349052,0.22566371681415928,0.0003
5
- 4,phase1,2.1265761725530274,0.2502768549280177,2.1911888143657583,0.23008849557522124,0.0003
6
- 5,phase1,2.088300267195253,0.26799557032115173,2.153209074408607,0.26548672566371684,0.0003
7
- 6,phase2,1.9990032737041232,0.3078626799557032,1.846995581567815,0.34513274336283184,0.0003
8
- 7,phase2,1.577180798927679,0.4739756367663344,1.831763710595865,0.35398230088495575,0.0003
9
- 8,phase2,1.294860844068221,0.574750830564784,1.7726619823844032,0.40707964601769914,0.0003
10
- 9,phase2,0.9931818792722286,0.6699889258028793,1.832471836984685,0.41150442477876104,0.0003
11
- 10,phase2,0.7694948211988869,0.7530454042081949,1.8003454419363916,0.4778761061946903,0.0003
12
- 11,phase2,0.6243530942224057,0.8006644518272426,1.9367720880339632,0.42920353982300885,0.0003
13
- 12,phase2,0.5367502292261304,0.8349944629014396,1.8948295781042723,0.4557522123893805,2.9999999999999997e-05
14
- 13,phase2,0.35034318131333836,0.9080841638981174,1.7645389168663363,0.46017699115044247,2.9999999999999997e-05
15
- 14,phase2,0.2635347050091753,0.937984496124031,1.751677575364577,0.4911504424778761,2.9999999999999997e-05
16
- 15,phase2,0.22511727680531582,0.9534883720930233,1.726252584594541,0.5221238938053098,2.9999999999999997e-05
17
- 16,phase2,0.19456648125270937,0.9601328903654485,1.757449639582001,0.4778761061946903,2.9999999999999997e-05
18
- 17,phase2,0.18161942601071904,0.9700996677740864,1.7264832026135606,0.4911504424778761,2.9999999999999997e-05
19
- 18,phase2,0.14499887035270598,0.9778516057585825,1.7434524171120298,0.4778761061946903,2.9999999999999997e-05
20
- 19,phase2,0.14208385011682478,0.9745293466223699,1.7163434105109325,0.4911504424778761,2.9999999999999997e-05
21
- 20,phase2,0.14279807643636913,0.9712070874861573,1.7629580595324525,0.5265486725663717,2.9999999999999997e-05
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/modelOps.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from torchvision import models, transforms
3
+ import torch
4
+ from torch import nn
5
+ from PIL import Image
6
+ from pathlib import Path
7
+
8
+ # 1. Load Model
9
+ @st.cache_resource
10
+ def load_model(MODEL_PATH: Path = "src/outputs/p2_e29_best_model.pth", device: str = "cpu"):
11
+ model = models.mobilenet_v2(pretrained=True)
12
+ model.classifier[1] = nn.Linear(model.classifier[1].in_features, 10)
13
+
14
+ state_dict = torch.load(MODEL_PATH, map_location=device)
15
+ model.load_state_dict(state_dict)
16
+ model.eval()
17
+ model.to(device)
18
+
19
+ return model
20
+
21
+ # 2. Preprocessing pipeline (match training)
22
+ def preprocess_image(image: Image.Image):
23
+ transform = transforms.Compose([
24
+ transforms.Grayscale(num_output_channels=3),
25
+ transforms.Resize((224, 224)),
26
+ transforms.ToTensor(),
27
+ transforms.Normalize(mean=[0.485, 0.456, 0.406],
28
+ std=[0.229, 0.224, 0.225])
29
+ ])
30
+ return transform(image).unsqueeze(0)
31
+
32
+ def predict_class(input_tensor, model):
33
+ """ Attempts to predict """
34
+ with torch.no_grad():
35
+ logits = model(input_tensor)
36
+ predicted_class = torch.argmax(logits, dim=1).item()
37
+ confidence = torch.softmax(logits, dim=1)[0, predicted_class].item()
38
+
39
+ return predicted_class, confidence
40
+
41
+
src/model_dev.ipynb DELETED
The diff for this file is too large to render. See raw diff
 
src/notebooks/model_dev.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
src/outputs/output.jpg ADDED
src/{logs/run_20250522_230935/p2_e10_best_model.pth β†’ outputs/p1_e11_best_model.pth} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:1c63058cb415bddf60b97185440ec69ec82a9599ac24fa3ab0d0eab4e9d17417
3
  size 9190155
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:84bddb281c20611bc07d98292816888f85004e80a9fe61243b7827826e456783
3
  size 9190155
src/{logs/run_20250522_230935/p2_e14_best_model.pth β†’ outputs/p1_e12_best_model.pth} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:1370ab084cd51dc07750ebadb37b91ad3ba56788b67abc577d9a4fbd596d631b
3
  size 9190155
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c412d32eedd87a20cf6dad8aee6da5c8210ac9ac56ea22ad3cd94d5984804dd4
3
  size 9190155
src/{logs/run_20250522_230935 β†’ outputs}/p1_e1_best_model.pth RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:161dfa7c056b458cf7475db484df5405fcde5f80389510f972b4708977720dae
3
  size 9189835
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e35ef5950512e9dad1d7339ddbfdb11076c3e65b1acd4dfa6356118a9d7c76ec
3
  size 9189835
src/{logs/run_20250522_230935/p2_e15_best_model.pth β†’ outputs/p1_e20_best_model.pth} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:c19c86f6db5419f76af139eb51b29cf09ef5a90b74fb4f8d197c04918fc680a2
3
  size 9190155
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d94eedda1bba3649681cf1623bf4d6d41081be504d8c26e62c7e87c96370a361
3
  size 9190155
src/{logs/run_20250522_230935 β†’ outputs}/p1_e2_best_model.pth RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:490d0e4d708fe344547742751c13fc53541f76813a594ef7566da8caef930204
3
  size 9189835
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a81ebfe275709ef5448aa6be5849b11c8c46776516c9130b5963f7ff5b391199
3
  size 9189835
src/{logs/run_20250522_230935 β†’ outputs}/p1_e3_best_model.pth RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:891218a702c637d0fddebf2b0d2e7dac36cf1a4e3f0a6b7ea2a4ca667b10023e
3
  size 9189835
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:535dd7d6ce7316f38a5efc1f21bbe8de806346a34ba1f31eebc50ba9927b9d70
3
  size 9189835
src/{logs/run_20250522_230935 β†’ outputs}/p1_e4_best_model.pth RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:685d4b6c0975f0e3c71ad0717fe618e7579c3543a117a502f1f63436a41b1dc0
3
  size 9189835
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d0388c05a8343272673e38e80f6b9c9636eb3eb05df01767d0a5f0dc586fdb6e
3
  size 9189835
src/outputs/p1_e6_best_model.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:df7c5d429a6a35e38f6d525d4b5606895b000ddae933ec2a7644c1808e34e817
3
+ size 9189835
src/{logs/run_20250522_230935/p2_e20_best_model.pth β†’ outputs/p2_e21_best_model.pth} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:424326051f606dfc990104cad4d3957f3639d012e125ec0517e97c7201144047
3
  size 9190155
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f202999c743118d37a01a8798ec79f5aba51582430e960a93737cd0c5dbaab95
3
  size 9190155
src/outputs/p2_e26_best_model.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3c6198cf81d0253545906085aafaad84979e444c0d1cffb61b4c6533e45fc2d2
3
+ size 9190155
src/outputs/p2_e27_best_model.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fa8a393873d8f55fef449bd6e404e5c0c7a762fb382c5426b02c2c42eb5f3665
3
+ size 9190155
src/outputs/p2_e29_best_model.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d3bf48aff6a416d27a279d4c6c4f302374134151a0114f60b97048e6362640ea
3
+ size 9190155
src/outputs/training_log.csv ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ epoch,phase,train_loss,train_acc,val_loss,val_acc,lr
2
+ 1,phase1,2.3600678752823128,0.12292358803986711,2.3299416335283127,0.09292035398230089,0.0003
3
+ 2,phase1,2.2662336245459707,0.15282392026578073,2.270022976714953,0.13274336283185842,0.0003
4
+ 3,phase1,2.2153296800678883,0.1937984496124031,2.2079010917022166,0.168141592920354,0.0003
5
+ 4,phase1,2.193896852590449,0.21705426356589147,2.1757551526601335,0.24778761061946902,0.0003
6
+ 5,phase1,2.1592299183077723,0.22591362126245848,2.163129606078156,0.2168141592920354,0.0003
7
+ 6,phase1,2.141071008817434,0.23477297895902546,2.1168759312249916,0.26991150442477874,0.0003
8
+ 7,phase1,2.107089408740385,0.2591362126245847,2.119572213265748,0.2610619469026549,0.0003
9
+ 8,phase1,2.077278288891941,0.2912513842746401,2.1147534783962554,0.24336283185840707,0.0003
10
+ 9,phase1,2.061994478684063,0.2768549280177187,2.1075824805065593,0.25663716814159293,0.0003
11
+ 10,phase1,2.02927204131552,0.292358803986711,2.0814672212685106,0.26991150442477874,0.0003
12
+ 11,phase1,2.020355613392717,0.28903654485049834,2.0687529407771286,0.27876106194690264,0.0003
13
+ 12,phase1,2.003215197972945,0.3067552602436323,2.0582406837328344,0.3185840707964602,0.0003
14
+ 13,phase1,1.977946742164468,0.3067552602436323,2.032191998135727,0.30973451327433627,0.0003
15
+ 14,phase1,1.9707895385334526,0.3388704318936877,2.0281900789885396,0.26991150442477874,0.0003
16
+ 15,phase1,1.9583986852388182,0.3222591362126246,2.0463130832773393,0.29646017699115046,0.0003
17
+ 16,phase1,1.9381876517239862,0.3588039867109635,2.0163620868615344,0.28761061946902655,0.0003
18
+ 17,phase1,1.9135289272728684,0.3444075304540421,2.019399522680097,0.27876106194690264,0.0003
19
+ 18,phase1,1.9271434384459012,0.3377630121816168,2.0202838889265484,0.2831858407079646,0.0003
20
+ 19,phase1,1.9111217321087488,0.34551495016611294,1.9879570344908049,0.2831858407079646,0.0003
21
+ 20,phase1,1.9159050026077236,0.33665559246954596,1.9808736100661015,0.3230088495575221,0.0003
22
+ 21,phase2,1.8704519714099888,0.3687707641196013,1.9086241279028158,0.3584070796460177,1e-05
23
+ 22,phase2,1.8367510330373398,0.38205980066445183,1.9458641816029507,0.3230088495575221,1e-05
24
+ 23,phase2,1.8030515985763482,0.3864894795127353,1.9403255703174962,0.3274336283185841,1e-05
25
+ 24,phase2,1.7982394309799008,0.3953488372093023,1.9076113627020237,0.3495575221238938,1e-05
26
+ 25,phase2,1.7539566732192224,0.4130675526024363,1.9150663445481158,0.34513274336283184,1e-05
27
+ 26,phase2,1.745465459353636,0.4097452934662237,1.9006942204669512,0.37168141592920356,1e-05
28
+ 27,phase2,1.7176943425984346,0.4152823920265781,1.8753417656484959,0.37610619469026546,1e-05
29
+ 28,phase2,1.7060037879716783,0.4374307862679956,1.9120324881730881,0.336283185840708,1e-05
30
+ 29,phase2,1.7053769406422163,0.42857142857142855,1.84919506575154,0.38495575221238937,1e-05
31
+ 30,phase2,1.6627270549634763,0.4363233665559247,1.8010390975833994,0.38495575221238937,1e-05
src/streamlit_app.py CHANGED
@@ -1,40 +1,39 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
  import streamlit as st
5
-
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
 
 
1
  import streamlit as st
2
+ import torch
3
+ from PIL import Image
4
+ from modelOps import load_model, preprocess_image, predict_class
5
+
6
+ def main():
7
+ st.set_page_config(page_title="Breaking Bone", page_icon="🦴")
8
+ st.title("🦴 Breaking Bone")
9
+ st.write("An X-Ray Broken Bone Classifier")
10
+ st.caption("Prepared by: John Manuel Carado")
11
+ st.write("Upload an X-ray image to classify potential fractures.")
12
+
13
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
14
+ model = load_model(device)
15
+
16
+ uploaded_file = st.file_uploader("Upload an X-ray image", type=["jpg", "jpeg", "png"])
17
+
18
+ if uploaded_file:
19
+ image = Image.open(uploaded_file).convert("RGB")
20
+
21
+ col1, col2 = st.columns(2)
22
+
23
+ with col1:
24
+ st.image(image, caption="Uploaded Image")
25
+
26
+ with col2:
27
+ st.subheader("Classification Results")
28
+ with st.spinner("Classifying..."):
29
+ try:
30
+ input_tensor = preprocess_image(image).to(device)
31
+ pred, conf = predict_class(input_tensor, model)
32
+ st.success(f"Predicted Class: **{pred}**")
33
+ st.info(f"Confidence: **{conf:.2%}**")
34
+ except Exception as e:
35
+ st.error(f"An error occurred during classification: {e}")
36
+ st.write("Please ensure the uploaded image is valid and the model is loaded correctly.")
37
+
38
+ if __name__ == "__main__":
39
+ main()