我正在训练一个功能API模型,我的模型如下图所示:数据总数为1094,训练:有效:测试比为7:2:1 .
def bonepool():
bonepool_input = Input(shape = (1024, 256, 1))
x = Conv2D(4, 3, padding = 'same', strides = (1,1), activation = 'relu')(bonepool_input)
x = Conv2D(4, 3, padding = 'same', strides = (1,1), activation = 'relu')(x)
x = MaxPooling2D(2, strides = (2, 2))(x)
x = Conv2D(8, 3, padding = 'same', strides = (1,1), activation = 'relu')(x)
x = Conv2D(8, 3, padding = 'same', strides = (1,1), activation = 'relu')(x)
x = MaxPooling2D(2, strides = (2, 2))(x)
x = Conv2D(16, 3, padding = 'same', strides = (1,1), activation = 'relu')(x)
x = Conv2D(16, 3, padding = 'same', strides = (1,1), activation = 'relu')(x)
x = MaxPooling2D(2, strides = (2, 2))(x)
x = Conv2D(32, 3, padding = 'same', strides = (1,1), activation = 'relu')(x)
x = Conv2D(32, 3, padding = 'same', strides = (1,1), activation = 'relu')(x)
x = MaxPooling2D(2, strides = (2, 2))(x)
boonepool_output = Flatten()(x)
return Model(bonepool_input, bonepool_output)
model_1 = bonepool()
model_2 = bonepool()
concate = average([model_1.output, model_2.output])
x = Dense(128, activation = 'relu')(concate)
x = Dense(128, activation = 'relu')(x)
x = Dense(64, activation = 'relu')(x)
output = Dense(1, activation = 'sigmoid')
ensemble_model = Model([model_1.input, model_2.input], output)
precision, recall, f1score函数通过keras.backend实现。我这样编译我的模型,并在模型拟合后检查历史。但是出了问题。
opt = Adam(learning rate = 0.01)
Class_wegiht = {0:4, 1:0.5}
ensemble_model.compile(loss = 'binary_crossentropy', optimizer = opt, metrics = ['accuracy', precision, recall, f1score])
hist = ensemble_model.fit(train, batch_size= BATCH_SIZE, epochs = 10, stepts_per_epoch = train__len__(), class_weight = Class_weight, validation_data = valid, validation_steps = valid.__len__(), verbose = 1)
结果是(我删除了所有其他相关值)
时代1/1047/47 [========================================] 损失:0.1427,精度= 0.8765,…
时代2/1047/47 [========================================] 损失:0.8736,精度= 0.3987,…
时代3/1047/47 [========================================] 损失:0.1563,精度= 0.8655,…
时代4/1047/47 [========================================] 损失:0.1125,精度= 0.8788,….........
但是当我打印历史记录时,
hist.history['accuracy']
前4个值与model.fit()的log不一样就像
(0.8211,0.3712,0.7764,0.8853,……)
同样的问题适用于loss、f1score、recall、precision、valid_loss、valid_accuracy、valid_f1score、valid_recall、....等。
但是当我将verbose从1更改为2时,model.fit()日志的所有值都与history. history完全相同。
有人说model.fit()缺少last_output,所以model.fit()和history之间可能有轻微的差异,但是当我是我的模型时,它们之间的差异有时超过3.0(loss是4.2,而那个时代的history['loss']只有1.2),我认为这不是轻微的差异。
如果是平均值和last_output之间的问题,那么使用verbose=0和verbose=1时的model.fit()日志应该是不同的,即使我使用Sequential模型。但是,当我使用顺序模型而不是功能模型时,三个值模型。Fit日志(verbose = 0),模型。Fit log (verbose = 1), history .history)完全相同。
所以我怀疑在使用函数式API时,由verbose=1显示的结果(准确性、精度、召回率、f1score等)总是与verbose=2显示的结果不同,并且历史记录总是与后者匹配,而不是前者。对吗?如果不是,有人能告诉我我错过了什么吗?
你的猜测似乎是对的。从
得到的损失和其他指标hist.history
是epoch的平均值。但是,如果使用verbose 1,则日志(输出打印)文件可能与历史记录不匹配,因为它们在每个批处理之后都会更新。你需要信任的是:
hist.history
请记住,训练集的值是在epoch上计算的,而权重是优化的,这意味着与历史上的训练集相关的值可能不匹配:
ensemble_model.evaluate(train)