sh0kul commited on
Commit
de38d90
·
1 Parent(s): 57ada90

Fixing model and most of UI

Browse files
models/{model.onnx → model.ckpt} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:1e564444ab1d45dd415b083ae5478368717b508748c6653ba56b457574db619c
3
- size 85128734
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5601b234e608862cde6159ba32bd77a3e5e2b23e41ce488ee778bf4154419090
3
+ size 94409193
pics/Defect/0.jpg CHANGED

Git LFS Details

  • SHA256: 0b420406e25d4d200d20a2f826d5a49f66f4f57ce06c6cfa3c620269a0058067
  • Pointer size: 132 Bytes
  • Size of remote file: 3.24 MB

Git LFS Details

  • SHA256: 7c5cb83d3f6686cfb615d4260a681ee4d4d769a9a9453b502ff78cf3a9528d76
  • Pointer size: 132 Bytes
  • Size of remote file: 4.32 MB
pics/Defect/1.jpg CHANGED

Git LFS Details

  • SHA256: 553893c8b369ecefc133113c67ec49779ba7f741d90bcb7b712d383debe0d044
  • Pointer size: 132 Bytes
  • Size of remote file: 3.43 MB

Git LFS Details

  • SHA256: 1ff71cd793e2f36d7d801ab362a8432c64993ba49b4b004997cf2bb9ff20c976
  • Pointer size: 132 Bytes
  • Size of remote file: 3.12 MB
pics/Defect/2.jpg CHANGED

Git LFS Details

  • SHA256: d6ea9ff9c1f35785dd2bf4da727b386cc93d1f610b0dfb59186a2390fcd8dcba
  • Pointer size: 132 Bytes
  • Size of remote file: 3.16 MB

Git LFS Details

  • SHA256: 553893c8b369ecefc133113c67ec49779ba7f741d90bcb7b712d383debe0d044
  • Pointer size: 132 Bytes
  • Size of remote file: 3.43 MB
pics/Defect/3.jpg CHANGED

Git LFS Details

  • SHA256: 34e4ca6da8800cda78530ee8df5a3a90f1b93a6468e2b16848bf4ecbd9250339
  • Pointer size: 132 Bytes
  • Size of remote file: 3.54 MB

Git LFS Details

  • SHA256: 9dfcae30366d23a779f88449c229d491ea4e44ec3f67399021f767e80b66b64d
  • Pointer size: 132 Bytes
  • Size of remote file: 5.31 MB
pics/Defect/5.jpg CHANGED

Git LFS Details

  • SHA256: 9dfcae30366d23a779f88449c229d491ea4e44ec3f67399021f767e80b66b64d
  • Pointer size: 132 Bytes
  • Size of remote file: 5.31 MB

Git LFS Details

  • SHA256: 34e4ca6da8800cda78530ee8df5a3a90f1b93a6468e2b16848bf4ecbd9250339
  • Pointer size: 132 Bytes
  • Size of remote file: 3.54 MB
pics/Defect/6.jpg CHANGED

Git LFS Details

  • SHA256: e5ac9873cd484451504e041a999fccc0651b0eb0d5e8c1c646bd954443b9b084
  • Pointer size: 132 Bytes
  • Size of remote file: 3.51 MB

Git LFS Details

  • SHA256: 0b420406e25d4d200d20a2f826d5a49f66f4f57ce06c6cfa3c620269a0058067
  • Pointer size: 132 Bytes
  • Size of remote file: 3.24 MB
pics/Defect/7.jpg CHANGED

Git LFS Details

  • SHA256: 7c5cb83d3f6686cfb615d4260a681ee4d4d769a9a9453b502ff78cf3a9528d76
  • Pointer size: 132 Bytes
  • Size of remote file: 4.32 MB

Git LFS Details

  • SHA256: e5ac9873cd484451504e041a999fccc0651b0eb0d5e8c1c646bd954443b9b084
  • Pointer size: 132 Bytes
  • Size of remote file: 3.51 MB
