我有一个带有两列的pandas数据框,一列具有图像的路径,另一列具有字符串类标签。
我还编写了以下函数,这些函数从数据帧加载图像,对其进行规范化并将类标签转换为一键矢量。
def prepare_data(df):
data_X, data_y = df.values[:,0], df.values[:,1]
# Load images
data_X = np.array([np.array(imread(fname)) for fname in data_X])
# Normalize input
data_X = data_X / 255 - 0.5
# Prepare labels
data_y = np.array([label2int[label] for label in data_y])
data_y = to_categorical(data_y)
return data_X, data_y
我想将此数据帧提供给Keras CNN,但整个数据集太大而无法立即加载到内存中。
这个站点上的其他答案告诉我,为此,我应该使用Keras ImageDataGenerator,但是老实说,我不理解如何从文档中做到这一点。
将延迟加载的批次中的数据馈送到模型的最简单方法是什么?
如果它是ImageDataGenerator,我该如何创建一个ImageDataGenerator来对Dataframe进行初始化,并将批处理通过我的函数传递以创建适当的numpy数组?以及如何使用ImageDataGenerator拟合模型?
ImageDataGenerator
是一个高级类,它允许从多个来源(从np arrays
,从目录…)产生数据,并且包括执行图像增强等功能的实用程序功能。
更新
从keras-preprocessing
1.0.4开始,ImageDataGenerator
提供了flow_from_dataframe
一种解决您的情况的方法。它要求dataframe
和directory
参数定义如下:
dataframe: Pandas dataframe containing the filenames of the
images in a column and classes in another or column/s
that can be fed as raw target data.
directory: string, path to the target directory that contains all
the images mapped in the dataframe.
因此,您不再需要自己实施它。
下面的原始答案
对于您的情况,使用描述的数据框,您还可以编写自己的自定义生成器,该生成器将prepare_data
函数中的逻辑用作更简单的解决方案。最好使用Keras的Sequence
对象这样做,因为它允许使用多重处理(如果您使用的是gpu,这将有助于避免瓶颈)。
您可以签出有关对象的文档Sequence
,其中包含一个实现示例。最终,您的代码将遵循以下原则(这是样板代码,您将不得不添加诸如label2int
函数或图像预处理逻辑之类的细节):
from keras.utils import Sequence
class DataSequence(Sequence):
"""
Keras Sequence object to train a model on larger-than-memory data.
"""
def __init__(self, df, batch_size, mode='train'):
self.df = df # your pandas dataframe
self.bsz = batch_size # batch size
self.mode = mode # shuffle when in train mode
# Take labels and a list of image locations in memory
self.labels = self.df['label'].values
self.im_list = self.df['image_name'].tolist()
def __len__(self):
# compute number of batches to yield
return int(math.ceil(len(self.df) / float(self.bsz)))
def on_epoch_end(self):
# Shuffles indexes after each epoch if in training mode
self.indexes = range(len(self.im_list))
if self.mode == 'train':
self.indexes = random.sample(self.indexes, k=len(self.indexes))
def get_batch_labels(self, idx):
# Fetch a batch of labels
return self.labels[idx * self.bsz: (idx + 1) * self.bsz]
def get_batch_features(self, idx):
# Fetch a batch of inputs
return np.array([imread(im) for im in self.im_list[idx * self.bsz: (1 + idx) * self.bsz]])
def __getitem__(self, idx):
batch_x = self.get_batch_features(idx)
batch_y = self.get_batch_labels(idx)
return batch_x, batch_y
您可以像自定义生成器一样传递此对象来训练模型:
sequence = DataSequence(dataframe, batch_size)
model.fit_generator(sequence, epochs=1, use_multiprocessing=True)
如下所述,不需要实现改组逻辑。shuffle
只需True
在fit_generator()
调用中将参数设置为即可。从文档:
shuffle:布尔值。是否在每个纪元开始时重新整理批次的顺序。仅用于Sequence实例(keras.utils.Sequence)。当steps_per_epoch不为None时无效。
问题内容: 我正在加载一个包含浮点和字符串数据混合的txt文件。我想将它们存储在可以访问每个元素的数组中。现在我正在做 这是输入文件的结构:。 现在,数据将作为唯一列导入。我如何划分它,以便分别存储不同的元素(所以我可以调用)?以及如何定义标题? 问题答案: 您可以使用: 添加您的代码,在引号之间留一个空格。因此,熊猫可以检测值之间的空格并按列排序。数据列用于命名您的列。
问题内容: 我有两个,都被索引。我需要将元素添加在一起以形成一个new ,但前提是索引和列相同。如果该项不存在于之一,则应将其视为零。 我试过使用,但这无论索引和列如何。还尝试了一个简单的方法,但是如果两个数据框都没有该元素,则给出a 。 有什么建议? 问题答案: 怎么样
我有一个熊猫数据框,它有语料库的术语频率,术语为行,年份为列,就像这样: 我希望能够通过将每个单词的值除以给定年份的总单词数来标准化它们——有些年份包含两倍多的文本,所以我试图按年缩放(像谷歌图书一样)。我已经看了如何缩放单个列的例子,克里斯·阿尔邦和我在SO上看到了缩放所有列的例子,但是每次我试图将这个数据框转换为一个数组来缩放时,事情都会窒息列这个词不是数字。(我尝试将术语列设置为索引,但不太
问题内容: 我遇到了一个看似简单的问题:在熊猫数据框中删除唯一的行。基本上与的相反。 假设这是我的数据: 当A和B唯一时,我想删除行,即我只保留行1和2。 我尝试了以下方法: 但是我只能得到第2行,因为唯一性是0、1和3! 问题答案: 选择所有重复行的解决方案: 您可以使用子集和参数来选择所有重复项: 解决方案: 对所有唯一行进行了一些修改的解决方案:
问题内容: 我想从“ tweets”列中删除停用词。如何遍历每一行和每一项目? 问题答案: 使用列表理解 返回值:
问题内容: 这可能很容易,但是我有以下数据: 在数据框1中: 在数据框2中: 我想要一个具有以下形式的数据框: 我尝试使用该方法,但是得到了交叉连接(即笛卡尔积)。 什么是正确的方法? 问题答案: 通常看来,您只是在寻找联接:
我想使用两列作为行ID,同时计算基于时间的分组。请看下图: 转化成这样: 正在发生的是,X在时间10发生了0次,但在15和23发生了1次。 Y在10点钟发生了3次,但在15和23没有。等等。
问题内容: 我有python pandas dataframe,其中一列包含月份名称。 如何使用字典进行自定义排序,例如: 问题答案: 熊猫0.15引入了“分类系列”,该分类系列提供了一种更清晰的方法: 首先,将月份列设为分类,然后指定要使用的顺序。 现在,当您对月份列进行排序时,它将相对于该列表进行排序: 注意:如果值不在列表中,它将被转换为NaN。 对于那些有兴趣的人来说,是一个较旧的答案。