데이터 분할

train, val, test 등으로 자료를 분할해서 사용할 수 밖에 없는 여건이 대부분인 경우가 많다. 이러한 3개가 아니면 train, val 등으로 2개로 나누어서 사용하기도 한다. 자료를 분할하는 방법은 여러가지가 있는데, class가 있는 경우에도 비율을 유지하며 분할하는 것에 대한 것은 찾지 못했다. PyTorch에서 제공하는 함수 중에서 torch.utils.data.SubsetRandomSampler이 가장 비슷한 것 같은데 예시를 보면 왠지 내가 원하는 기능이 아닌 것 같다.

Class마다 개별적으로 코딩해서 넣어주어야 하지만, 나에게 가장 맞는 방법을 구현해 보았다.

일단 파일 목록을 섞어 준다. 그리고 코드 오류를 확인하기 위하여 데이터셋을 줄일 수 있도록 한다. 예시는 0.02로 들었다.

props = 0.02
file_A = os.listdir('...')
numpy.random.seed(21)
numpy.random.shuffle(file_A)

train, val, test 나눌 위치를 정한다. 임의로 섞었으니 앞부분부터 선택해도 상관없을 것이다.필요한 것은 train과 val 사이의 숫자와 val과 test 사이의 숫자이다. 정수에서 0~1 실수를 곱하는 것이니 소수점이 나오지만, 데이터는 정수이니 이와 관련된 부분을 고려한다.

data_split_rate = (0.8, 0.1, 0.1)
train_idx = int(len(file_A) * data_split_rate[0] * props)
val_idx   = train_idx + int(len(file_A) * data_split_rate[1] * props)
test_idx = int(len(file_A) * props)

이제 0부터 진행하면서 기준 위치를 지나면 복사할 폴더를 변경하도록 해준다.

for i, file_name in enumerate(file_A):
    if i < train_idx:
        os.system('cp FROM경로'+file_name+' TO_train/경로')
    if i >= train_idx and i < val_idx:
        os.system('cp FROM경로'+file_name+' TO_val/경로')
    if i >= val_idx and i < test_idx:
        os.system('cp FROM경로'+file_name+' TO_test/경로')