harveyslash/Facial-Similarity-with-Siamese-Networks-in-Pytorch

Train siamese network for customize dataset (Python3, pytorch).

KASANA-KKING opened this issue · 6 comments

Hlo there, I’m new to python / pytorch. I have one folder(Folder1) contains 100 images of different of different person, but another folder(Folder2) contains 100 image different person (but same persons as in Folder1).

_folder1/p1.jpg
folder1/p2.jpg
folder1/p3.jpg
.
.
.folder1/p100.jpg

folder2/p1.jpg
folder2/p2.jpg
folder2/p3.jpg
.
.
.folder2/p100.jpg_
Same name indicate same person. I’m tring to modify this code, to train my system. But I don’t have any idea. Plz help me.
Thnks

since I'm using PyTorch's ImageFolder dataset, it is somewhat tricky to get what you want. I would suggest writing a script that copies all the images with the same name to a new directory, and then using that as the input for the networks.

What I'm thinking is :-

` def getitem(self,index):
img0_tuple = random.choice(self.imageFolderDataset.imgs)
#we need to make sure approx 50% of images are in the same class
should_get_same_class = random.randint(0,1)
if should_get_same_class:
while True:
#keep looping till the same class image is found
img1_tuple = random.choice(self.imageFolderDataset.imgs)
if img0_tuple[1]==img1_tuple[1]:
break
else:
img1_tuple = random.choice(self.imageFolderDataset.imgs)

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

What if I replaceif img0_tuple[1]==img1_tuple[1]:by something like:-nm0 = img0_tuple[0].split('.')[0]and then nm0 = nm0.split('/')[2]## to get image name##same for **nm1** and then if nm0==nm1:`
Will it work....

This will probably not work, because I am using image folder data set , which requires images to be in the form :
root_folder/class_name/image_name
take a look at the documentation http://pytorch.org/docs/master/torchvision/datasets.html#imagefolder
If image folder dataset works for your format, then you can do what you are saying.

However, if it doesnt work, you can just use python glob module to list all files that match a pattern. then you can modify my SiameseDataset class to accept that list of files instead of an instance of imagefolderdataset. after that you can proceed with your logic

Thnks for respond.
What I'm trying to do is: instead of marking same label (0/1) from the same folder, I'm marking same if name is same or the name is same (like 12-01,12-02,12-03..) if nm0==nm1
nm0 is name of the image from first folder and nm1 is name of image from second folder.
I'll try this .....but not sure will work or not.

I have modifies this code as follow. But it's not working. Plz let me what can I do make this work.

`
class SiameseNetworkDataset(Dataset):

def __init__(self,imageFolderDataset,transform=None,should_invert=True):
    self.imageFolderDataset = imageFolderDataset    
    self.transform = transform
    self.should_invert = should_invert
    
def __getitem__(self,index):
    img0_tuple = random.choice(self.imageFolderDataset.imgs)
    should_get_same_class = random.randint(0,1) 
    if should_get_same_class:
        while True:
            #keep looping till the same name image is found
            img1_tuple = random.choice(self.imageFolderDataset.imgs) 
            #print('img1_tupel_0: ', img1_tuple[0].split('-')[0])
            #print('\t\t\t\t\t\t\timg1_tupel_1: ', img0_tuple[0].split('-')[0])
            nam0 = img0_tuple[0].split('-')[0]
            nam1 = img1_tuple[0].split('-')[0]
            #print('img1_tupel_0',nam0.split('/')[2])
            #print('\t\t\t\t\timg1_tupel_1',nam1.split('/')[2])
            
            if nam0.split('/')[2]==nam1.split('/')[2]:
                print('img1  =  img0\t',nam0.split('/')[2]+ '\t=\t'+nam1.split('/')[2])
                break
    else:
        img1_tuple = random.choice(self.imageFolderDataset.imgs)
        #print('\t\t\t\t\t\timg1_tupel_2: ', img1_tuple)

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

`
Where my image name is like 10-01.jpg, 10-20.jpg.....11-01.jpg, 10-02.jpg.
10.XX.jpg means same(person1) person different poss.
11.XX.jpg means same(person2) person different poss.

I don't know how to save trained model after each epoch and use that saved model for testing(Using separate program say test.py). Above code is working if I use your testing code with training as you have done but, if I try to use saved model(net_train.pth) for testing(by python test.py) then I don't get same result as before.

Plz help in creating testing code for this trained model.