如何在keras中按键加载图像数据?

如何在keras中按键加载图像数据?,keras,Keras,我一直在研究一个序列模型,它将图像作为输入。然而,不同的是,输入图像实际上是由键决定的。 例如,训练序列是(您可以假设fi是视频的帧id) 并且对应的图像序列是 { M[f1], M[f2], M[f3], ..., M[fn] } 其中M是存储{fi->image}映射的映射。 假设在下一批中,我的训练序列 { f2, f3, ..., fn+1 } 并且图像序列变为 { M[f2], M[f3], M[f4], ..., M[fn+1] } 如您所见,如果我直接将图像序列保存到磁盘

我一直在研究一个序列模型,它将图像作为输入。然而,不同的是,输入图像实际上是由键决定的。
例如,训练序列是(您可以假设fi是视频的帧id)

并且对应的图像序列是

{ M[f1], M[f2], M[f3], ..., M[fn] }
其中M是存储{fi->image}映射的映射。
假设在下一批中,我的训练序列

{ f2, f3, ..., fn+1 }  
并且图像序列变为

{ M[f2], M[f3], M[f4], ..., M[fn+1] }
如您所见,如果我直接将图像序列保存到磁盘中,会有很多冗余(在上述情况下,M[f2]到M[fn]会保存两次)。因此,似乎有必要使用键引用图像,因此不能使用imagedataloader类。
[编辑]
我的模型是一个2类分类器,将图像序列作为输入,其中图像映射为帧id(fi)。在我的数据预处理代码中预生成图像序列是正还是负。
阳性样本可能如下所示:

{f3,  f4,  f5,  f6,  f7}     1
{f4,  f5,  f6,  f7,  f8}     1
{f5,  f6,  f7,  f8,  f9}     1
...
{f1,  f2,  f3,  f4,  f5}     0
{f2,  f3,  f4,  f5,  f6}     0
{f10, f11, f12, f13, f14}    0
...
|-data_root/
  |-Video 1/
  | |-frame_1_1.jpg
  | |-frame_1_2.jpg
  | ...
  |-Video 2/
  | |-frame_2_1.jpg
  | |-frame_2_2.jpg
  | ...
  ...
  ...
  |-Video N/
  | |-frame_N_1.jpg
  | |-frame_N_2.jpg
    ...
阴性样本如下所示:

{f3,  f4,  f5,  f6,  f7}     1
{f4,  f5,  f6,  f7,  f8}     1
{f5,  f6,  f7,  f8,  f9}     1
...
{f1,  f2,  f3,  f4,  f5}     0
{f2,  f3,  f4,  f5,  f6}     0
{f10, f11, f12, f13, f14}    0
...
|-data_root/
  |-Video 1/
  | |-frame_1_1.jpg
  | |-frame_1_2.jpg
  | ...
  |-Video 2/
  | |-frame_2_1.jpg
  | |-frame_2_2.jpg
  | ...
  ...
  ...
  |-Video N/
  | |-frame_N_1.jpg
  | |-frame_N_2.jpg
    ...
所以,这不像图像分类问题,图像有一个固定的标签。在我的例子中,每个图像都会被多次使用,它们的正或负是由整个序列共同决定的,而不是它本身。
[编辑II]
图像是N个视频的帧,存储在磁盘上,如下所示:

{f3,  f4,  f5,  f6,  f7}     1
{f4,  f5,  f6,  f7,  f8}     1
{f5,  f6,  f7,  f8,  f9}     1
...
{f1,  f2,  f3,  f4,  f5}     0
{f2,  f3,  f4,  f5,  f6}     0
{f10, f11, f12, f13, f14}    0
...
|-data_root/
  |-Video 1/
  | |-frame_1_1.jpg
  | |-frame_1_2.jpg
  | ...
  |-Video 2/
  | |-frame_2_1.jpg
  | |-frame_2_2.jpg
  | ...
  ...
  ...
  |-Video N/
  | |-frame_N_1.jpg
  | |-frame_N_2.jpg
    ...
