TypeError:Unable to serialize <tf.Variable ‘alpha:0‘ shape=() dtype=float32, numpy=0.8> to JSON.

问题描述

在使用如下代码进行模型保存时报错:

alpha = K.variable(value=0.8, dtype="float32", name="alpha") #权重
beta = K.variable(value=0.2, dtype="float32", name="beta") 

......

model.compile(loss='categorical_crossentropy',
              optimizer=sgd,
              loss_weights=[alpha, beta],
              metrics=['accuracy'])
model_path = "model\\model_best.h5"
model_checkpoint = ModelCheckpoint(model_path,
                                   monitor = 'loss',
                                   verbose = 1,# 日志显示模式:0->安静模式,1->进度条,2->每轮一行
                                   save_best_only = True,save_weights_only=False,mode='auto',period=1)
history=model.fit_generator(
    data_generator(train_datagen,trainX,trainY,batch_size),
    epochs=50,
    validation_data=data_generator(validate_datagen,testX,testY,batch_size),
    validation_steps=total_validate//batch_size,
    steps_per_epoch=total_train//batch_size,
    callbacks=cbks,
    verbose=1,
)
model.save_weights(model_path)

错误信息:
请添加图片描述


解决方案:

开始以为只需要进行类型转换就能解决,结果尝试了各种方法把代码中的alpha, beta转为numpy、float以及修改keras的源码都不能解决,其中转为float类型虽然在模型训练的时候不会报错,但是在模型调用的时候能看出来模型并不能正确预测,即说明模型权重等并没有完整记录。

后来偶然看到一个有人问了类似的问题,回答说这可能是tensorflow版本的问题,使用2.10版本会出现这样的问题,降为2.9.1版本即可解决。
TypeError:Unable to serialize <tf.Variable ‘alpha:0‘ shape=() dtype=float32, numpy=0.8> to JSON._第1张图片
而我使用的正是2.10版本的tensorflow,看到回答后立马去新建了个tensorflow2.9的环境,安装好各种包,结果还是报同样的错误。

最后突发奇想试着仅保存了模型权重,竟然就可以了!模型保存与调用都没有问题。


如果不知道如何改成仅保存权重的可以看下面的代码:

model_checkpoint = ModelCheckpoint(model_path,
                                   monitor = 'loss',
                                   verbose = 1,
                                   save_best_only = True,save_weights_only=True,mode='auto',period=1)#修改save_weights_only为True

model.save_weights(model_path)                                  

在模型调用的时候需要再写一遍模型的结构:

def build_model():
    input_ = Input(shape=(64, 64, 1))
    
    #block1
    model = Conv2D(64, (5, 5), activation ='relu', padding='same')(input_)
    model = Conv2D(64, (5, 5), activation ='relu', padding='same')(model)
    model = MaxPool2D(pool_size=(2, 2))(model)
    #block2
    model = Conv2D(128, (5, 5), activation ='relu', padding='same')(model)
    model = Conv2D(128, (5, 5), activation ='relu', padding='same')(model)
    model = MaxPool2D(pool_size=(2, 2))(model)
    #block3
    model = Conv2D(256, (5, 5), activation ='relu', padding='same')(model)
    model = Conv2D(256, (5, 5), activation ='relu', padding='same')(model)
    model = Conv2D(256, (5, 5), activation ='relu', padding='same')(model)
    model = MaxPool2D(pool_size=(2, 2))(model)
     #block4
     model = Conv2D(512, (3, 3), activation ='relu', padding='same')(model)
     model = Conv2D(512, (3, 3), activation ='relu', padding='same')(model)
     model = Conv2D(512, (3, 3), activation ='relu', padding='same')(model)
     model = MaxPool2D(pool_size=(2, 2))(model)
     #block5
     model = Conv2D(512, (3, 3), activation ='relu', padding='same')(model)
     model = Conv2D(512, (3, 3), activation ='relu', padding='same')(model)
     model = Conv2D(512, (3, 3), activation ='relu', padding='same')(model)
     model = MaxPool2D(pool_size=(2, 2))(model)
    
    # fully connected layer
    model = Flatten()(model)

    model = Dense(1024, activation='relu')(model)
    model = Dropout(0.6)(model)
    
    x1 = Dense(11, activation='softmax')(model)
    x2 = Dense(11, activation='softmax')(model)

    x = [x1, x2]

    model = Model(inputs=input_, outputs=x)
    return model

model = build_model()
model.load_weights('D:\\test\\model\\model_best.h5', by_name=False)                                 

然后就可以正常进行预测啦

你可能感兴趣的:(python,tensorflow,keras)