resolverkatla commited on
Commit
a3fdab1
·
verified ·
1 Parent(s): 8b50185

Upload 11 files

Browse files
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ /data/
2
+ /models/model.pth
3
+ kaggle.json
4
+ *.zip
app.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from PIL import Image
3
+ import torch
4
+ from torchvision import transforms
5
+ from models.cnn import CNNModel
6
+ from utils.transforms import get_transforms
7
+
8
+ @st.cache_resource
9
+ def load_model(model_path='saved_models/cnn_model.pth'):
10
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
11
+ checkpoint = torch.load(model_path, map_location=device)
12
+ class_names = checkpoint['class_names']
13
+ model = CNNModel(num_classes=len(class_names))
14
+ model.load_state_dict(checkpoint['model_state_dict'])
15
+ model.to(device)
16
+ model.eval()
17
+ return model, class_names, device
18
+
19
+ st.title("📸 Intel Image Classification")
20
+ st.write("Upload an image to classify it into one of the image categories: buildings, forest, glacier, mountain, sea, or street.")
21
+
22
+ model, class_names, device = load_model()
23
+
24
+ uploaded_file = st.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])
25
+
26
+ if uploaded_file:
27
+ image = Image.open(uploaded_file).convert("RGB")
28
+ st.image(image, caption="Uploaded Image", use_container_width=True)
29
+
30
+ transform = get_transforms(train=False)
31
+ image_tensor = transform(image).unsqueeze(0).to(device)
32
+
33
+ with torch.no_grad():
34
+ output = model(image_tensor)
35
+ predicted_idx = torch.argmax(output, 1).item()
36
+ predicted_class = class_names[predicted_idx]
37
+
38
+ st.success(f"Predicted class: {predicted_class}")
models/__pycache__/cnn.cpython-313.pyc ADDED
Binary file (1.9 kB). View file
 
models/cnn.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch.nn as nn
2
+ import torch.nn.functional as F
3
+
4
+ class CNNModel(nn.Module):
5
+ def __init__(self, num_classes):
6
+ super(CNNModel, self).__init__()
7
+ self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)
8
+ self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
9
+ self.pool = nn.MaxPool2d(2, 2)
10
+ self.fc1 = nn.Linear(64 * 37 * 37, 128)
11
+ self.fc2 = nn.Linear(128, num_classes)
12
+
13
+ def forward(self, x):
14
+ x = self.pool(F.relu(self.conv1(x))) # 150->75
15
+ x = self.pool(F.relu(self.conv2(x))) # 75->37
16
+ x = x.view(-1, 64 * 37 * 37)
17
+ x = F.relu(self.fc1(x))
18
+ x = self.fc2(x)
19
+ return x
requirements.txt CHANGED
@@ -1,3 +1,5 @@
1
- altair
2
- pandas
3
- streamlit
 
 
 
1
+ torch
2
+ torchvision
3
+ streamlit
4
+ Pillow
5
+ kaggle
saved_models/cnn_model.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4aaa29782a55510abe97ac09c662d0673440964297b0b504157f67b61e2477ec
3
+ size 44944297
train.py ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import torch
3
+ import torch.nn as nn
4
+ from torch.utils.data import DataLoader, random_split
5
+ from torchvision.datasets import ImageFolder
6
+ from torchvision import transforms
7
+ from models.cnn import CNNModel
8
+ from utils.transforms import get_transforms
9
+
10
+ def train_model(data_dir='data/intel/seg_train', epochs=10, batch_size=32, save_path='saved_models/cnn_model.pth'):
11
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
12
+
13
+ # Load dataset with ImageFolder (expects folder structure: class subfolders)
14
+ full_dataset = ImageFolder(root=data_dir, transform=get_transforms(train=True))
15
+ class_names = full_dataset.classes
16
+ print(f"Classes: {class_names}")
17
+
18
+ # Split dataset 80% train, 20% val
19
+ train_size = int(0.8 * len(full_dataset))
20
+ val_size = len(full_dataset) - train_size
21
+ train_ds, val_ds = random_split(full_dataset, [train_size, val_size])
22
+
23
+ # Update val transforms (no augmentation)
24
+ val_ds.dataset.transform = get_transforms(train=False)
25
+
26
+ train_loader = DataLoader(train_ds, batch_size=batch_size, shuffle=True)
27
+ val_loader = DataLoader(val_ds, batch_size=batch_size)
28
+
29
+ model = CNNModel(num_classes=len(class_names)).to(device)
30
+ criterion = nn.CrossEntropyLoss()
31
+ optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
32
+
33
+ for epoch in range(epochs):
34
+ model.train()
35
+ total_loss = 0
36
+ total_correct = 0
37
+
38
+ for images, labels in train_loader:
39
+ images, labels = images.to(device), labels.to(device)
40
+ optimizer.zero_grad()
41
+ outputs = model(images)
42
+ loss = criterion(outputs, labels)
43
+ loss.backward()
44
+ optimizer.step()
45
+
46
+ total_loss += loss.item() * images.size(0)
47
+ total_correct += (outputs.argmax(1) == labels).sum().item()
48
+
49
+ train_loss = total_loss / len(train_loader.dataset)
50
+ train_acc = total_correct / len(train_loader.dataset)
51
+
52
+ # Validation
53
+ model.eval()
54
+ val_loss = 0
55
+ val_correct = 0
56
+ with torch.no_grad():
57
+ for images, labels in val_loader:
58
+ images, labels = images.to(device), labels.to(device)
59
+ outputs = model(images)
60
+ loss = criterion(outputs, labels)
61
+ val_loss += loss.item() * images.size(0)
62
+ val_correct += (outputs.argmax(1) == labels).sum().item()
63
+
64
+ val_loss /= len(val_loader.dataset)
65
+ val_acc = val_correct / len(val_loader.dataset)
66
+
67
+ print(f"Epoch {epoch+1}/{epochs} — Train loss: {train_loss:.4f}, Train acc: {train_acc:.4f}, Val loss: {val_loss:.4f}, Val acc: {val_acc:.4f}")
68
+
69
+ os.makedirs(os.path.dirname(save_path), exist_ok=True)
70
+ torch.save({
71
+ 'model_state_dict': model.state_dict(),
72
+ 'class_names': class_names
73
+ }, save_path)
74
+ print(f"Model saved to {save_path}")
75
+
76
+ if __name__ == "__main__":
77
+ train_model()
utils/__pycache__/data_loader.cpython-313.pyc ADDED
Binary file (1.4 kB). View file
 
utils/__pycache__/transforms.cpython-313.pyc ADDED
Binary file (1.01 kB). View file
 
utils/metrics.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ import torch
2
+
3
+ def accuracy(outputs, labels):
4
+ _, preds = torch.max(outputs, 1)
5
+ return torch.sum(preds == labels).item() / len(labels)
utils/transforms.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from torchvision import transforms
2
+
3
+ def get_transforms(train=True):
4
+ if train:
5
+ return transforms.Compose([
6
+ transforms.Resize((150, 150)),
7
+ transforms.RandomHorizontalFlip(),
8
+ transforms.ToTensor(),
9
+ transforms.Normalize(mean=[0.485, 0.456, 0.406],
10
+ std=[0.229, 0.224, 0.225])
11
+ ])
12
+ else:
13
+ return transforms.Compose([
14
+ transforms.Resize((150, 150)),
15
+ transforms.ToTensor(),
16
+ transforms.Normalize(mean=[0.485, 0.456, 0.406],
17
+ std=[0.229, 0.224, 0.225])
18
+ ])