python-3.x - ImageDataGenerator.flow_from_directory 到可在 Kfold 中使用的数据集

标签 python-3.x scikit-learn tensorflow2.0 tf.keras k-fold

我正在尝试对用于将图像分类为 3 类的模型使用交叉验证方法。我使用以下代码导入图像:

train_datagen = ImageDataGenerator(rescale=1./255)
data = train_datagen.flow_from_directory(directory=train_path,
                                       target_size=(300,205), batch_size=8, 
                                       color_mode='grayscale',class_mode='categorical')

在我尝试使用 sklearn.model_selectionKFold 之前,训练模型并测试它效果很好。我在互联网上找到的所有示例都是简单的 numpy 数组,而我有一个分类数组。这意味着图像数组有标签,我无法将此 DirectoryIterator (flow_from_directory 返回一个 DirectoryIterator)转换为可与 kfold.split 一起使用的数组功能。

我尝试了以下方法,请记住我是分类模型的新手:

np_data = data.next()

num_folds = 5
kfold = KFold(n_splits=num_folds, shuffle=True)
for train, test in kfold.split(np_data):

然后我得到: ValueError:分割数 n_splits=5 不能大于样本数:n_samples=2。

我相信我收到此值错误是因为 np_array 内部有 2 个嵌套数组,第一个用于图像,第二个用于其类。

我会尝试仅对图像进行洗牌和折叠,但是如果没有它们所属类别的信息,我无法正确训练我的模型。我尝试按照 this link 中的指南进行操作但他们的测试和训练数据的导入方式似乎与我的数据不同。然后我也遇到了this ,但它对我的情况并没有真正的帮助。

我不知道我缺少什么,任何额外的帮助将不胜感激。

最后我尝试过这样做:

x, y = data.next()
for train, test in kfold.split(x, y):
     ...

当它开始第一次折叠的第一个纪元时,这给了我以下错误:

ValueError:没有为任何变量提供渐变:['conv2d/kernel:0', 'conv2d/bias:0', 'conv2d_1/kernel:0', 'conv2d_1/bias:0', 'conv2d_2/kernel:0', 'conv2d_2/bias:0', 'conv2d_3/kernel:0', 'conv2d_3/bias:0', 'dense/kernel:0', 'dense/bias:0', 'dense_1/kernel :0', 'dense_1/bias:0']。

最佳答案

我得到最后一个ValueError的原因是因为我在使用model.fit()时没有包含y[test]。以下对我来说效果很好。

使用 ImageDataGenerator.flow_from_directory(...) 导入图像后,x, y = data.next() 将图像及其标签生成到 x 和 y 数组中。今后:

kfold = KFold(n_splits=num_folds, shuffle=True)

fold_no = 1
for train, test in kfold.split(x, y):
   model = keras.models.Sequential(.....)
   model.fit(x[train], y[train], epochs=epochs)
   ...
   scores = model.evaluate(x[test], y[test], verbose=0)
   ...
   fold_no = fold_no + 1

我还使用此打印行来跟踪分数:

print(f'Score for fold {fold_no}: {network.metrics_names[0]} of {scores[0]}; {network.metrics_names[1]} of {scores[1]*100}%')

此外,损失和准确度结果可以存储在两个单独的数组中,并在折叠结束时获取平均值。

acc_per_fold.append(scores[1] * 100)
loss_per_fold.append(scores[0])

以上两行必须位于 for 循环内部(for train, test in kfold.split(x, y):),以下两行位于循环外部。

print("\n\n Overall accuracy: " + str(np.average(acc_per_fold)))
print("Overall loss: " + str(np.average(loss_per_fold)))

关于python-3.x - ImageDataGenerator.flow_from_directory 到可在 Kfold 中使用的数据集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65200978/

相关文章:

python - @tf.function ValueError : Creating variables on a non-first call to a function decorated with tf. 函数,无法理解行为

python - 将张量添加到 Tensorflow 中张量的特定列

python - Tensorflow2.0训练: model.编译vs GradientTape

python - O(n) 复杂度算法,无需 remove() 方法即可从未排序的列表中删除值的实例

python - 根据名称将多个文件从单个文件夹移动到多个文件夹

python - 在循环中比较python列表中的数据,直到不能再成对为止

python - 将 StackingClassifier 与训练/测试拆分而不是 CV 一起使用

python - 在 sklearn.svm.SVC(kernel ='rbf' ) 分类器上使用learning_curve 出现虚假 ValueError

Python 类型错误 : can only concatenate list (not "int") to list for Parkes error grid

docker - 使用docker在本地安装Jupyter Notebook:额外命令