Nelio Barbosa commited on
Commit
9d8daba
·
1 Parent(s): 74b3e30

Upload 4 files

Browse files
Files changed (4) hide show
  1. app.py +18 -0
  2. st.py +37 -0
  3. torch_utils.py +53 -0
  4. unv_model.py +98 -0
app.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, jsonify, request
2
+ from torch_utils import transform_image
3
+ from torch_utils import get_prediction
4
+
5
+
6
+ app = Flask(__name__)
7
+
8
+ @app.route('/classify', methods=['POST'])
9
+ def classify():
10
+ if request.method == 'POST':
11
+ file = request.files['file']
12
+ img_bytes = file.read()
13
+ img = transform_image(img_bytes)
14
+ pred = get_prediction(img)
15
+ return jsonify({'classification': int(pred[0])})
16
+
17
+ if __name__ == '__main__':
18
+ app.run(port=5000, debug=True)
st.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import requests
3
+ from PIL import Image
4
+ from io import BytesIO
5
+
6
+ CLASS_LABELS = {
7
+ 0: "airplane",
8
+ 1: "bird",
9
+ 2: "car",
10
+ 3: "cat",
11
+ 4: "deer",
12
+ 5: "dog",
13
+ 6: "horse",
14
+ 7: "monkey",
15
+ 8: "ship",
16
+ 9: "truck",
17
+ }
18
+
19
+ def get_classification(image_bytes):
20
+ response = requests.post("http://localhost:5000/classify", files={"file": image_bytes})
21
+ class_id = response.json()["classification"]
22
+ return CLASS_LABELS[class_id]
23
+
24
+ st.title("Image Classification")
25
+ st.write("Upload an image to classify")
26
+
27
+ uploaded_file = st.file_uploader("Choose an image", type=["jpg", "jpeg", "png"])
28
+
29
+ if uploaded_file is not None:
30
+ image = Image.open(uploaded_file)
31
+ st.image(image, caption="Uploaded Image", use_column_width=True)
32
+
33
+ if st.button("Classify"):
34
+ img_bytes = uploaded_file.read()
35
+ label = get_classification(img_bytes)
36
+ st.write("Prediction:", label)
37
+
torch_utils.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import io
2
+ import torch
3
+ import torch.nn as nn
4
+ import torch.nn.functional as F
5
+ import torchvision.transforms as transforms
6
+ from PIL import Image
7
+
8
+
9
+ class CNN(nn.Module):
10
+ def __init__(self):
11
+ super(CNN, self).__init__()
12
+ self.conv1 = nn.Conv2d(3, 32, 5)
13
+ self.conv2 = nn.Conv2d(32, 64, 5)
14
+ #full layer
15
+ self.fc1 = nn.Linear(64 * 13 * 13, 128)
16
+ self.fc2 = nn.Linear(128, 64)
17
+ self.fc3 = nn.Linear(64, 10)
18
+
19
+ def forward(self, x):
20
+ x = F.max_pool2d(F.relu(self.conv1(x)), (2,2))
21
+ x = F.max_pool2d(F.relu(self.conv2(x)), 2)
22
+ x = x.view(-1, self.num_flat_features(x))
23
+ x = F.relu(self.fc1(x))
24
+ x = F.relu(self.fc2(x))
25
+ x = self.fc3(x)
26
+ return x
27
+
28
+ def num_flat_features(self, x):
29
+ size = x.size()[1:] # all dimensions except the batch dimension
30
+ num_features = 1
31
+ for s in size:
32
+ num_features *= s
33
+ return num_features
34
+
35
+ loaded_model = CNN()
36
+ loaded_model.load_state_dict(torch.load("cnn_model.pth")) # it takes the loaded dictionary, not the path file itself
37
+ loaded_model.eval()
38
+
39
+
40
+ #transform images
41
+
42
+ def transform_image(image_bytes):
43
+ transform = transforms.Compose(
44
+ [transforms.Resize(64), transforms.CenterCrop(64), transforms.ToTensor()]
45
+ )
46
+ image = Image.open(io.BytesIO(image_bytes))
47
+ return transform(image).unsqueeze(0)
48
+
49
+ def get_prediction(image_tensor):
50
+ outputs = loaded_model(image_tensor)
51
+ # max returns (value ,index)
52
+ _, predicted = torch.max(outputs.data, 1)
53
+ return predicted
unv_model.py ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ import torch.nn.functional as F
4
+ import torch.optim as optim
5
+ import torchvision
6
+ import torchvision.transforms as transforms
7
+ import scipy
8
+
9
+ device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")# assign the device to the model
10
+
11
+ #hyper-parameters
12
+ learning_rate = 0.005
13
+ batch_size = 128
14
+ hidden_size = 300
15
+ num_classes = 10
16
+ num_epochs = 550
17
+
18
+ #load data
19
+
20
+ transform = transforms.Compose(
21
+ [transforms.Resize(64), transforms.CenterCrop(64), transforms.ToTensor()]
22
+ )
23
+
24
+ train_dataset = torchvision.datasets.STL10(root='./dataSTL10', split="train", transform=transform, download=True)
25
+ test_dataset = torchvision.datasets.STL10(root='./dataSTL10', split="test", transform=transform, download=True)
26
+ train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)
27
+ test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)
28
+
29
+ # CNN
30
+
31
+ class CNN(nn.Module):
32
+ def __init__(self):
33
+ super(CNN, self).__init__()
34
+ self.conv1 = nn.Conv2d(3, 32, 5)
35
+ self.conv2 = nn.Conv2d(32, 64, 5)
36
+ #full layer
37
+ self.fc1 = nn.Linear(64 * 13 * 13, 128)
38
+ self.fc2 = nn.Linear(128, 64)
39
+ self.fc3 = nn.Linear(64, num_classes)
40
+
41
+ def forward(self, x):
42
+ x = F.max_pool2d(F.relu(self.conv1(x)), (2,2))
43
+ x = F.max_pool2d(F.relu(self.conv2(x)), 2)
44
+ x = x.view(-1, self.num_flat_features(x))
45
+ x = F.relu(self.fc1(x))
46
+ x = F.relu(self.fc2(x))
47
+ x = self.fc3(x)
48
+ return x
49
+
50
+ def num_flat_features(self, x):
51
+ size = x.size()[1:] # all dimensions except the batch dimension
52
+ num_features = 1
53
+ for s in size:
54
+ num_features *= s
55
+ return num_features
56
+
57
+ cnn = CNN().to(device)
58
+
59
+ criterion = nn.CrossEntropyLoss()
60
+ optimizer = optim.Adam(cnn.parameters(), lr=learning_rate)
61
+
62
+ # training loop
63
+
64
+ for epoch in range(num_epochs):
65
+ for i, (images, labels) in enumerate(train_loader):
66
+ images = images.to(device)
67
+ labels = labels.to(device)
68
+
69
+ out = cnn(images)
70
+ loss = criterion(out, labels)
71
+
72
+ optimizer.zero_grad()
73
+ loss.backward()
74
+ optimizer.step()
75
+
76
+ if(i+1) % 1 == 0:
77
+ print(f'epoch: {epoch+1}/{num_epochs} step: {i+1}, loss: loss: {loss.item():.4f}')
78
+
79
+
80
+ with torch.no_grad():
81
+ n_correct = 0
82
+ n_samples = 0
83
+ for images, labels in test_loader:
84
+ images = images.to(device)
85
+ labels = labels.to(device)
86
+ outputs = cnn(images)
87
+ # max returns (value ,index)
88
+ _, predicted = torch.max(outputs.data, 1)
89
+ n_samples += labels.size(0)
90
+ n_correct += (predicted == labels).sum().item()
91
+
92
+ acc = 100.0 * n_correct / n_samples
93
+ print(f'Accuracy of the network on the {n_samples} test images: {acc} %')
94
+
95
+
96
+ # Save the model
97
+ torch.save(cnn.state_dict(), "cnn_model.pth")
98
+