ImageDataGenerator.flow_from_directory 到可以在 Kfold 中使用的数据集
ImageDataGenerator.flow_from_directory to a dataset that can be used in Kfold
我正在尝试对我用于 class 将图像转换为 3 class 的模型使用交叉验证方法。我使用以下代码导入图像:
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_selection
的 KFold
之前训练和测试模型效果很好。我在互联网上找到的所有示例都是简单的 numpy 数组,而我有一个 classification 数组。这意味着图像数组有标签,我无法解决将这个 DirectoryIterator
(flow_from_directory returns DirectoryIterator)转换为可与 kfold.split
一起使用的数组功能。
我尝试了以下方法,请记住我是 class化模型的新手:
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 个嵌套数组,第一个用于图像,第二个用于它们的 classes。
我会尝试仅对图像进行洗牌和折叠,但是如果没有信息 class 它们属于什么,我将无法正确训练我的模型。我已尝试按照 this link but the data for their testing and training seem to be imported in a different way than I have my data. Then I came across also 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)))
我正在尝试对我用于 class 将图像转换为 3 class 的模型使用交叉验证方法。我使用以下代码导入图像:
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_selection
的 KFold
之前训练和测试模型效果很好。我在互联网上找到的所有示例都是简单的 numpy 数组,而我有一个 classification 数组。这意味着图像数组有标签,我无法解决将这个 DirectoryIterator
(flow_from_directory returns DirectoryIterator)转换为可与 kfold.split
一起使用的数组功能。
我尝试了以下方法,请记住我是 class化模型的新手:
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 个嵌套数组,第一个用于图像,第二个用于它们的 classes。
我会尝试仅对图像进行洗牌和折叠,但是如果没有信息 class 它们属于什么,我将无法正确训练我的模型。我已尝试按照 this link but the data for their testing and training seem to be imported in a different way than I have my data. Then I came across also 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)))