Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 当列车图像太大而无法一次送入网络时,如何处理?_Python_Tensorflow_Deep Learning_Unity3d Unet - Fatal编程技术网

Python 当列车图像太大而无法一次送入网络时,如何处理?

Python 当列车图像太大而无法一次送入网络时,如何处理?,python,tensorflow,deep-learning,unity3d-unet,Python,Tensorflow,Deep Learning,Unity3d Unet,我用它来做肺部图像配准。但是我的火车图像太大,无法输入网络,图像的形状不同,形状也不规则。有些是513436…(不是2的幂,所以我不能直接使用U-NET或其他CNN) 为了解决这些问题,我将列车图像拆分为128x128x128子图像,步长为100。看起来是这样的: 在预测阶段,我还将图像分割成若干子图像,使用网络对每个子图像进行预测,然后对结果进行组合。但问题是子图像的边界与内部区域看起来不同,如下所示: 我天真的方法是平滑的,但我发现它不起作用。我认为这是一个普遍的问题。如何解决这个问题?

我用它来做肺部图像配准。但是我的火车图像太大,无法输入网络,图像的形状不同,形状也不规则。有些是513436…(不是2的幂,所以我不能直接使用U-NET或其他CNN)

为了解决这些问题,我将列车图像拆分为128x128x128子图像,步长为100。看起来是这样的:

在预测阶段,我还将图像分割成若干子图像,使用网络对每个子图像进行预测,然后对结果进行组合。但问题是子图像的边界与内部区域看起来不同,如下所示:

我天真的方法是平滑的,但我发现它不起作用。我认为这是一个普遍的问题。如何解决这个问题?请帮忙

这个数据问题有点不同。因为一个简单的火车图像的形状超过300x300x300。所以不是整个数据集太大,一个简单的数据太大

例如:

(430, 318, 168)  
(434, 354, 349)  
(428, 290, 439)  
(446, 290, 466)  
(452, 382, 373)  
(464, 290, 378)  
(424, 278, 217)  
(308, 202, 109)  
(420, 312, 537)  
(444, 314, 399)  
(418, 368, 323)  
(384, 432, 396)  
(412, 282, 408)  
(314, 188, 239)  
(428, 308, 422)  
(412, 302, 471)  
(276, 158, 127)  
(384, 432, 396)  
(394, 322, 370)  
(412, 322, 289)  
(412, 296, 458)  
(323, 250, 127)  
(448, 296, 431)  
(420, 302, 446)  
(438, 314, 393)  
(386, 424, 386) 
骨网是这样的:

def conv_block(x_in, nf, strides=1):
    """
    specific convolution module including convolution followed by leakyrelu
    """
    ndims = len(x_in.get_shape()) - 2
    assert ndims in [1, 2, 3], "ndims should be one of 1, 2, or 3. found: %d" % ndims

    Conv = getattr(KL, 'Conv%dD' % ndims)
    x_out = Conv(nf, kernel_size=3, padding='same',
                 kernel_initializer='he_normal', strides=strides)(x_in)
    x_out = LeakyReLU(0.2)(x_out)
    return x_out

def unet_core(vol_size, enc_nf, dec_nf, full_size=True, src=None, tgt=None, src_feats=1, tgt_feats=1):
    """
    unet architecture for voxelmorph models presented in the CVPR 2018 paper. 
    You may need to modify this code (e.g., number of layers) to suit your project needs.
    :param vol_size: volume size. e.g. (256, 256, 256)
    :param enc_nf: list of encoder filters. right now it needs to be 1x4.
           e.g. [16,32,32,32]
    :param dec_nf: list of decoder filters. right now it must be 1x6 (like voxelmorph-1) or 1x7 (voxelmorph-2)
    :return: the keras model
    """
    ndims = len(vol_size)
    assert ndims in [1, 2, 3], "ndims should be one of 1, 2, or 3. found: %d" % ndims
    upsample_layer = getattr(KL, 'UpSampling%dD' % ndims)

    # inputs
    if src is None:
        src = Input(shape=[*vol_size, src_feats])
    if tgt is None:
        tgt = Input(shape=[*vol_size, tgt_feats])
    x_in = concatenate([src, tgt])


    # down-sample path (encoder)
    x_enc = [x_in]
    for i in range(len(enc_nf)):
        x_enc.append(conv_block(x_enc[-1], enc_nf[i], 2))

    # up-sample path (decoder)
    x = conv_block(x_enc[-1], dec_nf[0])
    x = upsample_layer()(x)
    x = concatenate([x, x_enc[-2]])
    x = conv_block(x, dec_nf[1])
    x = upsample_layer()(x)
    x = concatenate([x, x_enc[-3]])
    x = conv_block(x, dec_nf[2])
    x = upsample_layer()(x)
    x = concatenate([x, x_enc[-4]])
    x = conv_block(x, dec_nf[3])
    x = conv_block(x, dec_nf[4])

    # only upsampleto full dim if full_size
    # here we explore architectures where we essentially work with flow fields 
    # that are 1/2 size 
    if full_size:
        x = upsample_layer()(x)
        x = concatenate([x, x_enc[0]])
        x = conv_block(x, dec_nf[5])

    # optional convolution at output resolution (used in voxelmorph-2)
    if len(dec_nf) == 7:
        x = conv_block(x, dec_nf[6])

    return Model(inputs=[src, tgt], outputs=[x])

