Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
61b912d
Create MRI_TimothyTjipto
sv-Tjipto Sep 19, 2023
b8a5308
Delete recognition/MRI_TimothyTjipto
sv-Tjipto Sep 19, 2023
0fc33ac
Create folder for Project
sv-Tjipto Sep 19, 2023
dddc179
Necessary python template
sv-Tjipto Sep 19, 2023
245fe39
change to question 7 and added .gitignore
sv-Tjipto Oct 3, 2023
2d1ffe3
Ignore dataset
sv-Tjipto Oct 3, 2023
c72df9c
Ignore database and its content
sv-Tjipto Oct 3, 2023
e796bf9
---
sv-Tjipto Oct 3, 2023
fd85dd3
brief change on dataset.py
sv-Tjipto Oct 3, 2023
2dbc2b9
Ignore jpeg
sv-Tjipto Oct 3, 2023
e58b258
deleted gitignore
sv-Tjipto Oct 3, 2023
58f23ac
Implemented Dataset
sv-Tjipto Oct 14, 2023
9f8af16
training set
sv-Tjipto Oct 16, 2023
b85df20
visual changes
sv-Tjipto Oct 18, 2023
c5f54e8
Import Model from Cluster
sv-Tjipto Oct 23, 2023
0166920
Cleaned up modules.py and documentation
sv-Tjipto Oct 23, 2023
d1b5ea8
Cleaned up documentation of dataset and train file
sv-Tjipto Oct 23, 2023
77d415e
Cleanup code, made transform and dataloader into
sv-Tjipto Oct 23, 2023
e532c7f
Remove unused function
sv-Tjipto Oct 23, 2023
3a0b7c1
Cleaned up train.py, Move visualising plt to
sv-Tjipto Oct 23, 2023
5276a99
Documentation for predict.py
sv-Tjipto Oct 23, 2023
fd2e21b
Completed documentation for dataset.py
sv-Tjipto Oct 23, 2023
256c636
Documentation for modules.py
sv-Tjipto Oct 23, 2023
83947ec
added comments
sv-Tjipto Oct 23, 2023
467863c
Finish Documentation
sv-Tjipto Oct 23, 2023
6d53838
Undo comment
sv-Tjipto Oct 23, 2023
18d610e
Title
sv-Tjipto Oct 24, 2023
48f6d9e
Remove top comments
sv-Tjipto Oct 24, 2023
ba35ebc
Images for README
sv-Tjipto Oct 24, 2023
8232921
Completed the section
sv-Tjipto Oct 24, 2023
2fad8ce
deleted stuff in gitignore
sv-Tjipto Oct 24, 2023
a091a9a
Change to True TRAINING_MODE
sv-Tjipto Oct 24, 2023
302b630
Rename folder
sv-Tjipto Oct 24, 2023
9d95a20
Added Question
sv-Tjipto Oct 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
recognition/MRI_TimothyTjipto/bin/lol.png
recognition/MRI_TimothyTjipto/bin/Note.txt
recognition/MRI_TimothyTjipto/bin/TEST.ipynb
recognition/MRI_TimothyTjipto/bin/test2.ipynb
recognition/MRI_TimothyTjipto/bin/Test3.ipynb
recognition/MRI_TimothyTjipto/bin/Tester3.ipynb
recognition/MRI_TimothyTjipto/bin/visualise_batch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
98 changes: 98 additions & 0 deletions recognition/SiameseNetwork_s4653241/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Siamese Network classifier to classify Alzheimer's disease