我想做的是,给定场景的两个帧/图像序列,模型预测这两个场景是否属于同一类型。
由于视频可能包含每个场景的较长时间跨度,我将场景的整个序列划分为多个非重叠子序列(忽略视频索引):

然后,我随机生成阳性样本Pi(从相同的序列生成的子序列对),如下所示:


P1{子序列i_4,子序列i_2},1
P2{子序列i_3,子序列i_5},1
...                                       ...
对于负采样,我从不同的场景生成成对的子序列(Ni):

   <Pair of sub-sequences>                 <Labels>
N1 {sub-sequence i_1, sub-sequence j_6},      0
N2 {sub-sequence i_2, sub-sequence j_4},      0
...                                       ...

N1{子序列i_1,子序列j_6},0
N2{子序列i_2,子序列j_4},0
...                                       ...
很明显,一帧/图像可以在不同的训练样本中多次出现。例如,在上述情况下,N2和P1都包含子序列i_2。因此,我选择按帧id序列(fi)保存生成的样本对,并在训练期间按帧id(fi)获取序列的相应帧/图像。

我该如何优雅地使用Keras

不确定如何构建序列,但您是否考虑过使用

使用所需的任何参数构建此对象后,可以使用
flow\u from\u directory(directory\u path)
方法。完成此操作后,可以使用此对象的filename属性:

my_generator = ImageDataGenerator(...)
my_generator.flow_from_directory(path_dir)
list_of_file_names = my_generator.filename
现在,列表的索引和列表的元素(=文件路径)之间有了映射

我希望这有帮助

编辑:

从这里,您可以构建一个映射到词汇表

map_images = {str(os.path.splitext(os.path.split(file_path)[1])[0]): file_path for file_path in list_of_file_names}
这将获取使用ImageDataGenerator从图像文件夹中检索到的
文件路径
,它提取文件名,删除文件扩展名,并将文件名转换为一个
字符串
,该字符串是您的帧id

现在,您可以使用
frame\u id
file\u path
之间的映射

函数
load\u img()
的定义如下,并返回一个PIL图像实例:

def load\u img(路径,灰度=假,目标大小=无):
“”“将图像加载为PIL格式。
#论据
路径:图像文件的路径
灰度:布尔值,是否以灰度加载图像。
目标大小:无(默认为原始大小)
或整数的元组“(img_高度,img_宽度)”。
#返回
一个PIL映像实例。
#提高
ImportError:如果PIL不可用。
“”“

然后,
img\u to\u array()
的定义如下,并返回一个3D numpy数组以馈送您的模型:

def img_to_数组(img,dim_ordering='default'):
“”“将PIL映像实例转换为Numpy数组。
#论据
img:PIL图像实例。
尺寸顺序:图像数据格式。
#返回
三维Numpy阵列。
#提高
ValueError:如果传递了无效的“img”或“dim_ordering”。
"""

总结一下:1在frame_id和相应文件的路径之间建立一个映射。然后使用
img\u load()
img\u to\u array()
加载文件。我希望我正确理解了你的问题

编辑2:

看到您的新编辑,现在我了解了您的文件系统结构,我们甚至可以在您的字典中添加视频,如下所示:

# list of video_id of each frame
videos = my_generator.classes
# mapping of the frame_id to path_of_file and vid_id
map_images = {str(os.path.splitext(os.path.split(file_path)[1])[0]): (file_path, vid_id) for file_path,vid_id in zip(list_of_file_names,videos) }

你可以通过将想法分成几段(简单的两行换行)来充分发挥问题的价值。您还可以用Graves(1旁边的类似撇号的键)
围绕代码位,如下所示。代码块可以用两个换行符显示,每行用四个空格缩进。这些图像序列是否总是有这种形式的顺序索引,或者可以有类似f1、f3、f2、f5的索引?它们是如何存储在磁盘上的?你的目录结构是什么?这个用于标记数据的预处理函数是什么样子的?谢谢回答!我已经编辑了我的问题。我希望我已经把我的问题说清楚了。正如您所看到的,同一图像在训练期间可能会被多次使用,并且包含该图像的序列标签可能是正的,也可能是负的。因此,为了节省空间,生成的序列是act