如何在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