diff --git a/ML/Pytorch/Basics/custom_dataset/custom_dataset.py b/ML/Pytorch/Basics/custom_dataset/custom_dataset.py index 2af90371..08ee7d5a 100644 --- a/ML/Pytorch/Basics/custom_dataset/custom_dataset.py +++ b/ML/Pytorch/Basics/custom_dataset/custom_dataset.py @@ -56,8 +56,8 @@ def __getitem__(self, index): # Load Data dataset = CatsAndDogsDataset( - csv_file="cats_dogs.csv", - root_dir="cats_dogs_resized", + csv_file="custom_dataset/cats_dogs.csv", + root_dir="custom_dataset/cats_dogs_resized", transform=transforms.ToTensor(), ) diff --git a/ML/Pytorch/Basics/pytorch_transforms.py b/ML/Pytorch/Basics/pytorch_transforms.py index 85c57f53..c130edb1 100644 --- a/ML/Pytorch/Basics/pytorch_transforms.py +++ b/ML/Pytorch/Basics/pytorch_transforms.py @@ -7,149 +7,38 @@ Programmed by Aladdin Persson * 2020-04-09 Initial coding +Bugfixes by Ohad Shapira +* 2021-12-08 bug fixes """ # Imports import torch -import torch.nn as nn # All neural network modules, nn.Linear, nn.Conv2d, BatchNorm, Loss functions -import torch.optim as optim # For all Optimization algorithms, SGD, Adam, etc. -import torch.nn.functional as F # All functions that don't have any parameters -from torch.utils.data import ( - DataLoader, -) # Gives easier dataset managment and creates mini batches -import torchvision.datasets as datasets # Has standard datasets we can import in a nice way -import torchvision.transforms as transforms # Transformations we can perform on our dataset +import torchvision.transforms as transforms +from torchvision.utils import save_image -# Simple CNN -class CNN(nn.Module): - def __init__(self, in_channels, num_classes): - super(CNN, self).__init__() - self.conv1 = nn.Conv2d( - in_channels=in_channels, - out_channels=8, - kernel_size=(3, 3), - stride=(1, 1), - padding=(1, 1), - ) - self.pool = nn.MaxPool2d(kernel_size=(2, 2), stride=(2, 2)) - self.conv2 = nn.Conv2d( - in_channels=8, - out_channels=16, - kernel_size=(3, 3), - stride=(1, 1), - padding=(1, 1), - ) - self.fc1 = nn.Linear(16 * 8 * 8, num_classes) +from custom_dataset.custom_dataset import CatsAndDogsDataset - def forward(self, x): - x = F.relu(self.conv1(x)) - x = self.pool(x) - x = F.relu(self.conv2(x)) - x = self.pool(x) - x = x.reshape(x.shape[0], -1) - x = self.fc1(x) - - return x - - -# Set device -device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - -# Hyperparameters -learning_rate = 1e-4 -batch_size = 64 -num_epochs = 5 - - -# Load pretrain model & modify it -model = CNN(in_channels=3, num_classes=10) -model.classifier = nn.Sequential(nn.Linear(512, 100), nn.ReLU(), nn.Linear(100, 10)) -model.to(device) - -# Load Data +# Load data my_transforms = transforms.Compose( - [ # Compose makes it possible to have many transforms - transforms.Resize((36, 36)), # Resizes (32,32) to (36,36) - transforms.RandomCrop((32, 32)), # Takes a random (32,32) crop - transforms.ColorJitter(brightness=0.5), # Change brightness of image - transforms.RandomRotation( - degrees=45 - ), # Perhaps a random rotation from -45 to 45 degrees - transforms.RandomHorizontalFlip( - p=0.5 - ), # Flips the image horizontally with probability 0.5 - transforms.RandomVerticalFlip( - p=0.05 - ), # Flips image vertically with probability 0.05 + [ + transforms.ToPILImage(), + transforms.Resize((256, 256)), # Resizes to (256,256) + transforms.RandomCrop((224, 224)), # Crop to random (224,224) + transforms.ColorJitter(brightness=0.5), + transforms.RandomRotation(degrees=45), # random rotation transforms.RandomGrayscale(p=0.2), # Converts to grayscale with probability 0.2 - transforms.ToTensor(), # Finally converts PIL image to tensor so we can train w. pytorch - transforms.Normalize( - mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5] - ), # Note: these values aren't optimal + transforms.RandomHorizontalFlip(p=0.5), # Flips horizontally with probability 0.5 + transforms.RandomVerticalFlip(p=0.05), # Flips vertically with probability 0.05 + transforms.ToTensor(), # Converts PIL image to tensor + transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]), ] ) +dataset = CatsAndDogsDataset(csv_file="custom_dataset/cats_dogs.csv", root_dir='custom_dataset/cats_dogs_resized', + transform=my_transforms) -train_dataset = datasets.CIFAR10( - root="dataset/", train=True, transform=my_transforms, download=True -) -train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True) - -# Loss and optimizer -criterion = nn.CrossEntropyLoss() -optimizer = optim.Adam(model.parameters(), lr=learning_rate) - -# Train Network -for epoch in range(num_epochs): - losses = [] - - for batch_idx, (data, targets) in enumerate(train_loader): - # Get data to cuda if possible - data = data.to(device=device) - targets = targets.to(device=device) - - # forward - scores = model(data) - loss = criterion(scores, targets) - - losses.append(loss.item()) - # backward - optimizer.zero_grad() - loss.backward() - - # gradient descent or adam step - optimizer.step() - - print(f"Cost at epoch {epoch} is {sum(losses)/len(losses):.5f}") - -# Check accuracy on training & test to see how good our model - - -def check_accuracy(loader, model): - if loader.dataset.train: - print("Checking accuracy on training data") - else: - print("Checking accuracy on test data") - - num_correct = 0 - num_samples = 0 - model.eval() - - with torch.no_grad(): - for x, y in loader: - x = x.to(device=device) - y = y.to(device=device) - - scores = model(x) - _, predictions = scores.max(1) - num_correct += (predictions == y).sum() - num_samples += predictions.size(0) - - print( - f"Got {num_correct} / {num_samples} with accuracy {float(num_correct)/float(num_samples)*100:.2f}" - ) - - model.train() - - -check_accuracy(train_loader, model) +img_num = 0 +for _ in range(10): + for img, label in dataset: + save_image(img, 'custom_dataset/cats_dogs_transforms/img_{img_num}.png'.format(img_num=str(img_num))) + img_num += 1