python - 如何序列化keras模型的类对象
问题描述
我试图保存 keras 完整模型,但遇到了这个错误
Traceback (most recent call last):
File "d:/Workspace/College/Semester 8/Tugas Akhir/Keras-RFCN-master/Keras-RFCN-master/testing.py", line 133, in <module>
main()
File "d:/Workspace/College/Semester 8/Tugas Akhir/Keras-RFCN-master/Keras-RFCN-master/testing.py", line 96, in main
model.save("D:/weight.h5")
File "d:\Workspace\College\Semester 8\Tugas Akhir\Keras-RFCN-master\Keras-RFCN-master\KerasRFCN\Model\Model.py", line 560, in save
self.model.save(save_path)
File "C:\Users\kevin\anaconda3\envs\tf-gpu\lib\site-packages\keras\engine\network.py", line 1139, in save
save_model(self, filepath, overwrite, include_optimizer)
File "C:\Users\kevin\anaconda3\envs\tf-gpu\lib\site-packages\keras\engine\saving.py", line 415, in save_wrapper
save_function(obj, filepath, overwrite, *args, **kwargs)
File "C:\Users\kevin\anaconda3\envs\tf-gpu\lib\site-packages\keras\engine\saving.py", line 507, in save_model
_serialize_model(model, h5dict, include_optimizer)
File "C:\Users\kevin\anaconda3\envs\tf-gpu\lib\site-packages\keras\engine\saving.py", line 101, in _serialize_model
model_config = json.dumps(model_config, default=get_json_type)
File "C:\Users\kevin\anaconda3\envs\tf-gpu\lib\json\__init__.py", line 238, in dumps
**kw).encode(obj)
File "C:\Users\kevin\anaconda3\envs\tf-gpu\lib\json\encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "C:\Users\kevin\anaconda3\envs\tf-gpu\lib\json\encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "C:\Users\kevin\anaconda3\envs\tf-gpu\lib\site-packages\keras\engine\saving.py", line 91, in get_json_type
raise TypeError('Not JSON Serializable: %s' % (obj,))
TypeError: Not JSON Serializable: <KerasRFCN.Config.Config object at 0x0000029B0A3BD248>
通过该错误,很明显 JSON 无法序列化我的类,该类返回一个名为 config 的对象。那么如何确保 Keras 可以序列化我的配置..??
我认为在init中定义的所有定义都可以序列化。
我真的是 python、Keras 和 TensorFlow 的新手。
我正在使用 tensorflow-GPU 1.15.2、Keras 2.2.5 和 python 3.7,这是我在 def init中定义所有变量之前的配置代码:
class Config(object):
NAME = "BDD" # Override in sub-classes
# Backbone model
BACKBONE = "resnet50"
# NUMBER OF GPUs to use. For CPU training, use 1
GPU_COUNT = 1
# Number of images to train with on each GPU.
IMAGES_PER_GPU = 2
# Number of training steps per epoch
STEPS_PER_EPOCH = 1000
# Number of validation steps to run at the end of every training epoch.
VALIDATION_STEPS = 50
# The strides of each layer of the FPN Pyramid.
# Like BACKBONE_STRIDES = [4, 8, 16, 16, 16]
BACKBONE_STRIDES = [4, 8, 16, 32, 64]
# Number of classification classes (including background)
NUM_CLASSES = 1 # Override in sub-classes
# Length of square anchor side in pixels
RPN_ANCHOR_SCALES = (32, 64, 128, 256, 512)
# Ratios of anchors at each cell (width/height)
# A value of 1 represents a square anchor, and 0.5 is a wide anchor
RPN_ANCHOR_RATIOS = [0.5, 1, 2]
# Anchor stride
# If 1 then anchors are created for each cell in the backbone feature map.
# If 2, then anchors are created for every other cell, and so on.
RPN_ANCHOR_STRIDE = 1
# Non-max suppression threshold to filter RPN proposals.
# You can reduce this during training to generate more propsals.
RPN_NMS_THRESHOLD = 0.7
# How many anchors per image to use for RPN training
RPN_TRAIN_ANCHORS_PER_IMAGE = 256
# ROIs kept after non-maximum supression (training and inference)
POST_NMS_ROIS_TRAINING = 2000
POST_NMS_ROIS_INFERENCE = 1000
# Input image resing
# Images are resized such that the smallest side is >= IMAGE_MIN_DIM and
# the longest side is <= IMAGE_MAX_DIM. In case both conditions can't
# be satisfied together the IMAGE_MAX_DIM is enforced.
IMAGE_MIN_DIM = 800
IMAGE_MAX_DIM = 1024
# If True, pad images with zeros such that they're (max_dim by max_dim)
IMAGE_PADDING = True # currently, the False option is not supported
# Image mean (RGB)
MEAN_PIXEL = np.array([123.7, 116.8, 103.9])
# Number of ROIs per image to feed to classifier
TRAIN_ROIS_PER_IMAGE = 200
# Percent of positive ROIs used to train classifier/mask heads
ROI_POSITIVE_RATIO = 0.33
# Pooled ROIs
POOL_SIZE = 3
# Maximum number of ground truth instances to use in one image
MAX_GT_INSTANCES = 100
# Bounding box refinement standard deviation for RPN and final detections.
RPN_BBOX_STD_DEV = np.array([0.1, 0.1, 0.2, 0.2])
BBOX_STD_DEV = np.array([0.1, 0.1, 0.2, 0.2])
# Max number of final detections
DETECTION_MAX_INSTANCES = 100
# Minimum probability value to accept a detected instance
# ROIs below this threshold are skipped
DETECTION_MIN_CONFIDENCE = 0.8
# Non-maximum suppression threshold for detection
DETECTION_NMS_THRESHOLD = 0.3
# Learning rate and momentum
LEARNING_RATE = 0.001
LEARNING_MOMENTUM = 0.9
# Weight decay regularization
WEIGHT_DECAY = 0.0005
USE_RPN_ROIS = True
K = 3
def __init__(self):
"""Set values of computed attributes."""
# Effective batch size
self.BATCH_SIZE = self.IMAGES_PER_GPU * self.GPU_COUNT
# Input image size
self.IMAGE_SHAPE = np.array(
[self.IMAGE_MAX_DIM, self.IMAGE_MAX_DIM, 3])
# Compute backbone size from input image size
self.BACKBONE_SHAPES = np.array(
[[int(math.ceil(self.IMAGE_SHAPE[0] / stride)),
int(math.ceil(self.IMAGE_SHAPE[1] / stride))]
for stride in self.BACKBONE_STRIDES])
def display(self):
"""Display Configuration values."""
print("\nConfigurations:")
for a in dir(self):
if not a.startswith("__") and not callable(getattr(self, a)):
print("{:30} {}".format(a, getattr(self, a)))
print("\n")
解决方案
如果您使用的是子类模型,那么在定义模型之后,您需要在一些数据上调用模型,例如model.predict(x)
这将创建权重并使模型能够使用model.save
或'model.save_weights and
load_weights`保存
首先,一个从未使用过的子类模型是无法保存的。
这是因为需要在某些数据上调用子类模型才能创建其权重。
在调用模型之前,它不知道它应该期望的输入数据的形状和 dtype,因此无法创建其权重变量。
有关该方法的更多详细信息,请参见此处的示例
推荐阅读
- c - 显示如何使用 register_printf_domain_function 的示例程序?
- python - kfold 中的真实值和预测值
- java - 如何在 Java Swing 的 JTable 单元格中设置两种背景颜色
- elasticsearch - Logstash 不向弹性搜索发送数据
- python - 应用特定条件后,保留 pandas 中的第一个 True 行和所有其他 False 行
- typescript - 将节点标准模块导入 TypeScript
- neural-network - 我无法弄清楚为什么张量的大小在 Pytorch 中不匹配
- javascript - lodash 来自具有属性的对象数组的新对象
- scrapy - 如何使用 scrapy 从 5 个不同的网站抓取数据
- sql - 显示与 SQL Server、SQL 中 Max Id 上的两个不同条件的组合相同的结果集