csv 파일을 통해 Dataloader __getitem__ 해올때 idx 다루기

안녕하세요!
밑에 첨부 이미지는 제가 갖고 있는 큰 사이즈의 csv 파일을 제가 같은 형식으로 간략화 하여 나타낸 것입니다!
해당 csv 파일은 이미지들이 들어있는 각 폴더의 경로가 "File Location"에 나타나 있으며, 해당 폴더 안에 각각 몇개의 이미지들이 들어있는지는 “Number of Images” 에 나타나 있습니다.

enter image description here

다름이 아니라, 제가 csv 파일과 pandas를 이용하여 이미지들을 행단위로 iloc[idx]를 이용하여 읽어내려오는 기본적인 방식은 이해 했습니다.
하지만 위와 같이 하나의 row 안에 표시된 폴더들 안에, 이미지들을 불러오기 위해 한번 더 루프를 돌려야할 때 어려움을 겪어 질문을 드리게 되었습니다.

위 이미지에 따르면 ./data/asd 폴더 안에 이미지 16개를 순차적으로 불러온 후 ./data/vbn 폴더로 넘어가 또 그 안에 있는 이미지 16개를 순차적으로 불러와야하는 상황입니다.

아래와 같이 코드를 짜보기도 했고,
차라리 idx가 각 폴더 안의 이미지 파일들을 가리키게 하고 getitem 함수를 반복적으로 호출해봐야 하나 싶어 여러 시도중에 있는데
이미지 호출 방식에 대해 어떤 조언이든 주시면 너무 감사하겠습니다…!

class CustomDataset(torch.utils.data.Dataset):

def __init__(self, root, csv_file):
    self.root = root
    self.df = pd.read_csv(csv_file)

def __len__(self):
    #The sum of "Number of Images" values will be the total length of the image dataset.
    return len(self.df.iloc[1:,1].sum())

def __getitem__(self, idx): 
    #This is where I have trouble controlling idx.
    img_name = os.path.join(self.root, self.df.iloc[idx, 2] + '.dcm')
    image = io.imread(img_name)
    image = torch.tensor(image)

    return image
  • 아래 답변은 OpenAI의 ChatGPT로 자동 생성한 것으로, 정확하지 않을 수 있습니다.
  • 잘못된 답변을 보셨다면 댓글로 첨삭 지도 부탁드립니다. :sweat_smile:

안녕하세요! 데이터셋 내의 하위 디렉토리에 있는 이미지들을 로드하는 경우, 일반적으로 각 하위 디렉토리에 대한 인덱스 정보를 유지하며 데이터를 읽어야 합니다.

다음은 제가 제안하는 구현 방법입니다.

CustomDataset 클래스를 수정하여 폴더 경로 및 이미지 파일 이름에 대한 목록을 추적하도록 합니다.

class CustomDataset(torch.utils.data.Dataset):
    def __init__(self, root, csv_file):
        self.root = root
        self.df = pd.read_csv(csv_file)
        
        # Initialize empty lists for folder and file lists
        self.folder_list = []
        self.file_list = []
        
        # Loop through each row of dataframe
        for row in range(self.df.shape[0]):
            folder_path = os.path.join(self.root, self.df.iloc[row, 2])
            num_images = self.df.iloc[row, 1]
            
            # Append folder names to folder list
            for i in range(num_images):
                self.folder_list.append(folder_path)
                
            # Get list of image file names in folder
            file_names = os.listdir(folder_path)
            file_names.sort()
            
            # Append image file names to file list
            for file in file_names:
                self.file_list.append(file)
    
    def __len__(self):
        return len(self.folder_list)
    
    def __getitem__(self, idx):
        folder_path = self.folder_list[idx]
        file_name = self.file_list[idx]
        img_name = os.path.join(folder_path, file_name)
        image = io.imread(img_name)
        image = torch.tensor(image)
        
        return image

이제, 데이터 로더의 인스턴스를 생성할 때 shuffle 인자를 True로 설정하면, 이미지 데이터를 무작위로 섞을 수 있습니다.

dataset = CustomDataset(root='./data/', csv_file='sample.csv')
dataloader = torch.utils.data.Dataloader(dataset, batch_size=32, shuffle=True)

이렇게 하면, 더 이상 일일이 루프를 돌려 하위 폴더의 이미지들을 차례대로 로드할 필요가 없게 됩니다. 이 구현 방법이 도움이 되기를 바랍니다!