Closed ylz1104 closed 3 years ago
谢谢,-2那里似乎是笔误? 确实应该继续加上当前文件的偏移量。我看了一下,似乎得改成:
# move backward
reminder = self.cur_fd.tell()
while self.read_pointer - reminder > target:
self.read_pointer -= reminder
self.cur_fd.close()
self.cur_fd = self.read_file[-1].open('rb')
self.file.insert(0, self.read_file.pop())
reminder = self.cur_fd.tell()
self.cur_fd.seek(target - self.read_pointer, SEEK_CUR)
self.read_pointer = target
2.之前原来的代码做了一个判断,一个可以理解为target在最后一个文件里,另一个是target在之前的文件里,那么如果target在之前的文件里,最起码应该从read_file的-2的文件开始查找,而最后一个文件会被pop到file里。
3.我不知道我描述的够不够清楚,感觉您的代码也是稍微有点复杂,处理data的时候感觉内存应用会很大; 而且我看到文件处理用的是线程,对python来说用进程会不会更好的处理数据。
VirtualFile的初衷用来处理3种情况:
多线程(mt)处理IO并发足够了,如果是进程(mp)的话,不同进程在通过pickle传输子进程图像数据的时候反而造成性能瓶颈。 通过预读文件进内存来加速单个epoch的训练,使瓶颈不在文件IO上。从速度来看远远大于pytorch的Dataset挨个解码,或者带压缩的lmdb等数据结构。
VirtualFile的源码按照我的修改应该不会影响depth=1和depth>1的情况
感谢您的解答,我看到了图像调用read进行读取,再pickle序列化给子进程处理确实会影响性能。通过prefetch确实一定程度上平衡了IO与model训练之间的问题。
目前我还没有看Loader部分的源码,不知道与一年前版本的源码有什么区别。 之前我用过您的代码训练过vespcn,还提过问题,在训练模型后进行inference的时候,我发现数据IO确实有些问题,一个是在url中的图片不能过多,一个是对图片的中间处理不知道什么原因耗时较长,导致inference时间较长。
我想冒昧的问一下为什么不使用tensorflow的Data模块来处理数据呢?
因为大家都想使用VESPCN这种实时模型,也感觉现在论文方向VSR太注重质量也忽视速度问题,毕竟是low-level而且在工业方面需求也高,我很想解决速度问题,现在除了量化和gpu加速没别的什么办法了。
我本来计划写一个类似的project,包含tf和pytorch,写了一部分,但是就是在data和loader部分很不完善。现在感觉您的方案很好,我也在这个上面复现了新的模型,如JSI_GAN等。又加了一些data argument方法。
我之前是一直使用Data来做,处理数据我也是将视频转为RGB图像序列,再使用Data。之前我用vespcn就是使用的这个做inference数据加载,按效率来讲,您原来的代码是7s出一帧4k图像,我没怎么看loader部分的源码,所以不知道是什么原因导致的,但是使用Data可以达到0.7s出一帧。我不知道您有没有做过这方面的对比。还有可能也是我一般使用opencv处理图像,我测试在速度上好像比pillow要好一点。
除了莽,还可以思考
前几周的Loader有一些重复处理,在训练上效率很低,我现在的vespcn也远大于3个卷积层,不知道是不是这方面的原因。 单从数据加载的角度应该不会有10倍的差距,我下来看一看。pillow和opencv包括tensorflow.image的底层实现都差不多,解码png都是libpng,差别不会太大。
轻量级模型在特征提取方面会稍显不足,其实许多论文中对图像类似条纹状的放大来看就明白了,对细节的描述能力不强。还有对于不同视频数据集来说,很难达到一致的指标水平,这个在实际工作中是很重要的问题,我个人比较青睐dynamic filter这种解决思路,也看到了类似插件式的CARAFE这种轻量式设计,可以嵌入其他模型中。而且,高参数量意味着可能会有高质量的特征提取和细节表达,但是参数量与推理速度不一定是呈线性关系的。
关于real-world偏移的问题,其实现实很难获得这方面的数据集,目前我知道的有Real_SR。大家都在降质核和去噪方向上努力。 没办法,能力有限,还需要继续学习,开拓一下新视野。
回到这个问题本身,这部分代码段仅针对RawFile
类型。对于RawFile
类型,有且仅有一个文件FD,所以这里的逻辑是:
当seek到文件头之前,重新回到文件头而已。
不应该存在多个文件连续seek的情况。
self.read_pointer -= reminder self.cur_fd.close() self.cur_fd = self.read_file[-1].open('rb') self.file.insert(0, self.read_file.pop())
我觉得应该改成self.read_pointer -= reminder self.cur_fd.close() self.cur_fd = self.read_file[-2].open('rb') self.cur_fd.seek(0,SEEK_END) self.file.insert(0, self.read_file.pop())