[7]Project uses Siamese Network to predict the similarity between two images and classify normal or AD(Alzheimer's Disease).

## Siamese network

Siamese Network is a specialized neural network architectural which uses two identical subnetworks that shares parameters and weight.

Use two images as inputs and produces a similarity score between the two. Then classify with a label.

Popular with face verification, signature verification, and few-shot learning.

![SiameseNetwork_Example](Images/Siamese_Network.png)

Both uses the same identical Convolutional Neural Network(CNN).

During Training, Siamese networks often uses pairs that are "similar" or "dissimilar". Network learns to minimize the distance for similar pairs and maximize it for dissimilar pairs.

After processing the inputs, the final layer/differencing layer computes a distance metrics between the two outputs, often Euclidean distance. Similar items will have smaller distance between their output, while dissimilar items will have a larger distance.

Main advantages of using Siamese Network is their ability to perform one-shot learning. The ability to recongize new classes or entities with little data.

## ADNI brain dataset

### 1. Data Preprocessing

The ADNI brain dataset contains two classes, AD and NC in both Training and Test. All image has initial shape of (3,240,256) 256 x 240 (W x H) [batch_size,channel,height,width]. Loading the dataset, all images will be normalized.All Images are resized to (1,120,128) to increase training speed.

It is then paired and labeled accourdingly if it is similar class or not. Pairing process randomly pics between 2 classes to pair up. In doing so doesn't overtrain the model.

Batchloader is set to 16 to speed up the training process, can be change if needed.

Figure shows a batch with labels stating if it's a Similar or Dissimilar pair.

![visualise_pair](Images/visualise_batch.png)

POS being Positive pair and NEG being Negative pair for visual purposes.

### 2. Siamese Model

The Siamese Model first part begins with the embedding where it transforms the input images into a continuous vector space.

3 convolutional layers, 2 max-pooling layer and 2 dense layer with sigmoid activation function.

Sigmoid activation for final layer as output is within specific range.




### 3. Training

Contrastive Loss is used as a loss function as it is focus on learning the similarity or dissimilarity between pairs of the inputs.

Optimizer is Adam with a learning rate of 0.00006

After 40 Epoch,

![iteration_loss](Images/Iteration%20loss.png)


### 4. Testing

Testing the trained model results,

![loss](Images/Loss.png)
![accuracy](Images/Accuracy.png)

### 5. Prediction


![predicton1](Images/prediction/test1g.png) ![prediction2](Images/prediction/test2g.png) ![prediction3](Images/prediction/test3g.png)



## Code Discription
1. "dataset.py" contains Data loader for loading and preprocessing the dataset.

2. "modules.py" contains Source code of the components of the model.Each component is implementated as a class or a function.

3. "predict.py" contains to showexample usage of trained model. Print out any results and/ or provide visualisations where applicable.

4. "train.py" contains the source code for training, validating, testing and saving the model.
- Change TRAIN_PATH to PATH of training dataset and set TRAINING_MODE to True if you want to use model for training.
- If use checkpoint of trained model to test edit CHECKPOINT PATH



## **Dependencies**
1. Python 3.11.5
2. External Libriaries:
- torch 2.01
- matplotlib 3.8.0
- torchvision 0.15.2
- numpy 1.25.2


## References
[1] Images of Achitecute of Siamese Neural Network https://www.latentview.com/blog/siamese-neural-network-a-face-recognition-case-study/
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
214 changes: 214 additions & 0 deletions recognition/SiameseNetwork_s4653241/dataset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
# Importing necessary libraries and modules
import torch
import numpy as np
import matplotlib.pyplot as plt
from torchvision import datasets,transforms
from torch.utils.data import DataLoader,ConcatDataset,Dataset,TensorDataset, Subset
from PIL import Image
import random

def get_transform():
"""
Returns a composed transform for preprocessing images.
Returns:
torchvision.transforms.Compose: A composed transform for preprocessing images.
"""
transform = transforms.Compose([
transforms.Grayscale(num_output_channels=1), # Convert to grayscale with one channel
transforms.Resize((120,128)), # Resize to (120,128)
transforms.ToTensor(),
# You can add more transformations if needed
])
return transform

def get_dataloader(dataset, batch_size = 16, shuffle=True):
"""
Returns a DataLoader for the given dataset.

This function creates and returns a DataLoader for the provided dataset with the specified batch size and shuffling option.

Parameters:
- dataset (Dataset): The dataset for which the DataLoader is to be created.
- batch_size (int, optional): The number of samples per batch. Default is 16.
- shuffle (bool, optional): Whether to shuffle the dataset before splitting into batches. Default is True.

Returns:
- DataLoader: A DataLoader object for the given dataset with the specified parameters.
"""
v_dataloader = DataLoader(dataset,
shuffle=shuffle,
num_workers=1,
batch_size=batch_size)
return v_dataloader



def visualise_1(dataset):
"""
Plots a random image in the dataset

Args:
dataset (Dataset): Dataset which the random image will be picked
"""
img,lab = random.choice(dataset)
plt.title(lab)
plt.imshow(img)
plt.axis('off')
plt.savefig("visualise_1")
plt.show()


def visualise_batch(dataloader):
"""
Plots a batch of images from the dataloader

Args:
dataloader (Dataloader): Dataset which a batch will be taken to be plotted.
"""
LABELS = ['POS','NEG']

example_batch = iter(dataloader)
images1,images2,labels = next(example_batch)

plt.figure(figsize=(16,4)) # width x height
batch_size = len(images1)
for idx in range(batch_size):

image1 = transforms.ToPILImage()(images1[idx])
image2 = transforms.ToPILImage()(images2[idx])
label = LABELS[int(labels[idx].item())]

plt.subplot(2,batch_size,idx+1)

plt.imshow(image1,cmap='gray')
plt.axis('off')

plt.subplot(2,batch_size,idx+1+batch_size)
plt.imshow(image2,cmap='gray')
plt.title(label)
plt.axis('off')

plt.savefig("visualise_batch")
plt.show()



class SiameseNetworkDataset1(Dataset):
"""
A dataset class for creating pairs of images for Siamese networks.

Args:
Dataset (torchvision.datasets.ImageFolder): A dataset object containing images and their labels.
transform (torchvision.transforms): A function/transform that takes in an image and returns a transformed version.
Default is None.
"""
def __init__(self,imageFolderDataset,transform=None):

self.imageFolderDataset = imageFolderDataset
self.transform = transform

def __getitem__(self,index):
"""
Returns a pair of images and a label indicating if they belong to the same class.

Args:
index (int): Index (ignored)

Returns:
tuple: A tuple containing two images and a label
"""
img0_tuple = random.choice(self.imageFolderDataset.imgs)

#We need to approximately 50% of images to be in the same class
should_get_same_class = random.randint(0,1)
if should_get_same_class:
while True:
#Look untill the same class image is found
img1_tuple = random.choice(self.imageFolderDataset.imgs)
if img0_tuple[1] == img1_tuple[1]:
break
else:

while True:
#Look untill a different class image is found
img1_tuple = random.choice(self.imageFolderDataset.imgs)
if img0_tuple[1] != img1_tuple[1]:
break

img0 = Image.open(img0_tuple[0])
img1 = Image.open(img1_tuple[0])

img0 = img0.convert("L")
img1 = img1.convert("L")

if self.transform is not None:
img0 = self.transform(img0)
img1 = self.transform(img1)

return img0, img1, torch.from_numpy(np.array([int(img1_tuple[1] != img0_tuple[1])], dtype=np.float32))

def __len__(self):
return len(self.imageFolderDataset.imgs)


class SiameseNetworkDataset_test(Dataset):
"""
A test dataset class for creating pairs of images for Siamese networks.

Args:
Dataset (torchvision.datasets.ImageFolder): A dataset object containing images and their labels.
transform (torchvision.transforms): A function/transform that takes in an image and returns a transformed version.
Default is None.
"""
def __init__(self,imageFolderDataset,transform=None):
self.imageFolderDataset = imageFolderDataset
self.transform = transform

def __getitem__(self,index):
"""
Returns a pair of images, a label indicating if they belong to the same class and labels of images.

Args:
index (int): Index (ignored in this implementation as images are chosen randomly).

Returns:
tuple: A tuple containing two images, a label (1 if the images are from different classes, 0 otherwise) and 2 labels of the respective images.
"""
img0_tuple = random.choice(self.imageFolderDataset.imgs)

#We need to approximately 50% of images to be in the same class
should_get_same_class = random.randint(0,1)
if should_get_same_class:
while True:
#Look untill the same class image is found
img1_tuple = random.choice(self.imageFolderDataset.imgs)
if img0_tuple[1] == img1_tuple[1]:
break
else:

while True:
#Look untill a different class image is found
img1_tuple = random.choice(self.imageFolderDataset.imgs)
if img0_tuple[1] != img1_tuple[1]:
break

img0 = Image.open(img0_tuple[0])
img1 = Image.open(img1_tuple[0])

img0 = img0.convert("L")
img1 = img1.convert("L")

if self.transform is not None:
img0 = self.transform(img0)
img1 = self.transform(img1)

return img0, img1, torch.from_numpy(np.array([int(img1_tuple[1] != img0_tuple[1])], dtype=np.float32)), img0_tuple[1],img1_tuple[1]

def __len__(self):
"""
Returns the total number of images in the dataset.

Returns:
int: Total number of images in the dataset.
"""
return len(self.imageFolderDataset.imgs)
Loading