pics/Defect/8.jpg CHANGED

Git LFS Details

  • SHA256: 1ff71cd793e2f36d7d801ab362a8432c64993ba49b4b004997cf2bb9ff20c976
  • Pointer size: 132 Bytes
  • Size of remote file: 3.12 MB

Git LFS Details

  • SHA256: f61ac4f0a670ecea98bdf647dbf609a490ec9de70218e5199f7b91867407be47
  • Pointer size: 132 Bytes
  • Size of remote file: 5.32 MB
pics/Defect/9.jpg CHANGED

Git LFS Details

  • SHA256: f61ac4f0a670ecea98bdf647dbf609a490ec9de70218e5199f7b91867407be47
  • Pointer size: 132 Bytes
  • Size of remote file: 5.32 MB

Git LFS Details

  • SHA256: d6ea9ff9c1f35785dd2bf4da727b386cc93d1f610b0dfb59186a2390fcd8dcba
  • Pointer size: 132 Bytes
  • Size of remote file: 3.16 MB
pics/nDefect/0.jpg CHANGED

Git LFS Details

  • SHA256: 1f9fdc5dd57006c8c50aebba8f93e34d1a4a97391e554f9010cc6a7e19035fe0
  • Pointer size: 132 Bytes
  • Size of remote file: 2.91 MB

Git LFS Details

  • SHA256: ccf4d61c220fbb24a8f7fcb8ba994a5dea3c8d2e5b67410c220095afad78e4e5
  • Pointer size: 132 Bytes
  • Size of remote file: 4.91 MB
pics/nDefect/1.jpg CHANGED

Git LFS Details

  • SHA256: a2e1f5cdb5a322e74524b02067b7abaf083cf9314f843baad5a8874bcc5bfab0
  • Pointer size: 132 Bytes
  • Size of remote file: 3.43 MB

Git LFS Details

  • SHA256: af809cc86f0b9b7290a711491701d54659630f92ba7826f28ab62f7176212a64
  • Pointer size: 132 Bytes
  • Size of remote file: 3.4 MB
pics/nDefect/2.jpg CHANGED

Git LFS Details

  • SHA256: 4770141fcbfff68d1f242aa7face7805a37ad5ae5fd7636494885a3ab9c3bc9f
  • Pointer size: 132 Bytes
  • Size of remote file: 3.36 MB

Git LFS Details

  • SHA256: 2ed2b39d7de21f084f5e984263777d7437e0ab62c5768cfa8242c85c72bb0ce3
  • Pointer size: 132 Bytes
  • Size of remote file: 4.03 MB
pics/nDefect/3.jpg CHANGED

Git LFS Details

  • SHA256: 07e81519374677d93bb052c219b3f8032c408301a3a8145f0b9b27abf9a7dfe8
  • Pointer size: 132 Bytes
  • Size of remote file: 3.13 MB

Git LFS Details

  • SHA256: 1f9fdc5dd57006c8c50aebba8f93e34d1a4a97391e554f9010cc6a7e19035fe0
  • Pointer size: 132 Bytes
  • Size of remote file: 2.91 MB
pics/nDefect/4.jpg CHANGED

Git LFS Details

  • SHA256: 2ed2b39d7de21f084f5e984263777d7437e0ab62c5768cfa8242c85c72bb0ce3
  • Pointer size: 132 Bytes
  • Size of remote file: 4.03 MB

Git LFS Details

  • SHA256: d0ce3d85e69822b3e93f00578a14a5bc30396f1fcddacbbe35d0b9c6d00749d9
  • Pointer size: 132 Bytes
  • Size of remote file: 4.36 MB
pics/nDefect/5.jpg CHANGED

Git LFS Details

  • SHA256: af809cc86f0b9b7290a711491701d54659630f92ba7826f28ab62f7176212a64
  • Pointer size: 132 Bytes
  • Size of remote file: 3.4 MB

