#tensorflow #keras #multilabel-classification
#tensorflow #keras #multilabel-классификация
Вопрос:
Я обучаю модель для классификации изображений по 10 различным меткам. Для загрузки данных я использую ImageDataGenerator.
tensorflow.keras.preprocessing.image import ImageDataGenerator
train_dir = '/content/drive/MyDrive/Colab Notebooks/EuroSAT/Train/'
train_datagen = ImageDataGenerator(rescale=1./255,
horizontal_flip=True, vertical_flip=True)
train_generator = train_datagen.flow_from_directory(train_dir, batch_size=16,
class_mode='categorical', target_size=(64, 64),
subset ='training', shuffle = False)
Но в каждой категории почти 3000 изображений, а ImageDataGenerator
всего загружается только 5443 изображения.
Найдено 5827 изображений, принадлежащих к 10 классам.
Что я могу сделать, чтобы, возможно, обойти?
Комментарии:
1. Вы уверены, что у вас нет какого-либо неподдерживаемого формата изображения, подобного
jfif
?2. @Frightera да, я уверен, поскольку ImageDataGenerator содержит 23414 изображений из 10 разных классов, когда я последовательно запускаю один и тот же код в Jupyter Notebook.
Ответ №1:
Возможно, у вас есть форматы изображений, которые не поддерживаются, или файлы изображений повреждены. Это может происходить часто, если, например, вы загружаете изображения через Google или bing. Поскольку я делаю это часто, я разработал приведенную ниже функцию, которая проверяет каталог, содержащий изображения, хранящиеся в подкаталогах (каталоги классов, если вы используете ImageDataGenerator(), flow_from_directory . Он проверяет, являются ли файлы допустимыми файлами изображений и имеют ли расширения, указанные в пользовательском списке правильных расширений. Код показан ниже. Это немного долго, потому что он выполняет много проверок входных данных и т.д. Обратите внимание, что если он обнаруживает файл с расширением jfif, он переименовывает его в jpg, поскольку они имеют одинаковый формат. Параметр convert_ext можно настроить для преобразования всех изображений в новый формат изображения на основе указанного расширения, например ‘bmp’, если оставить значение None, изображения сохраняют свой исходный формат.
import os
import shutil
import cv2
def check_file_extension (source_dir, good_ext_list, delete=False, convert_ext=None):
# source_dir is the directory containing the class sub directories that hold the images
# good_ext_list is a list of strings you specify as good extensions for the ImageDataGenerator
# this list should be ['jpg', 'jpeg', 'bmp', 'png', 'tiff']
# delete is a boolean, if set to True image files that have invalid extensions or are not valid
# image files will be deleted.
# the function return a list. If delete=False this is a list of all files that have invalid
# extensions or are not valid image files
# if convert_ext is set to other than None, it should be a string indicating the new image format
# the files will be converted to, for example "jpg"
processed_count=0 # will be total number of files found
good_count=0 # will be total number of valid image files found
bad_file_list=[] # will be a list of all files processed that had invalid extensions
removed_count=0 # will be the number of files deleted if delete is set to true
class_list=os.listdir(source_dir)
if len(class_list)==0:
print('directory ', source_dir, ' is empty *** Program Terminating')
return None
print('{0:^20s}{1}{2:^17s}{1}{3:^14s}{1}{4:^15s}'.format('Class Directory',' ', 'Files Processed', 'Files Verified', 'Files Removed'))
for klass in class_list:
class_path=os.path.join(source_dir, klass)
if os.path.isdir(class_path)==False:# check if this is a directory if it is not print a warning
print ('*** Warning *** there are files in ', source_dir, ' it should only contain sub directories' )
else:
class_file_count=0 # will be number of files found in the class directory
class_good_count=0 # will be the number of good files found in the class directory
class_removed_count =0
f_list=os.listdir(class_path) # get a list of files in the class directory
for f in f_list:
f_path=os.path.join(class_path,f)
if os.path.isfile(f_path)==False: # check if it is a file if it is a directory print a warning
print ('*** Warning *** there is a directory in ', class_path, ' there should only be files there')
else:
class_file_count =1 #increment class file counter
index=f.rfind('.')
fname=f[:index]
fext=f[index 1:].lower()
if fext not in good_ext_list and fext !='jfif':
if delete:
os.remove(f_path)
class_removed_count =1 # increment removed file counter
else:
bad_file_list.append(f_path) # don't delete but put the path in list of files with bad extensions
else:
if fext =='jfif': # if ext= jfif change it to jpg
fnew_path=os.path.join(class_path, fname '.' 'jpg')
shutil.copy(f_path,fnew_path )
os.remove(f_path)
else:
try:
img=cv2.imread(f_path)
shape=img.shape
if convert_ext !=None:
fnew_path=os.path.join(class_path, fname '.' convert_ext)
cv2.imwrite(fnew_path,img)
os.remove (f_path)
class_good_count =1
except:
if delete:
os.remove(f_path)
class_removed_count =1
else:
bad_file_list.append(f_path)
print('{0:^20s}{1}{2:^17s}{1}{3:^14s}{1}{4:^15s}'.format(klass,' ', str(class_file_count),str(class_good_count), str(class_removed_count)) )
processed_count=processed_count class_file_count
good_count=good_count class_good_count
removed_count=removed_count class_removed_count
print('processed ', processed_count, ' files ', good_count, 'files were verified ', removed_count, ' files were removed')
return bad_file_list
Ниже приведен пример использования
source_dir=r'c:temppeoplestorage'
good_ext_list=['jpg', 'jpeg', 'bmp', 'tiff', 'png']
new_ext='bmp'
bad_file_list=check_file_extension (source_dir, good_ext_list, delete=False,convert_ext=new_ext )
print (bad_file_list)
ниже приведен типичный результат
Class Directory Files Processed Files Verified Files Removed
savory 20 20 0
unsavory 21 20 0
processed 41 files 40 files were verified 0 files were removed
['c:\temp\people\storage\unsavory\040.xyz']
Комментарии:
1. спасибо за помощь. Но поврежденных файлов как таковых нет. Тот же код, который я опубликовал, генерирует указанные 22 тысячи фотографий, когда я запускаю его в записной книжке jupyter локально. Можете ли вы помочь сейчас?