Копирование файлов с помощью shutil.copy()
Такая задача: есть датасет, состоящий из папок, в каждой из которых есть некоторое число картинок. Нужно найти максимальное число картинок, а затем во всех остальных папках копировать уже лежащие в папке изображения, до тех пор, пока их не станет не меньше, чем максимум. Т.е. я просто балансирую классы, копируя уже существующие изображения.
Проблема в том, что функция shutil.copy() копирует файл с таким же именем, из-за чего ей нельзя воспользоваться при копировании файла в ту же директорию.
Как тогда решить эту задачу?
Вот мой код:
import shutil
import os
from random import randint
dir_path = 'C:/Users/**/cnn/data/train/dataset/'
max_files = 0
directory = os.listdir(path=os.path.join(dir_path))
for folder in directory:
files_num = len(os.listdir(path=os.path.join(dir_path+folder)))
if files_num > max_files:
max_files = files_num
print('--------\n\nmax is', max_files)
for folder in directory:
files_num = len(os.listdir(path=os.path.join(dir_path + folder)))
files = os.listdir(path=os.path.join(dir_path+folder))
for file in files:
if files_num >= max_files:
break
else:
shutil.copy(os.path.join(dir_path + folder + '/' + file),
os.path.join(dir_path + folder))
files_num = len(os.listdir(path=os.path.join(dir_path + folder)))
Ответы (2 шт):
Баланисировать выборку, клонируя изображения, очень сомнительная затея.
Сеть не будет дополнительно обучаться на тех же самых картинках. Это просто замедлит обучение и врядли увеличит точность предсказаний.
Вместо этого воспользуйтесь apply_tfms, как это показано в данной статье для того, чтобы создать дополнительные изображения.
Как указал @MaxU балансировать классы копированием -- плохая идея, но если кому-то понадобится, то решение @splash58 с небольшой доработкой сработало. Привожу код:
import shutil
import os
from random import randint
from tqdm import tqdm
dir_path = 'C:/Users/***/cnn/data/train/dataset/'
max_files = 0
directory = os.listdir(path=os.path.join(dir_path))
for folder in directory:
files_num = len(os.listdir(path=os.path.join(dir_path+folder)))
print('{0} contains {1} files'.format(folder, files_num))
if files_num > max_files:
max_files = files_num
print('--------\n\nmax is', max_files)
for folder in tqdm(directory):
files_num = len(os.listdir(path=os.path.join(dir_path + folder)))
files = os.listdir(path=os.path.join(dir_path+folder))
while files_num < max_files:
for file in files:
if files_num >= max_files:
break
else:
shutil.copy(os.path.join(dir_path + folder + '/' + file),
os.path.join(dir_path + folder+ '/' + file[:-4] + str(randint(0,10)))+'.jpg')
files_num = len(os.listdir(path=os.path.join(dir_path + folder)))