keras中model.evaluate()函数使用从flow_from_directory中生成的测试集一直循环问题

目录

一、从test_generator中提取(x_test,y_test)

二、升级TensorFlow或者TensorFlow-gpu后 ,问题得到解决

三、与predict()函数的区别

四、顺序编码 转化成one_hot 编码 或者是 one_hot 转化

五、从数据生成器ImageDataGenerator中的flow_from_directory中获取加载的文件名和相应的类别

问题背景:训练完模型保存后,要用测试集进行模型的评估,查看在测试集上的准确率Accuracy和损失loss,测试集数据是ImageDateGenerator产生的test_data=test_datagen.flow_from_directory(),并没有做数据增强,只做归一化,调用后发现一直循环不停!!!!结果不断地变化….很恼火

batch_size = 32
test_datagen = ImageDataGenerator(rescale=1./255)

test_generator = test_datagen.flow_from_directory(
    directory=test_dir,
    target_size=(224, 224),
    color_mode="rgb",
    batch_size=batch_size,
    class_mode='categorical',

)

#调用保存的模型,进行测试
test_model = models.load_model("feature_extraction_with_data_augmentation.keras")
test_loss, test_acc = test_model.evaluate(test_generator)
print(f"Test accuracy: {test_acc:.3f}")

解决过程:

一、从test_generator中提取(x_test,y_test)

查看model.evaluate()函数的说明,发现evaluate(x_test,y_test)有两个参数,对比发现test_generator就一个参数,这不行啊?于是就萌生了自己将从test_data提出来(test_images,test_labels)的想法。。。累啊。。。一下午的折腾,上代码:

from keras import utils as np_utils
from tensorflow.keras.preprocessing import image
import os

def read_image_files(path,image_size=(224,224)):
    test_files = os.listdir(path)
    print(test_files)
    test_images = []
    #读取测试图片并进行预处理
    for fn in test_generator.filenames:
        img_filename = path + fn
        #print(img_filename)
        img = image.load_img(img_filename,target_size=image_size)
        img_array = image.img_to_array(img)
        test_images.append(img_array)
    test_data = np.array(test_images)
    test_data/=255.0
    print("The test_data shape is:",test_data.shape)

    return test_data

n_classes=5 #数据集中共有5个类别

test_images = read_image_files('./test/')
test_labels = test_generator.classes
print("The test classes:",test_labels)
print("The test_labels shape :",test_labels.shape)

test_labels = utils.to_categorical(test_labels, n_classes) #Convert binary labels to one-hot code

print("One-hot coding test_lables shape :",test_labels.shape)
print("One-hot coding matrix:",test_labels)
print(test_generator.class_indices)  #test_dataSet classes dict
#print(test_generator.filenames)    # test_dataSet image filenames

test_model = keras.models.load_model("feature_extraction_with_data_augmentation.keras")
test_loss, test_acc = test_model.evaluate(test_images,test_labels)
print(f"Test accuracy: {test_acc:.3f}")

x_images:测试集中图像张量,是所有的图像

y_labels: 图像的真实labels

test_generator.filenames :读取generator中的文件名,包括子目录

test_generator.classes :图像的标签,是0 0 1 2 3 4 1 2….的形式,需要转换为one-hot编码

utils.to_categorical(test_tabels,n_classes):将标签转为one-hot编码

keras中model.evaluate()函数使用从flow_from_directory中生成的测试集一直循环问题

二、升级TensorFlow或者TensorFlow-gpu后 ,问题得到解决

但是,第一次会出现以下警告,大意是生成回溯调用。

[En]

For the first time, however, there will be the following warning to the effect that a backtracking call is generated.

keras中model.evaluate()函数使用从flow_from_directory中生成的测试集一直循环问题

原因我查阅了ImageDataGenerator类的说明,应该是通过它产生的数据集是一个无限的重复过程,不是数据集是固定不变。也有建议测试集不要做增强,只做归一化处理即可。

三、与predict()函数的区别

predict()方法
当使用predict()方法进行预测时,返回值是数值,表示样本属于每一个类别的概率,我们可以使用numpy.argmax()方法找到样本以最大概率所属的类别作为样本的预测标签。

预测样本属于每个类别的概率
print(model.predict(imgs))        # 打印概率
[[3.3745366e-01 2.2980917e-02 2.0197949e-03 1.2046755e-02 1.9850987e-03
  1.3152690e-04 4.0220530e-03 1.3779138e-03 5.9722424e-01 2.0758053e-02]
 [5.0913623e-06 5.6117901e-08 9.7215974e-01 2.0343825e-05 2.3693956e-02
  1.6027538e-03 7.3659585e-06 2.5106100e-03 5.8250910e-10 1.4506637e-09]
 [7.1339104e-03 6.1033275e-06 2.1771197e-03 9.7346401e-01 2.2141664e-06
  1.6861971e-02 8.6817810e-05 1.2291509e-04 4.7768017e-06 1.4035056e-04]]

evaluate ()方法

输入 数据(data)金标准(label),然后将预测结果与金标准相比较,得到两者误差并输出。输出 损失精确度.

    # 评估模型,不输出预测结果
    loss,accuracy = model.evaluate(X_test,Y_test)
    print('\ntest loss',loss)
    print('accuracy',accuracy)

四、顺序编码 转化成one_hot 编码 或者是 one_hot 转化

x=[1,2,3,2,1,3,4,5,4,3,2,1,1]
x_one_hot=tf.keras.utils.to_categorical(x)
print(x_one_hot)

五、从数据生成器ImageDataGenerator中的flow_from_directory中获取加载的文件名和相应的类别

使用了densenet进行fine-tune,因为图片数据比较多且占内存因此数据的加载使用ImageDataGenerator生成器,使用flow_from_directory从文件夹中获取各个类别的数据。

因为在测试时,您需要知道哪些数据被误判,并找到相应的文件名。

[En]

Because when testing, you need to know which data has been misjudged, and to find the corresponding file name.

test_datagen = ImageDataGenerator(rescale=1./255)
val_generator = test_datagen.flow_from_directory( test_dir,
                                                  target_size=(img_size, img_size),
                                                  batch_size=32,
                                                  shuffle=False)
print(val_generator.class_indices)   # 输出对应的标签文件夹
print(val_generator.filenames)  # 按顺序输出文件的名字

2022.6.25补充:

循环的原因偶然找到了,其实不是版本的问题,主要是忘了设置steps参数。

test_model.evaluate(test_generator,steps=1)

steps:设置个数值即可解决。。。

Original: https://blog.csdn.net/m0_64748541/article/details/124167189
Author: 青椒炒代码
Title: keras中model.evaluate()函数使用从flow_from_directory中生成的测试集一直循环问题

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/496200/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球