有一篇文章提到CNN中的大图像,它使用自适应填充解决了边界问题,但描述不清楚。我认为这类似于重叠策略。

如果您的问题可以通过将形状大小设置为2的倍数来解决,我建议使用openCV

您可以简单地通过添加白/黑边框来展开图像。您还可以缩放图像,这取决于在您的情况下哪个效果更好

另一个选项-运行ImageMagic以增加较小图像的图像大小。 例如:


这将使较小图像的大小增加4倍。

解决方案

您好@ruokuanwu这是一个非常常见的问题,我们有很多数据需要在深度学习中进行训练,但我们无法一次将所有数据存储到我们的内存中。数据可能以TB为单位,因此为了解决此问题,keras具有从目录中流出的功能。通过此功能,keras将能够直接从磁盘获取批处理。现在我们不必一次上传所有数据。此功能从磁盘中取出一批数据,将其加载到内存中,并将其馈送到模型中进行处理。这样就解决了大数据集的训练问题

您可以在这里看到通过图像生成器进行训练的示例

要求:


如果您正在进行图像分类,您必须将每个类别放在单独的文件夹中,并给出单独类别文件夹所在的父文件夹的路径。

对于U-net模型,可以将输入拆分为多个部分并单独处理

需要注意的一点是图像的边界:将256x256分割为4幅128x128的图像可能会在分割时产生明显的边界(图像中心的十字)。为了避免这种情况,分割图像时稍微重叠,忽略边界是有意义的

换句话说。对于大小为256x256的图像,而适合内存的最大可能输入为128,请遵循下一个算法:

  • 选择边框大小。对于具有4个下采样层的unet,合理的做法是选择与2^U下采样数=2^4=16成比例的边界
  • 将输入图像分割成96x96的正方形,其中96=128-2*边框大小
  • 对于每一个正方形,从每一侧附加另一个16px,形成原始图像。产生128x128的图像
  • 处理完图像后,切掉96x96的内部正方形,并用它缝合最终预测

  • 如果voxelmorph实现了传统配准的结果,例如将运动图像配准到固定图像,那么听起来您只需要调整输入图像的大小,以便形状符合神经网络的输入形状。如果图像具有特殊形状(2的倍数),voxelmorph只需使用U形网络作为骨骼,它们可以使用体素变形进行训练。但是我的火车图像的形状不符合这一点,形状不同,不是2的倍数,主要是图像太大,无法训练。如果我将其拆分,则从子图像的结果合成的最后一个结果具有“边界”。如何组合预测图像?你的主干网有多少个下/上采样层?只有4个采样层。@ruokuanwu如果你有4个下采样层,这意味着图像两端的16px会受到影响。我建议在96px(128-16*2)的步骤进行采样,并且在缝合预测时仅使用内部96x96静噪,将每侧的16px忽略为噪声或无关。请让我们知道,如果你尝试它之间的火车图像差异太大。如果我使用最大num作为轴的标准长度(2的倍数),则一些较小形状的图像将被许多零或其他(恒定填充或反射填充)填充。我认为主要问题不是形状是否为2的倍数,主要是简单的火车图像太大,无法训练一次。当我将它分割成子图像,然后合并子结果时,存在一个“边界问题”。有一些差异,我添加了一些关于数据的细节。
    magick convert -resize 400% smallImage.png Enlarged.png