Keras加载模型与加载权重显示不一致的行为

时间:2019-05-31 08:52:53

标签: python tensorflow keras

编辑:
防止某人(懒惰)提供解决方案。

TL; DR

从整个保存的模型中加载模型并仅加载权重不会产生相同的结果。

编辑结束

长版

我正在尝试使用here中的Single Shot Detector的keras实现。该存储库似乎确实是自我解释,尽管它包含许多说明和指示,但我的模型面临一些问题。我将尝试减少到​​更关键的那些。

我基本上遵循ssd300_inference.ipynb中的命令,并比较两种加载模型的方式:

  1. 加载整个模型(模型+权重)
  2. 或者从头开始创建模型并加载模型。

据我了解,这两种方法应该等效并且产生相同的结果。就我而言,它们不是,实际上第一种方法对于所提供的模型完全失败(这可能意味着一个错误的文件,但显然并非如此)。

请通过两种方式检查我尝试过的一致性:

  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])
  

预测框:

     

conf级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])
  

预测框:

     

conf级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)保存模型,我将获得相同的结果(至少):

  

预测框:

     

conf级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]]

但是当我保存模型并重新加载它时,保存的模型会产生轻微的(!)不同结果:

  

预测框:

     

conf级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 MB和105.3 MB。
  • 培训过程似乎遵循training summary中提供的模式,至少可以查看lossval_loss降低速率,值等(如果有帮助)的方法。
  • 提供的模型在结果表的从零开始训练的单元格下的存储库中可用。
  • 提供其他检查点时存在类似的行为(例如,根据我的培训)。
  • 我的系统似乎也满足了回购协议的要求。

所以,收集我的问题是:

  • 为什么model.save()不保存整个模型?
  • 为什么模型与仅加载权重模型不一致?

0 个答案:

没有答案