Keras中evaluate/evaluate_generator和predict/predict_generator理解

本文详细介绍了Keras中模型评估方法evaluate和evaluate_generator的使用,包括如何配置损失函数、优化器及评估指标,并通过实例展示了如何利用evaluate_generator进行模型评估。此外还探讨了评估结果的含义,特别关注于R²分数的正确解读。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

具体各个函数参数可以查看官方文档

evaluate/evaluate_generator

evaluate接收的参数更为简单,大多数情况只需指定x和y。
evaluate_generator需要指定datagenerator。自定义datagenerator,带来的好处就是可以异步加载数据到内存,支持多线程等。

下面以evaluate_generator为例,介绍使用方法:

# Loss Function
model_func = {
    'loss': tensor_angle_loss,
    'metrics': [
        coeff_determination,
        accuracy_5,
        accuracy_10,
    ]
}


model = Sequential()
# ...
# Optimizer
optimizer = optimizers.Adam(lr=0.0001)
# Compile
model.compile(optimizer=optimizer, loss=model_func['loss'], metrics=model_func['metrics'])
model.fit(...)

scores = model.evaluate_generator(generator=validation_generator,
                                  workers=10,
                                  use_multiprocessing=True,
                                  verbose=0)

print('%s: %.2f' % (model.metrics_names[0], scores[0])) # Loss
print('%s: %.2f%%' % (model.metrics_names[1], scores[1] * 100)) # metrics1
print('%s: %.2f%%' % (model.metrics_names[2], scores[2] * 100)) # metrics2
print('%s: %.2f%%' % (model.metrics_names[3], scores[3] * 100)) # metrics3

说明:evaluate/evaluate_generator返回值长度等于你指定的评价函数数目+1个损失函数,比如上面代码在compile时指定了1个损失函数(通常损失就只能一个吧)和3个评价函数(回归实验:拟合评价函数R2,误差5准确度,误差10准确度)。
输出:

loss: 27.43
coeff_determination: 85.39%
accuracy_5: 68.46%
accuracy_10: 77.13%

use_multiprocessing=True代表使用多线程预加载batch,这时workers=10代表允许最多10个线程。

注意到不管是evaluate方法需要指定batch_size,还是evaluate_generator需要在generator指定batch_size。如果你设置batch_size不是1,得到评价结果可能就和下面介绍的predict/predict_generator得到结果再去评价是不一样的。
举个例子:
如果使用的是SSE(和方差、误差平方和)损失函数,而batch_size = 10。那么1个batch的SSE是10个验证样本的误差平方和,最总evaluate/evaluate_generator返回的loss则是所以batch的平均SSE。

这里记录一下使用R2评价的坑,假如验证是排序好的,一个batch内的y_true可能非常近似,这就导致TSS很小,而预测的值只要稍微偏离真实值RSS/TSS就会得到非常大的值,导致R2很小。就算把验证集打乱,使用evaluate/evaluate_generator函数得到也只是各个batch的R2平均,是不是和原本R2背离了呢?
R 2 = 1 − F V U = 1 − R S S T S S = 1 − ∑ i ( y i − f i ) 2 ∑ i ( y i − y ^ ) 2 R^{2}=1-\mathrm{FVU}=1-\frac{\mathrm{RSS}}{\mathrm{TSS}}=1-\frac{\sum_{i}\left(y_{i}-f_{i}\right)^{2}}{\sum_{i}\left(y_{i}-\hat{y}\right)^{2}} R2=1FVU=1TSSRSS=1i(yiy^)2i(yifi)2
上式中 y y y 是实际值, f f f 是预测值, y ^ \hat{y} y^ 是实际值的平均值。FVU被称为fraction of variance unexplained, RSS叫做Residual sum of squares, TSS叫做Total sum of squares。根据 R 2 R^{2} R2 的定 义,可以看到 R 2 R^{2} R2 是有可能小于O的,所以R2不是r的平方。一般地, R 2 R^{2} R2 越接近1,表示回归分析中自变量对因变量的解释越好。

predict/predict_generator

和evaluate/evaluate_generator参数差不多,只是不需要标签,返回值变为对应输入的预测输出list。不在赘述。

参考

Model 类(函数式 API)
相关系数r和决定系数R2的那些事
8 Tips for Interpreting R-Squared
What is the difference between Keras model.evaluate() and model.predict()?