Git LFS Details

  • SHA256: 4b646710775d8c9f663741b1f0b738be39149966f787462c04f7bc3cfee83f55
  • Pointer size: 132 Bytes
  • Size of remote file: 3.37 MB
pics/nDefect/6.jpg CHANGED

Git LFS Details

  • SHA256: 4b646710775d8c9f663741b1f0b738be39149966f787462c04f7bc3cfee83f55
  • Pointer size: 132 Bytes
  • Size of remote file: 3.37 MB

Git LFS Details

  • SHA256: a2e1f5cdb5a322e74524b02067b7abaf083cf9314f843baad5a8874bcc5bfab0
  • Pointer size: 132 Bytes
  • Size of remote file: 3.43 MB
pics/nDefect/7.jpg CHANGED

Git LFS Details

  • SHA256: ccf4d61c220fbb24a8f7fcb8ba994a5dea3c8d2e5b67410c220095afad78e4e5
  • Pointer size: 132 Bytes
  • Size of remote file: 4.91 MB

Git LFS Details

  • SHA256: 4770141fcbfff68d1f242aa7face7805a37ad5ae5fd7636494885a3ab9c3bc9f
  • Pointer size: 132 Bytes
  • Size of remote file: 3.36 MB
pics/nDefect/9.jpg CHANGED

Git LFS Details

  • SHA256: d0ce3d85e69822b3e93f00578a14a5bc30396f1fcddacbbe35d0b9c6d00749d9
  • Pointer size: 132 Bytes
  • Size of remote file: 4.36 MB

Git LFS Details

  • SHA256: 07e81519374677d93bb052c219b3f8032c408301a3a8145f0b9b27abf9a7dfe8
  • Pointer size: 132 Bytes
  • Size of remote file: 3.13 MB
requirements.txt CHANGED
@@ -3,5 +3,4 @@ torch
3
  torchvision
4
  pytorch-lightning
5
  matplotlib
6
- numpy
7
- onnxruntime
 
3
  torchvision
4
  pytorch-lightning
5
  matplotlib
6
+ numpy
 
app.py → scripts/app.py RENAMED
@@ -4,50 +4,103 @@ from PIL import Image
4
  import pytorch_lightning as pl
5
  import torch.nn as nn
6
  from torchvision import transforms as T
7
- from torchvision.models import resnet152
8
  import matplotlib.pyplot as plt
9
  import onnxruntime as ort
10
  from glob import glob
11
  import streamlit as st
12
  import numpy as np
 
 
13
 
14
  #Define the labels
15
- labels = ['Defect', 'nDefect']
16
 
17
  # Define the sample images
18
  sample_images = {
19
- "Defect01": "pics/Defect/0.jpg",
20
- "Defect02": "pics/Defect/1.jpg",
21
- "Defect03": "pics/Defect/2.jpg",
22
- "Non-Defect01": "pics/nDefect/0.jpg",
23
- "Non-Defect02": "pics/nDefect/1.jpg",
24
- "Non-Defect03": "pics/nDefect/2.jpg"
25
  }
26
 
27
- class ONNXModel(pl.LightningModule):
28
- def __init__(self, model_path, n_classes=2):
29
- super().__init__()
30
- self.onnx_session = ort.InferenceSession(model_path)
31
- self.input_name = self.onnx_session.get_inputs()[0].name
32
  self.n_classes = n_classes
33
- #Change the last layer
34
- self.backbone = resnet152(weights="ResNet152_Weights.DEFAULT")
 
35
  # self.backbone = models.resnet152(pretrained=True)
36
  # self.backbone = models.vgg19(pretrained=True)
37
  for param in self.backbone.parameters():
38
  param.requires_grad = False
39
- #Change the last layer to 2 classes
 
40
  self.backbone.fc = torch.nn.Linear(self.backbone.fc.in_features, n_classes) #For ResNet base mdoel
