Модель загрузки Keras против весов загрузки показывает противоречивое поведение - PullRequest
0 голосов
/ 31 мая 2019

Edit:
Запретить кому-то (ленивому) решение проблемы.

TL; DR

Загрузка модели из всей сохраненной модели и загрузка только весов не дает одинаковых результатов.

Конец редактирования

Более длинная версия

Я пытаюсь использовать keras реализацию Single Shot Detector из здесь . Похоже, что хранилище действительно говорит само за себя, и хотя в нем много инструкций и указаний, у меня возникают некоторые проблемы с моей моделью. Я постараюсь сократить до наиболее важных из них.

Я в основном следую командам в ssd300_inference.ipynb и сравниваю два способа загрузки модели:

  1. Либо загрузить всю модель (модель + вес)
  2. Или создайте модель с нуля и загрузите вес.

Насколько я понимаю, эти два метода должны были быть эквивалентны и давать одинаковые результаты. В моем случае это не так, и фактически первый метод полностью не работает для предоставленной модели (это может означать просто неправильный файл, но, очевидно, это не так).

check Для проверки согласованности я пробовал оба способа:

  1. Загрузить модель, проверить результаты, сохранить веса из этой модели, загрузить веса и получить результаты и
  2. Создание модели, загрузка весов, проверка результатов, сохранение модели, загрузка модели и проверка результатов

и сравнение показывает некоторую несогласованность по крайней мере (в некоторых случаях также не было никаких результатов).

Код, который я использовал:

Загрузите модель и получите результаты:

model_path = 'path/to/the/provided/model/ssd300_pascal_07+12_102k_steps.h5'
model = load_model(model_path, custom_objects={'AnchorBoxes': AnchorBoxes,
                                               'L2Normalization': L2Normalization,
                                               'DecodeDetections': DecodeDetections,
                                               'compute_loss': ssd_loss.compute_loss})

# check on the sample image
orig_images = []  # Store the images here.
input_images = []  # Store resized versions of the images here.

orig_images.append(imread(img_path))
img = image.load_img(img_path, target_size=(img_height, img_width))
img = image.img_to_array(img)
input_images.append(img)
input_images = np.array(input_images)
y_pred = model.predict(input_images)
y_pred_thresh = [y_pred[0][y_pred[0, :, 1] > confidence_threshold]]

np.set_printoptions(precision=2, suppress=True, linewidth=90)
print("Predicted boxes:\n")
print('   class   conf xmin   ymin   xmax   ymax')
print(y_pred_thresh[0])

Прогнозируемые ящики:

класс конф. Xmin ymin xmax ymax
[]

Сохранить вес загруженной модели в место:

model_weights_path = 'path/to/weights/model_weights.h5'
model.save_weights(model_weights_path)

Создание модели, загрузка весов и получение результатов:

model = ssd_300(image_size=(img_height, img_width, 3),
                n_classes=20,
                mode='inference',
                l2_regularization=0.0005,
                scales=[0.1, 0.2, 0.37, 0.54, 0.71, 0.88, 1.05],
                # The scales for MS COCO are [0.07, 0.15, 0.33, 0.51, 0.69, 0.87, 1.05]
                aspect_ratios_per_layer=[[1.0, 2.0, 0.5],
                                         [1.0, 2.0, 0.5, 3.0, 1.0 / 3.0],
                                         [1.0, 2.0, 0.5, 3.0, 1.0 / 3.0],
                                         [1.0, 2.0, 0.5, 3.0, 1.0 / 3.0],
                                         [1.0, 2.0, 0.5],
                                         [1.0, 2.0, 0.5]],
                two_boxes_for_ar1=True,
                steps=[8, 16, 32, 64, 100, 300],
                offsets=[0.5, 0.5, 0.5, 0.5, 0.5, 0.5],
                clip_boxes=False,
                variances=[0.1, 0.1, 0.2, 0.2],
                normalize_coords=True,
                subtract_mean=[123, 117, 104],
                swap_channels=[2, 1, 0],
                confidence_thresh=0.5,
                iou_threshold=0.45,
                top_k=200,
                nms_max_output_size=400)

model.load_weights(model_weights_path, by_name=True)

adam = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)
ssd_loss = SSDLoss(neg_pos_ratio=3, alpha=1.0)
model.compile(optimizer=adam, loss=ssd_loss.compute_loss)

orig_images = []  # Store the images here.
input_images = []  # Store resized versions of the images here.

orig_images.append(imread(img_path))
img = image.load_img(img_path, target_size=(img_height, img_width))
img = image.img_to_array(img)
input_images.append(img)
input_images = np.array(input_images)
y_pred = model.predict(input_images)
y_pred_thresh = [y_pred[0][y_pred[0, :, 1] > confidence_threshold]]

np.set_printoptions(precision=2, suppress=True, linewidth=90)
print("Predicted boxes:\n")
print('   class   conf xmin   ymin   xmax   ymax')
print(y_pred_thresh[0])

Прогнозируемые коробки:

класс конф. Xmin ymin xmax ymax
[[15. 0,95 122,57 11,28 207,09 157,54]
[15. 0,59 107,37 37,41 223,76 264,92]
[15. 0,58 15,01 61,65 281,45 283,4]]

Что совершенно отличается от предыдущего (первый не нашел никакого объекта), последний находит 3 человека (что неверно, но в любом случае).

Если я поменяю порядок (создайте модель, затем загрузите веса, получите результаты, сохраните модель, используя model.save(model_save_path) Я получу те же результаты (по крайней мере):

Прогнозируемые коробки:

класс конф. Xmin ymin xmax ymax
[[15. 0,95 122,57 11,28 207,09 157,54]
[15. 0,59 107,37 37,41 223,76 264,92]
[15. 0,58 15,01 61,65 281,45 283,4]]

но когда я сохраняю модель и перезагружаю ее, сохраненная модель дает несколько (!) Разные результаты:

Прогнозируемые ящики:

класс конф. Xmin ymin xmax ymax
[[15. 0,95 111,57 6,28 196,09 152,54]
[15. 0,59 97,37 27,41 213,76 254,92]
[15. 0,58 15,01 61,65 281,45 283,4]]

Я не уверен, что здесь происходит, но я нашел несколько подсказок:

  • сохраненная модель во втором случае (сначала вес, затем сохранить модель) меньше предоставленного или полученного от другого контрольные точки (при обучении), так что, видимо, это не спасает весь модель? Это тот же размер, что и веса, чтобы быть более конкретным. Размеры примерно 210,5 МБ против 105,3 МБ.
  • Процесс обучения, по-видимому, следует шаблону, приведенному в резюме обучения , по крайней мере, если посмотреть на loss и val_loss снижающиеся скорости, значения и т. Д., Если это помогает.
  • Предоставленная модель доступна в репо под Обученные с нуля в таблице результатов.
  • Подобное поведение присутствует, когда предоставляются другие контрольные точки (из моего обучения, например).
  • Требования к репо, по-видимому, удовлетворяются и моей системой.

Итак, соберите мои вопросы:

  • почему model.save() не сохраняет всю модель?
  • Почему в модели есть несоответствия между методами загрузки только весами?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...