Как бороться с тысячами изображений для обучения CNN Keras - PullRequest
0 голосов
/ 17 октября 2018

У меня ~ 10000k изображений, которые не помещаются в памяти.Так что сейчас я могу читать только 1000 изображений и тренироваться на них ...

Мой код здесь:

img_dir = "TrainingSet" # Enter Directory of all images 
image_path = os.path.join(img_dir+"/images",'*.bmp')
files = glob.glob(image_path)
images = []
masks = []
contours = []
indexes = []
files_names = []

for f1 in np.sort(files):
  img = cv2.imread(f1)
  result = re.search('original_cropped_(.*).bmp', str(f1))
  idx = result.group(1)
  mask_path = img_dir+"/masks/mask_cropped_"+str(idx)+".bmp"
  mask = cv2.imread(mask_path,0)
  contour_path = img_dir+"/contours/contour_cropped_"+str(idx)+".bmp"
  contour = cv2.imread(contour_path,0)

  indexes.append(idx)
  images.append(img)
  masks.append(mask)
  contours.append(contour)

train_df = pd.DataFrame({"id":indexes,"masks": masks, "images": images,"contours": contours })
train_df.sort_values(by="id",ascending=True,inplace=True)
print(train_df.shape)

img_size_target = (256,256)

ids_train, ids_valid, x_train, x_valid, y_train, y_valid, c_train, c_valid = train_test_split(
    train_df.index.values,
    np.array(train_df.images.apply(lambda x: cv2.resize(x,img_size_target).reshape(img_size_target[0],img_size_target[1],3))), 
    np.array(train_df.masks.apply(lambda x: cv2.resize(x,img_size_target).reshape(img_size_target[0],img_size_target[1],1))), 
    np.array(train_df.contours.apply(lambda x: cv2.resize(x,img_size_target).reshape(img_size_target[0],img_size_target[1],1))), 
    test_size=0.2, random_state=1337)

#Here we define the model architecture... 
#.....
#End of model definition

# Training 
optimizer = Adam(lr=1e-3,decay=1e-10)    
model.compile(loss="binary_crossentropy", optimizer=optimizer, metrics=["accuracy"])

early_stopping = EarlyStopping(patience=10, verbose=1)
model_checkpoint = ModelCheckpoint("./keras.model", save_best_only=True, verbose=1)
reduce_lr = ReduceLROnPlateau(factor=0.5, patience=5, min_lr=0.00001, verbose=1)

epochs = 200
batch_size = 32

history = model.fit(x_train, y_train,
                validation_data=[x_valid, y_valid], 
                epochs=epochs,
                batch_size=batch_size,
                callbacks=[early_stopping, model_checkpoint, reduce_lr])

Что я хотел бы знать, так это как я могу изменить свой код вЧтобы сделать пакеты из небольшого набора изображений, не загружая все остальные 10000 в память?Это означает, что алгоритм будет читать X изображений каждую эпоху из каталога и обучаться на нем, а затем переходит к следующему X до последнего.

X здесь будет разумное количество изображений, которые могут поместиться в память.

Ответы [ 2 ]

0 голосов
/ 17 октября 2018

np.array(train_df.images.apply(lambda x:cv2.resize(x,img_size_target).reshape(img_size_target[0],img_size_target[1],3)))

Сначала вы можете применить этот фильтр (и 2 других) к каждому отдельному файлу и сохранить их в специальной папке (images_prepoc, masks_preproc и т. Д.) В отдельном сценарии, затемзагрузите их обратно, уже готовые к использованию в текущем скрипте.

Если предположить, что фактические размеры изображений больше 256x256, у вас будет более быстрый алгоритм, использующий меньше памяти за счет одной фазы подготовки.

0 голосов
/ 17 октября 2018

используйте fit_generator вместо fit

def generate_batch_data(num):
    #load X images here
    return images

model.fit_generator(generate_batch_data(X),
        samples_per_epoch=10000, nb_epoch=10)

В качестве альтернативы вы можете использовать train_on_batch вместо fit

Обсуждение на GitHub по этой теме: https://github.com/keras-team/keras/issues/2708

...