CNN учится по-разному, в зависимости от способа предоставления данных - PullRequest
0 голосов
/ 01 февраля 2019

Сначала я опишу проблему, ниже приведен весь необходимый код.Данные, которые я использую, верны, я проверил их.

Итак, у меня есть CNN, которому я преподаю, предоставляя массив изображений (назовем это case 1).Хорошо учится.Затем я изменяю способ предоставления обучающих данных: я использую собственный генератор данных (ниже) для загрузки изображений с диска, пакет за пакетом (случай 2).

Вот проблема: во втором случае не учатся ввсе.Если не.Если я не запускаю первый случай в течение короткого времени, затем остановите его и обучите полученную сеть, используя второй случай.Затем он узнает так же, как учился первый случай.

Насколько я понимаю, во втором случае пропущена важная инициализация, и, выбрав его в первом случае, я установил его правильно.

Любая идея, что пропущено во втором случае?

=== Подробности

У меня есть CNN для классификации изображений.Ничего экстраординарного:

model = Sequential()

model.add(Conv2D(32, (7, 7), strides = (1, 1), input_shape = (IMAGE_SIZE, IMAGE_SIZE, 1),
    kernel_regularizer=regularizers.l2(REGULARIZER),
    activity_regularizer=regularizers.l1(REGULARIZER)))
model.add(BatchNormalization(axis = 3, name = 'bn0'))
model.add(Activation('relu'))
model.add(Dropout(DROPOUT))

model.add(MaxPooling2D((2, 2), name='max_pool'))
model.add(Conv2D(64, (3, 3), strides = (1,1), name="conv1",
    kernel_regularizer=regularizers.l2(REGULARIZER),
    activity_regularizer=regularizers.l1(REGULARIZER)))
model.add(Activation('relu'))
model.add(Dropout(DROPOUT))
model.add(AveragePooling2D((3, 3), name='avg_pool'))

model.add(Flatten())
model.add(Dense(500, activation="relu", name='rl',
    kernel_regularizer=regularizers.l2(REGULARIZER),
    activity_regularizer=regularizers.l1(REGULARIZER)))
model.add(Dropout(DROPOUT))
model.add(Dense(train_labels.shape[1], activation='softmax', name='sm',
    kernel_regularizer=regularizers.l2(REGULARIZER),
    activity_regularizer=regularizers.l1(REGULARIZER)))

model.compile(loss='categorical_crossentropy', optimizer="adam", metrics=['accuracy'])
model.summary()

Теперь, это хорошо учится, если я наполняю его массивом изображений.Изображения загружаются в отдельную функцию, и предоставляется ВЕСЬ массив, поэтому модель разбивает его на партии:

datagen = ImageDataGenerator(
    rotation_range=30,
    width_shift_range=0.2,
    height_shift_range=0.2,
    zoom_range=0.2)

history = model.fit_generator(datagen.flow(x_train, train_labels, shuffle=True,
    batch_size=BATCH_SIZE), steps_per_epoch=len(x_train) / BATCH_SIZE, epochs=EPOCHS,
    validation_data=([x_valid[:,:,:, :1]], [valid_labels]), # class_weight=class_weights,
    callbacks=[saveBestModel]) 

Сеть хорошо учится.Теперь, если я загружаю изображения с диска в пакетном режиме, я использую следующий код:

def image_generator(image_file_names, labels):
    while 1:
        total = len(image_file_names)
        for start in range(0, total, BATCH_SIZE):
            x_batch = []
            end = min(start + BATCH_SIZE, total)
            y_batch = labels[start:end, :]
            file_names_batch = image_file_names[start:end]

            text_file = open("log.txt", "a")
            text_file.write("\n".join(file_names_batch))
            text_file.write("\n%s\n===================\n" % start)
            text_file.close()

            for file_name in file_names_batch:
                img = load_img("../input/train/" + file_name,
                target_size=(IMAGE_SIZE, IMAGE_SIZE), grayscale=True)
                img = img_to_array(img)
                #img = datagen.random_transform(img, seed=42)
                img = img / 255.
                x_batch.append(img)
            yield np.array(x_batch), y_batch

В этом случае вызов функции:

history = model.fit_generator(image_generator(np_train[:, 0], train_labels), 
    steps_per_epoch=len(np_train) / BATCH_SIZE, epochs=EPOCHS, shuffle=True,
    validation_data=([x_valid[:,:,:, :1]], [valid_labels]), #class_weight=class_weights,
    callbacks=[saveBestModel])

Вот проблема:во втором случае не учится вообще.Если не.Если я не запускаю первый случай в течение короткого времени, затем остановите его и обучите полученную сеть, используя второй случай.Затем он узнает.

Насколько я понимаю, во втором случае не хватает какой-то важной инициализации, и, выбрав его в первом случае, я исправлю это.

Любая идея, что пропущено за секундуслучай

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...