Initial commit
This commit is contained in:
parent
1d444b3351
commit
0251ac6af3
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
.venv
|
.venv
|
||||||
|
__pycache__
|
7
BN.py
7
BN.py
@ -1,5 +1,4 @@
|
|||||||
import torch.nn as nn
|
import torch.nn as nn
|
||||||
import torch.optim as optim
|
|
||||||
|
|
||||||
# Define CNN Model
|
# Define CNN Model
|
||||||
class CatDogClassifier(nn.Module):
|
class CatDogClassifier(nn.Module):
|
||||||
@ -8,14 +7,14 @@ class CatDogClassifier(nn.Module):
|
|||||||
self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)
|
self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)
|
||||||
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
|
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
|
||||||
self.pool = nn.MaxPool2d(2, 2)
|
self.pool = nn.MaxPool2d(2, 2)
|
||||||
self.fc1 = nn.Linear(64 * (img_size//4) * (img_size//4), 128) # Flatten size depends on image size
|
self.fc1 = nn.Linear(64 * (img_size//4) * (img_size//4), 128)
|
||||||
self.fc2 = nn.Linear(128, 2) # Output 2 classes (cat or dog)
|
self.fc2 = nn.Linear(128, 2)
|
||||||
self.relu = nn.ReLU()
|
self.relu = nn.ReLU()
|
||||||
|
|
||||||
def forward(self, x):
|
def forward(self, x):
|
||||||
x = self.pool(self.relu(self.conv1(x)))
|
x = self.pool(self.relu(self.conv1(x)))
|
||||||
x = self.pool(self.relu(self.conv2(x)))
|
x = self.pool(self.relu(self.conv2(x)))
|
||||||
x = x.view(x.size(0), -1) # Flatten
|
x = x.view(x.size(0), -1) # Flattening
|
||||||
x = self.relu(self.fc1(x))
|
x = self.relu(self.fc1(x))
|
||||||
x = self.fc2(x)
|
x = self.fc2(x)
|
||||||
return x
|
return x
|
||||||
|
9
README.md
Normal file
9
README.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# Cats and Dogs Classification
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Quick and dirty *Bayesian Network* that classifies pictures of cats and dogs. Works okay-ish..
|
||||||
|
|
||||||
|
|
||||||
|
## Installations
|
||||||
|
|
7
caca.py
7
caca.py
@ -1,7 +0,0 @@
|
|||||||
import torch
|
|
||||||
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
|
||||||
tensor = torch.randn(3, 3).to(device) # Moves the tensor to GPU
|
|
||||||
|
|
||||||
|
|
||||||
print(tensor)
|
|
||||||
print(device)
|
|
BIN
dataset/test_set/XD/IMG_2763.jpg
Normal file
BIN
dataset/test_set/XD/IMG_2763.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.1 MiB |
BIN
dataset/test_set/XD/IMG_3077.jpg
Normal file
BIN
dataset/test_set/XD/IMG_3077.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.9 MiB |
84
main.py
84
main.py
@ -2,71 +2,33 @@ import os
|
|||||||
import cv2
|
import cv2
|
||||||
import torch
|
import torch
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from torch.utils.data import DataLoader, TensorDataset
|
|
||||||
from torch import nn, optim
|
|
||||||
from BN import CatDogClassifier
|
|
||||||
import time
|
|
||||||
|
|
||||||
# Define image size
|
model = torch.load("models/bayes_cat_dog_classifier.pth")
|
||||||
|
model.eval()
|
||||||
|
|
||||||
|
model.to("cuda")
|
||||||
|
|
||||||
IMG_SIZE = 128
|
IMG_SIZE = 128
|
||||||
|
|
||||||
# Function to load images from a directory
|
def predict_image(image_path):
|
||||||
def load_images_from_folder(folder, label):
|
img = cv2.imread(image_path)
|
||||||
data = []
|
img = cv2.resize(img, (IMG_SIZE, IMG_SIZE)) / 255.0
|
||||||
for filename in os.listdir(folder):
|
img = np.transpose(img, (2, 0, 1)) # Convert to (C, H, W)
|
||||||
img_path = os.path.join(folder, filename)
|
img_tensor = torch.tensor(img, dtype=torch.float32).unsqueeze(0).to("cuda") # Add batch dimension
|
||||||
img = cv2.imread(img_path) # Load image
|
|
||||||
if img is not None:
|
|
||||||
img = cv2.resize(img, (IMG_SIZE, IMG_SIZE)) # Resize
|
|
||||||
img = img / 255.0 # Normalize
|
|
||||||
data.append((img, label))
|
|
||||||
return data
|
|
||||||
|
|
||||||
# Load dataset
|
model.eval() # Set model to evaluation mode
|
||||||
cat_data = load_images_from_folder("dataset/training_set/cats", label=0) # Label 0 for cats
|
with torch.no_grad():
|
||||||
dog_data = load_images_from_folder("dataset/training_set/dogs", label=1) # Label 1 for dogs
|
output = model(img_tensor)
|
||||||
|
predicted = torch.argmax(output, dim=1).item()
|
||||||
|
|
||||||
# Combine and shuffle data
|
return "Dog" if predicted == 1 else "Cat"
|
||||||
dataset = cat_data + dog_data
|
|
||||||
np.random.shuffle(dataset)
|
|
||||||
|
|
||||||
# Convert to NumPy arrays
|
|
||||||
X = np.array([item[0] for item in dataset], dtype=np.float32) # Image data
|
|
||||||
Y = np.array([item[1] for item in dataset], dtype=np.int64) # Labels
|
|
||||||
|
|
||||||
# Reshape to PyTorch format (N, C, H, W)
|
|
||||||
X = np.transpose(X, (0, 3, 1, 2)) # Convert to (batch, channels, height, width)
|
|
||||||
|
|
||||||
# Convert to PyTorch tensors
|
|
||||||
X_tensor = torch.tensor(X).to("cuda")
|
|
||||||
Y_tensor = torch.tensor(Y).to("cuda")
|
|
||||||
|
|
||||||
# Create dataset and data loader
|
|
||||||
dataset = TensorDataset(X_tensor, Y_tensor)
|
|
||||||
dataloader = DataLoader(dataset, batch_size=32, shuffle=True)
|
|
||||||
|
|
||||||
# Initialize model, loss, and optimizer
|
|
||||||
model = CatDogClassifier()
|
|
||||||
model = model.to("cuda")
|
|
||||||
criterion = nn.CrossEntropyLoss()
|
|
||||||
optimizer = optim.Adam(model.parameters(), lr=0.001)
|
|
||||||
|
|
||||||
# Training loop
|
|
||||||
num_epochs = 25
|
|
||||||
start_time = time.time()
|
|
||||||
for epoch in range(num_epochs):
|
|
||||||
total_loss = 0
|
|
||||||
for images, labels in dataloader:
|
|
||||||
optimizer.zero_grad() # Reset gradients
|
|
||||||
outputs = model(images) # Forward pass
|
|
||||||
loss = criterion(outputs, labels) # Compute loss
|
|
||||||
loss.backward() # Backpropagation
|
|
||||||
optimizer.step() # Update weights
|
|
||||||
total_loss += loss.item()
|
|
||||||
|
|
||||||
print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {total_loss/len(dataloader):.4f}")
|
|
||||||
|
|
||||||
print(f"Time taken: {(time.time()-start_time):.2f} seconds")
|
|
||||||
|
|
||||||
|
|
||||||
torch.save(model, "super_model.pth")
|
preds = []
|
||||||
|
for filename in os.listdir("dataset/test_set/XD/"):
|
||||||
|
img_path = os.path.join("dataset/test_set/XD/", filename)
|
||||||
|
prediction = predict_image(img_path)
|
||||||
|
preds.append(prediction)
|
||||||
|
|
||||||
|
print(preds.count("Cat"))
|
||||||
|
print(preds.count("Dog"))
|
||||||
|
38
predict.py
38
predict.py
@ -1,38 +0,0 @@
|
|||||||
import os
|
|
||||||
import cv2
|
|
||||||
import torch
|
|
||||||
import numpy as np
|
|
||||||
from torch.utils.data import DataLoader, TensorDataset
|
|
||||||
from torch import nn, optim
|
|
||||||
from BN import CatDogClassifier
|
|
||||||
|
|
||||||
model = torch.load("super_model.pth")
|
|
||||||
model.eval()
|
|
||||||
|
|
||||||
model.to("cuda")
|
|
||||||
|
|
||||||
IMG_SIZE = 128
|
|
||||||
|
|
||||||
def predict_image(image_path):
|
|
||||||
img = cv2.imread(image_path)
|
|
||||||
img = cv2.resize(img, (IMG_SIZE, IMG_SIZE)) / 255.0
|
|
||||||
img = np.transpose(img, (2, 0, 1)) # Convert to (C, H, W)
|
|
||||||
img_tensor = torch.tensor(img, dtype=torch.float32).unsqueeze(0).to("cuda") # Add batch dimension
|
|
||||||
|
|
||||||
model.eval() # Set model to evaluation mode
|
|
||||||
with torch.no_grad():
|
|
||||||
output = model(img_tensor)
|
|
||||||
predicted = torch.argmax(output, dim=1).item()
|
|
||||||
|
|
||||||
return "Dog" if predicted == 1 else "Cat"
|
|
||||||
|
|
||||||
|
|
||||||
preds = []
|
|
||||||
for filename in os.listdir("dataset/test_set/cats/"):
|
|
||||||
img_path = os.path.join("dataset/test_set/cats/", filename)
|
|
||||||
prediction = predict_image(img_path)
|
|
||||||
preds.append(prediction)
|
|
||||||
|
|
||||||
print(preds.count("Cat"))
|
|
||||||
print(preds.count("Dog"))
|
|
||||||
print(preds.count("Cat") / 1000)
|
|
BIN
super_model.pth
BIN
super_model.pth
Binary file not shown.
70
train.py
Normal file
70
train.py
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import os
|
||||||
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
import torch
|
||||||
|
from torch.utils.data import DataLoader, TensorDataset
|
||||||
|
from torch import nn, optim
|
||||||
|
from BN import CatDogClassifier
|
||||||
|
import time
|
||||||
|
|
||||||
|
from main import total_loss, outputs
|
||||||
|
|
||||||
|
IMG_SIZE = 128
|
||||||
|
|
||||||
|
DEVICE = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
|
||||||
|
|
||||||
|
"""
|
||||||
|
This function loads all the images from the folder and labels them
|
||||||
|
"""
|
||||||
|
def load_images_from_folder(folder, label):
|
||||||
|
data = []
|
||||||
|
for filename in os.listdir(folder):
|
||||||
|
img_path = os.path.join(folder, filename)
|
||||||
|
img = cv2.imread(img_path)
|
||||||
|
if img is not None:
|
||||||
|
img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))
|
||||||
|
img = img / 255.0
|
||||||
|
data.append((img, label))
|
||||||
|
return data
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Loading the dataset
|
||||||
|
cat_data = load_images_from_folder("dataset/training_set/cats", label=0)
|
||||||
|
dog_data = load_images_from_folder("dataset/training_set/dogs", label=1)
|
||||||
|
|
||||||
|
dataset = cat_data + dog_data
|
||||||
|
np.random.shuffle(dataset)
|
||||||
|
|
||||||
|
X = np.array([item[0] for item in dataset], dtype=np.float32)
|
||||||
|
Y = np.array([item[1] for item in dataset], dtype=np.int64)
|
||||||
|
|
||||||
|
X = np.transpose(X, (0, 3, 1, 2))
|
||||||
|
|
||||||
|
X_tensor = torch.tensor(X).to(DEVICE)
|
||||||
|
Y_tensor = torch.tensor(Y).to(DEVICE)
|
||||||
|
|
||||||
|
dataset = TensorDataset(X_tensor, Y_tensor)
|
||||||
|
dataloader = DataLoader(dataset, batch_size=32, shuffle=True)
|
||||||
|
|
||||||
|
model = CatDogClassifier()
|
||||||
|
model = model.to(DEVICE)
|
||||||
|
criterion = nn.CrossEntropyLoss()
|
||||||
|
optimizer = optim.Adam(model.parameters(), lr=0.001)
|
||||||
|
|
||||||
|
num_epochs = 25
|
||||||
|
start_time = time.time()
|
||||||
|
|
||||||
|
for epoch in range(num_epochs):
|
||||||
|
total_loss = 0
|
||||||
|
for images, labels in dataloader:
|
||||||
|
optimizer.zero_grad()
|
||||||
|
outputs = model(images)
|
||||||
|
loss = criterion(outputs, labels)
|
||||||
|
loss.backward()
|
||||||
|
optimizer.step()
|
||||||
|
total_loss += loss.item()
|
||||||
|
|
||||||
|
print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {total_loss/len(dataloader):.4f}")
|
||||||
|
|
||||||
|
print(f"Time taken: {(time.time() - start_time):.2f} seconds")
|
||||||
|
torch.save(model, f"models/bayes_cat_dog_classifier.pth")
|
Loading…
x
Reference in New Issue
Block a user