我训练了一个超分辨率的模型。推理工作如下:
def inference(self, filename):
img_in = misc.imread(filename) / 255.0
res = self.sess.run(self.out, feed_dict={ self.x: [img_in], self.is_training: False, self.lr_input: 0.0 })[0] * 255.0
image = misc.toimage(res, cmin=0, cmax=255)
fn_res = filename.replace(".png", "_result.png").replace(".jpg", "_result.jpg")
misc.imsave(fn_res, image)但是当图像大于600x600px时,它会说:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Aborted (core dumped)我使用16‘m内存和16’m交换文件,使用CPU推断。但是在Ubuntu16.04中设置的swapfile并没有帮助,尽管它已经足够了。
我知道我可以通过将图像分割成碎片并按顺序处理来解决这个问题。但是在输出中有明显的分裂标记。
为什么不动呢?有任何方法可以使用Python或Tensorflow实现内存交换文件吗?还有其他解决办法吗?
发布于 2018-09-17 23:15:24
通过将图像分割成碎片,一个一个地处理,然后将它们组合在一起来解决问题。为了避免输出图像中可见的“分割线”,我重复上面描述的不同尺寸的过程,并计算平均值。
最后我得到了这个:
def inference(self, filename, self_ensemble=False):
img_q = Image.open(filename)
scale = 4
if img_q.width > 400:
total = np.zeros((img_q.height * scale, img_q.width * scale, 3))
#repeat 7 times with different piece size
for x in range(7):
total += self.inference_inter(filename, scale, 32 * (x + 8), ensemble=self_ensemble)
total = total / 7.0
image = misc.toimage(total, cmin=0, cmax=255)
fn_res = filename.replace(".png", "_result.png").replace(".jpg", "_result.jpg")
misc.imsave(fn_res, image)
else:
img_in = misc.imread(filename) / 255.0
res = self.sess.run(self.out, feed_dict={ self.x: [img_in], self.is_training: False, self.lr_input: 0.0 })[0] * 255.0
image = misc.toimage(res, cmin=0, cmax=255)
fn_res = filename.replace(".png", "_result.png").replace(".jpg", "_result.jpg")
misc.imsave(fn_res, image)
def inference_inter(self, filename, scale, pat_size, ensemble=True):
img_in = misc.imread(filename) / 255.0
img_q = Image.open(filename)
res = np.zeros((img_q.height * scale, img_q.width * scale, 3))
for qx in range(0, img_q.width, pat_size):
for qy in range(0, img_q.height, pat_size):
res[(qy * scale):((qy + pat_size) * scale)][(qx * scale):((qx + pat_size) * scale)] = self.sess.run(self.out, feed_dict={ self.x: [img_in[qy:(qy + pat_size)][qx:(qx + pat_size)]], self.is_training: False, self.lr_input: 0.0 })[0] * 255.0
return res发布于 2018-10-01 10:13:53
本文讨论了您的问题,并解释了其存在的原因:
https://dl.acm.org/citation.cfm?id=3132847.3132872
如果您无法访问它,下面是一些cites /一个摘要:
有两个问题:填充和规范化。
衬垫:
在进行卷积时,网络需要填充图像边界上缺失的像素值。这是因为前两个边框像素的内核位于所提供的图像之外。
正常化:
在卷积网络中,采用批归一化技术来加快收敛速度,减少内部协变量转移。 现在,假设我们把图像分割成两个子图像。我们买了两小批。如果它们独立地通过CNN,我们将得到两个归一化结果,它们只适用于子图像的局部均值和计算中的方差。因此,即使我们将这些片段合并回一个图像,我们也会得到一个与整个图像生成的结果视觉上不同的结果。
他们提出以下解决办法:
衬垫:
对于内部边界,我们使用了一种新的填充技术,字典填充。
这意味着它们使用相邻子图像的相应像素值。
对于外部边界,我们使用圆形衬垫.
这意味着您将图像左侧的像素放在右边,就好像您已经将图像连接在右边(反之亦然)。(与上底相同)
正常化:
这有点复杂。最后,它们将子图像规范化,共享图像之间的归一化值(均值和方差),并将它们组合在一起。
填充可能很容易实现,但我不知道如何使用tensorflow实现规范化部分。如果有人想清楚,并发送一些代码,我将非常感激。
https://stackoverflow.com/questions/52375305
复制相似问题