41
  # self.backbone.classifier[6] = torch.nn.Linear(self.backbone.classifier[6].in_features, n_classes) #For VGG bse model
42
- self.onnx_session = ort.InferenceSession(model_path)
43
- self.input_name = self.onnx_session.get_inputs()[0].name
 
 
 
 
44
  def forward(self, x):
45
  preds = self.backbone(x)
46
  return preds
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  # Load the model on the appropriate device
49
- model = ONNXModel(model_path='models/model.onnx')
50
- model = model.to("cpu")
 
 
 
51
 
52
  transform = T.Compose([
53
  T.Resize((224, 224)),
@@ -56,24 +109,21 @@ transform = T.Compose([
56
 
57
  def predict(image):
58
  image = transform(image).unsqueeze(0)
59
- image = image.to("cpu")
60
 
61
  # Perform the prediction
62
  with torch.no_grad():
63
- logits = model(image)
64
  probs = F.softmax(logits, dim=1)
65
  return probs
66
 
67
  # Define the Streamlit app
68
  def app():
69
  predictions = None
70
- st.title("Defect Classification")
71
-
72
  uploaded_file = st.file_uploader("Upload your image...", type=["jpg"])
73
 
74
  with st.expander("Or choose from sample here..."):
75
-
76
- st.header("Sample Defect Images")
77
  col1, col2, col3 = st.columns(3)
78
  with col1:
79
  st.image(sample_images["Defect01"], caption="Defect01", use_column_width=True)
@@ -81,7 +131,6 @@ def app():
81
  st.image(sample_images["Defect02"], caption="Defect02", use_column_width=True)
82
  with col3:
83
  st.image(sample_images["Defect03"], caption="Defect03", use_column_width=True)
84
- st.header("Sample Non-Defect Images")
85
  col1, col2, col3 = st.columns(3)
86
  with col1:
87
  st.image(sample_images["Non-Defect01"], caption="Non-Defect01", use_column_width=True)
@@ -90,8 +139,6 @@ def app():
90
  with col3:
91
  st.image(sample_images["Non-Defect03"], caption="Non-Defect03", use_column_width=True)
92
 
93
- sample = st.selectbox(label = "Select here", options = list(sample_images.keys()), label_visibility="hidden")
94
-
95
  # If an image is uploaded, make a prediction on it
96
  if uploaded_file is not None:
97
  image = Image.open(uploaded_file)
@@ -104,13 +151,16 @@ def app():
104
 
105
  # Show predictions with their probabilities
106
  if predictions is not None:
107
- st.write(predictions)
 
108
  for pred, prob in zip(labels, predictions[0]):
109
  st.write(f"{pred}: {prob * 100:.2f}%")
110
  st.progress(prob.item())
111
  else:
112
  st.write("No predictions.")
113
-
 
 
114
 
115
  # Run the app
116
  if __name__ == "__main__":
 
4
  import pytorch_lightning as pl
5
  import torch.nn as nn
6
  from torchvision import transforms as T
7
+ from torchvision import models
8
  import matplotlib.pyplot as plt
9
  import onnxruntime as ort
10
  from glob import glob
11
  import streamlit as st
12
  import numpy as np
13
+ from torchmetrics.functional import accuracy
14
+ from torchmetrics import Accuracy
15
 
16
  #Define the labels
17
+ labels = ['Defect', 'Non-Defect']
18
 
19
  # Define the sample images
20
  sample_images = {
21
+ "Defect01": "../pics/Defect/2.jpg",
22
+ "Defect02": "../pics/Defect/6.jpg",
23
+ "Defect03": "../pics/Defect/8.jpg",
24
+ "Non-Defect01": "../pics/nDefect/3.jpg",
25
+ "Non-Defect02": "../pics/nDefect/4.jpg",
26
+ "Non-Defect03": "../pics/nDefect/8.jpg"
27
  }
28
 
29
+ class DefectResNet(pl.LightningModule):
30
+ def __init__(self, n_classes=2):
31
+ super(DefectResNet, self).__init__()
32
+
33
+ # จำนวนของพันธุ์output (2)
34
  self.n_classes = n_classes
35
+
36
+ #เปลี่ยน layer สุดท้าย
37
+ self.backbone = models.resnet50(pretrained=True)
38
  # self.backbone = models.resnet152(pretrained=True)
39
  # self.backbone = models.vgg19(pretrained=True)
40
  for param in self.backbone.parameters():
41
  param.requires_grad = False
42
+
43
+ # เปลี่ยน fc layer เป็น output ขนาด 2
44
  self.backbone.fc = torch.nn.Linear(self.backbone.fc.in_features, n_classes) #For ResNet base mdoel
45
  # self.backbone.classifier[6] = torch.nn.Linear(self.backbone.classifier[6].in_features, n_classes) #For VGG bse model
46
+
47
+ self.entropy_loss = nn.CrossEntropyLoss()
48
+ self.accuracy = Accuracy(task="multiclass", num_classes=2)
49
+
50
+ self.save_hyperparameters(logger=False)
51
+
52
  def forward(self, x):
53
  preds = self.backbone(x)
54
  return preds
55
 
56
+ def training_step(self, batch, batch_idx):
57
+ x, y = batch
58
+ logits = self.backbone(x)
59
+ loss = self.entropy_loss(logits, y)
60
+ y_pred = torch.argmax(logits, dim=1)
61
+ self.log("train_loss", loss)
62
+ self.log("train_acc", self.accuracy(y_pred, y))
63
+ return loss
64
+
65
+ def validation_step(self, batch, batch_idx):
66
+ x, y = batch
67
+ logits = self.backbone(x)
68
+ loss = self.entropy_loss(logits, y)
69
+ y_pred = torch.argmax(logits, dim=1)
70
+ self.log("val_loss", loss)
71
+ self.log("val_acc", self.accuracy(y_pred, y))
72
+ return loss
73
+
74
+ def configure_optimizers(self):
75
+ self.optimizer = torch.optim.AdamW(self.parameters(), lr=1e-3)
76
+ return {
77
+ "optimizer": self.optimizer,
78
+ "monitor": "val_loss",
79
+ }
80
+
81
+ def test_step(self, batch, batch_idx):
82
+ x, y = batch
83
+ logits = self.backbone(x)
84
+ loss = self.entropy_loss(logits, y)
85
+ y_pred = torch.argmax(logits, dim=1)
86
+ self.log("val_loss", loss)
87
+ self.log("val_acc", self.accuracy(y_pred, y))
88
+ return loss
89
+
90
+ def _shared_eval_step(self, batch, batch_idx):
91
+ x, y = batch
92
+ y_hat = self.model(x)
93
+ logits = self.backbone(x)
94
+ loss = self.entropy_loss(logits, y)
95
+ acc = accuracy(y_hat, y)
96
+ return loss, acc
97
+
98
  # Load the model on the appropriate device
99
+ loadmodel = DefectResNet()
100
+ def load_checkpoint(checkpoint):
101
+ loadmodel.load_state_dict(checkpoint["state_dict"])
102
+ load_checkpoint(torch.load("../models/model.ckpt"))
103
+ loadmodel.eval()
104
 
105
  transform = T.Compose([
106
  T.Resize((224, 224)),
 
109
 
110
  def predict(image):
111
  image = transform(image).unsqueeze(0)
 
112
 
113
  # Perform the prediction
114
  with torch.no_grad():
115
+ logits = loadmodel(image)
116
  probs = F.softmax(logits, dim=1)
117
  return probs
118
 
119
  # Define the Streamlit app
120
  def app():
121
  predictions = None
122
+ st.title("Digital textile printing defect classification for industrial.")
 
123
  uploaded_file = st.file_uploader("Upload your image...", type=["jpg"])
124
 
125
  with st.expander("Or choose from sample here..."):
126
+ sample = st.selectbox(label = "Select here", options = list(sample_images.keys()), label_visibility="hidden")
 
127
  col1, col2, col3 = st.columns(3)
128
  with col1:
129
  st.image(sample_images["Defect01"], caption="Defect01", use_column_width=True)
 
131
  st.image(sample_images["Defect02"], caption="Defect02", use_column_width=True)
132
  with col3:
133
  st.image(sample_images["Defect03"], caption="Defect03", use_column_width=True)
 
134
  col1, col2, col3 = st.columns(3)
135
  with col1:
136
  st.image(sample_images["Non-Defect01"], caption="Non-Defect01", use_column_width=True)
 
139
  with col3:
140
  st.image(sample_images["Non-Defect03"], caption="Non-Defect03", use_column_width=True)
141
 
 
 
142
  # If an image is uploaded, make a prediction on it
143
  if uploaded_file is not None:
144
  image = Image.open(uploaded_file)
 
151
 
152
  # Show predictions with their probabilities
153
  if predictions is not None:
154
+ # st.write(predictions)
155
+ st.subheader(f'Predictions : {labels[torch.argmax(predictions[0]).item()]}')
156
  for pred, prob in zip(labels, predictions[0]):
157
  st.write(f"{pred}: {prob * 100:.2f}%")
158
  st.progress(prob.item())
159
  else:
160
  st.write("No predictions.")
161
+ st.subheader("Credits")
162
+ st.write("By : Settapun Laoaree | AI-Builders")
163
+ st.markdown("Source : [Github](https://github.com/ShokulSet/DefectDetection-AIBuilders) [Hugging Face](https://huggingface.co/spaces/sh0kul/DefectDetection-Deploy)")
164
 
165
  # Run the app
166
  if __name__ == "__main__":
pics/Rename.py → scripts/rename.py RENAMED
@@ -1,5 +1,5 @@
1
  # Python 3 code to rename multiple
2
- # files in a directory or folder
3
 
4
  # importing os module
5
  import os
@@ -7,15 +7,24 @@ import os
7
  # Function to rename multiple files
8
  def main():
9
 
10
- folder = "/home/shokul/AIBuilder/deploy/DefectDetection-AIBuilders/pics/nDefect"
11
- for count, filename in enumerate(os.listdir(folder)):
 
12
  dst = f"{str(count)}.jpg"
13
- src =f"{folder}/{filename}" # foldername/filename, if .py file is outside folder
14
- dst =f"{folder}/{dst}"
15
 
16
  # rename() function will
17
  # rename all the files
18
  os.rename(src, dst)
 
 
 
 
 
 
 
 
19
 
20
  # Driver Code
21
  if __name__ == '__main__':
 
1
  # Python 3 code to rename multiple
2
+ # files in a directory or defect_path
3
 
4
  # importing os module
5
  import os
 
7
  # Function to rename multiple files
8
  def main():
9
 
10
+ defect_path = "../pics/Defect"
11
+ ndefect_path = "../pics/nDefect"
12
+ for count, filename in enumerate(os.listdir(defect_path)):
13
  dst = f"{str(count)}.jpg"
14
+ src =f"{defect_path}/{filename}" # defect_pathname/filename, if .py file is outside defect_path
15
+ dst =f"{defect_path}/{dst}"
16
 
17
  # rename() function will
18
  # rename all the files
19
  os.rename(src, dst)
20
+
21
+ for count, filename in enumerate(os.listdir(ndefect_path)):
22
+ dst = f"{str(count)}.jpg"
23
+ src =f"{ndefect_path}/{filename}" # defect_pathname/filename, if .py file is outside defect_path
24
+ dst =f"{ndefect_path}/{dst}"
25
+ # rename() function will
26
+ # rename all the files
27
+ os.rename(src, dst)
28
 
29
  # Driver Code
30
  if __name__ == '__main__':