Python 为什么我通过使用keras数据生成器和自定义生成器读取相同的图像来获得不同的阵列
摘要:我从数据框中编写了一个定制的流来读取图像。然而,我发现在读取相同图像时,(I)keras数据生成器和定制生成器打印的图像是相同的(ii),但numpy阵列不同 详细信息:(i)我编写了一个生成器,并用定制的生成器替换了Keras生成器(所有其他代码都是复制和粘贴的),但我得到了明显不同的结果(使用定制生成器的一个错误要大5倍)。这就是为什么我调查了两台发电机准备的数据。 (ii)为了确保两个生成器处理相同的图像,我只在数据中放入一个图像,因此batchsize=1。 (iii)为了确保颜色模式为RGB,我使用了keras.preprocessing.image.load_img。 (iv)我通过观察(看起来相同)和观察numpy阵列(不同),比较了两个发生器的图像 代码:Python 为什么我通过使用keras数据生成器和自定义生成器读取相同的图像来获得不同的阵列,python,image-processing,keras,deep-learning,data-generation,Python,Image Processing,Keras,Deep Learning,Data Generation,摘要:我从数据框中编写了一个定制的流来读取图像。然而,我发现在读取相同图像时,(I)keras数据生成器和定制生成器打印的图像是相同的(ii),但numpy阵列不同 详细信息:(i)我编写了一个生成器,并用定制的生成器替换了Keras生成器(所有其他代码都是复制和粘贴的),但我得到了明显不同的结果(使用定制生成器的一个错误要大5倍)。这就是为什么我调查了两台发电机准备的数据。 (ii)为了确保两个生成器处理相同的图像,我只在数据中放入一个图像,因此batchsize=1。 (iii)为了确保颜色
import pandas as pd
import os
from keras.preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
import numpy as np
import keras
import cv2
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
img_size = 256
train_batchsize = 1
df_train = pd.read_csv('data_for_generatorvalidation.csv')
datagen = ImageDataGenerator(rescale=1. / 255)
train_generator1 = datagen.flow_from_dataframe(df_train,directory=None,
x_col='Image',
y_col=targt_vb,
has_ext=True,
batch_size=train_batchsize,
seed=1,
shuffle=False,
class_mode="raw",
target_size=(img_size, img_size),
color_mode='rgb',
interpolation='nearest'
)
np_imgs1, np_values1 = train_generator1[0]
class DataGenerator3(keras.utils.Sequence):
def __init__(self, dataframe, batch_size, dim, shuffle=True, iftest = False):
self.dim = dim
self.batch_size = batch_size
self.dataframe = dataframe.reset_index(drop=True)
self.shuffle = shuffle
self.on_epoch_end()
self.iftest = iftest
def __len__(self):
'Denotes the number of batches per epoch'
return int(np.floor(len(self.dataframe) / self.batch_size))
def __getitem__(self, index):
'Generate one batch of data'
# Generate indexes of the batch
indexes = self.indexes[index * self.batch_size:(index + 1) * self.batch_size]
dataframe_temp = self.dataframe.iloc[indexes]
# Generate data
X, y = self.__data_generation(dataframe_temp)
return X, y
def on_epoch_end(self):
'Updates indexes after each epoch'
self.indexes = np.arange(len(self.dataframe))
if self.shuffle == True:
np.random.shuffle(self.indexes)
def __data_generation(self, dataframe_temp):
'Generates data containing batch_size samples' # X : (n_samples, *dim, n_channels)
# Initialization
X = np.empty((self.batch_size, self.dim[0], self.dim[1], self.dim[2]), dtype=float)
X = X.astype('float32')
y = np.empty((self.batch_size), dtype=float)
file_name = []
dataframe_temp2 = dataframe_temp.reset_index(drop=True)
for [n_index, vector_row] in dataframe_temp2.iterrows():
img_row = vector_row.Image
value_row = vector_row.CI_GHI
img = load_img(img_row)
img = img_to_array(img)
X[n_index,] = img/255.0
y[n_index] = value_row
file_name.append(img_row)
if self.iftest == True:
return X, y, file_name
elif self.iftest == False:
return X, y
params1 = {'batch_size': train_batchsize,
'dim': (img_size, img_size, 3),
'shuffle': False,
'iftest': False}
train_generator2 = DataGenerator3(df_train, **params1)
np_imgs2, np_values2 = train_generator2[0]
for i in range(1):
img1 = np_imgs1[i]
value1 = np_values1[i]
img2 = np_imgs2[i]
value2 = np_values2[i]
fig = plt.figure()
ax1 = fig.add_subplot(1, 2, 1)
ax1.text(.5, 1.1, round(value1, 4), size=20, weight='bold', ha="center",
transform=ax1.transAxes)
ax1.imshow(img1)
ax2 = fig.add_subplot(1, 2, 2)
ax2.imshow(img2)
ax2.text(.5, 1.1, round((value2), 4), size=20, weight='bold', ha="center",
transform=ax2.transAxes)
plt.show()
print(np.array_equal(img1, img2))
图像:生成器的图像输入、两个生成器读入的图像(对于回归问题,值约为y),以及两个生成器的numpy数组快照(您可以在其中找到差异)
您可以将图像嵌入到您的博文中,而不是链接到外部网站。感谢您的留言。我目前没有足够的声誉来发布图像。我对Keras一点都不熟悉,但我想确定你是否知道JPEG是有损的。不同的编码器(写入器)和解码器(读取器)在准确性和性能方面做出不同的权衡。如果您有一个Numpy数组,并将其另存为JPEG格式,然后立即从磁盘读回,则通常会有所不同。是否可以保存为无损PNG?谢谢@MarkSetchell。我以前都不知道。我假设是同一个读卡器(这就是为什么我使用keras.preprocessing.image.load_img而不是其他函数,如cv2、PIL等来加载图像)。我还做了一个快速检查,发现相同的函数(keras.preprocessing.image.load\img)可以通过读取相同的图像来获得相同的数组。你可以将图像嵌入到你的帖子中,而不是链接到外部站点。谢谢你的留言。我目前没有足够的声誉来发布图像。我对Keras一点都不熟悉,但我想确定你是否知道JPEG是有损的。不同的编码器(写入器)和解码器(读取器)在准确性和性能方面做出不同的权衡。如果您有一个Numpy数组,并将其另存为JPEG格式,然后立即从磁盘读回,则通常会有所不同。是否可以保存为无损PNG?谢谢@MarkSetchell。我以前都不知道。我假设是同一个读卡器(这就是为什么我使用keras.preprocessing.image.load_img而不是其他函数,如cv2、PIL等来加载图像)。我还进行了快速检查,发现相同的函数(keras.preprocessing.image.load\u img)可以通过读取相同的图像来获得相同的数组。