from keras import applications from keras.preprocessing.image import ImageDataGenerator from keras import optimizers from keras.models import Sequential, Model from keras.layers import Dropout, Flatten, Dense img_width, img_height = 256, 256 batch_size = 16 epochs = 50 train_data_dir = 'C:/Users/Z-/Desktop/kaggle/train' validation_data_dir = 'C:/Users/Z-/Desktop/kaggle/test1' OUT_CATAGORIES = 1 nb_train_samples = 2000 nb_validation_samples = 100 base_model = applications.VGG16(weights='imagenet', include_top=False, input_shape=(img_width, img_height, 3)) base_model.summary() for layer in base_model.layers[:15]: layer.trainable = False top_model = Sequential() top_model.add(Flatten(input_shape=base_model.output_shape[1:])) top_model.add(Dense(256, activation='relu')) top_model.add(Dropout(0.5)) top_model.add(Dense(OUT_CATAGORIES, activation='sigmoid')) model = Model(inputs=base_model.input, outputs=top_model(base_model.output)) model.compile(loss='binary_crossentropy', optimizer=optimizers.SGD(learning_rate=0.0001, momentum=0.9), metrics=['accuracy']) train_datagen = ImageDataGenerator(rescale=1. / 255, horizontal_flip=True) test_datagen = ImageDataGenerator(rescale=1. / 255) train_generator = train_datagen.flow_from_directory( train_data_dir, target_size=(img_height, img_width), batch_size=batch_size, class_mode='binary') validation_generator = test_datagen.flow_from_directory( validation_data_dir, target_size=(img_height, img_width), batch_size=batch_size, class_mode='binary', shuffle=False ) model.fit_generator( train_generator, steps_per_epoch=nb_train_samples / batch_size, epochs=epochs, validation_data=validation_generator, validation_steps=nb_validation_samples / batch_size, verbose=2, workers=12 ) score = model.evaluate_generator(validation_generator, nb_validation_samples / batch_size) scores = model.predict_generator(validation_generator, nb_validation_samples / batch_size)看看这段代码有什么错误
06-02
from keras.preprocessing.image import ImageDataGenerator from keras.models import Sequential from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D from keras.optimizers import Adam import matplotlib.pyplot as plt import shutil import os # 加载数据集 train_dir = 'path/to/train' val_dir = ''path/to /validation' test_dir = ''path/to /test' batch_size = 20 epochs = 20 img_height, img_width = 150, 150 train_datagen = ImageDataGenerator( rescale=1./255, shear_range=0.2, zoom_range=0.2, horizontal_flip=True ) val_datagen = ImageDataGenerator(rescale=1./255) train_generator = train_datagen.flow_from_directory( train_dir, target_size=(img_height, img_width), batch_size=batch_size, class_mode='categorical' ) val_generator = val_datagen.flow_from_directory( val_dir, target_size=(img_height, img_width), batch_size=batch_size, class_mode='categorical' ) test_generator = val_datagen.flow_from_directory( test_dir, target_size=(img_height, img_width), batch_size=batch_size, class_mode='categorical' ) model = Sequential([ Conv2D(32, (3, 3), activation='relu', input_shape=(img_height, img_width, 3)), MaxPooling2D((2, 2)), Conv2D(64, (3, 3), activation='relu'), MaxPooling2D((2, 2)), Conv2D(128, (3, 3), activation='relu'), MaxPooling2D((2, 2)), Conv2D(128, (3, 3), activation='relu'), MaxPooling2D((2, 2)), Flatten(), Dropout(0.5), Dense(512, activation='relu'), Dense(10, activation='softmax') ]) # 编译模型并指定优化器、损失函数评估指标 model.compile( optimizer=Adam(learning_rate=0.001), loss='categorical_crossentropy', metrics=['accuracy'] ) history = model.fit( train_generator, steps_per_epoch=train_generator.samples // batch_size, epochs=epochs, validation_data=val_generator, validation_steps=val_generator.samples // batch_size ) plt.plot(history.history['accuracy'], label='Training Accuracy') plt.plot(history.history['val_accuracy'], label='Validation Accuracy') plt.legend() plt.show()优化这段代码的验证集的准确率,并加上使用混淆矩阵分析该代码结果的代码
05-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值