【问题标题】:Inputs to Unet CNN(Unet) type structuresUnet CNN(Unet) 类型结构的输入
【发布时间】:2022-08-04 18:22:19
【问题描述】:

我一直在完成我的论文(脑语义分割和生存预测以及基因组学)。在处理成像部分时,我遵循了文献并了解到分割大脑的少数体面方法中的一些是使用 Unets。我看到了这些的 2D 和 3D 实现,它们以奇怪的方式制作数据集。由于这是我的论文,我不想直接抄袭别人的作品,所以我必须自己做一些事情。我被困在一个特定的部分,我无法让我的输入连接到网络。据我了解,网络需要获取 2D 图像 (H,W) ,一个通道用于您尝试一起传递的图像数量,另一个通道用于您尝试分割的类别数量。在这种情况下,我从 \'18, \'19, \'20 中获取了 BraTS 数据集。从初始数据集中,我解压缩 nifti 文件并使用 NLM 过滤和 N4BiasFieldCorrection 执行双步预处理,然后我将图像保存在 Z 轴上的 2D 切片中(这转化为每种模态(flair,t1,t1c,t2)得到它\ 自己的文件夹包含 155.png 图像。对于掩码,我只是将 4 个类编码为 [0,1,2,3] 并将它们保存为 Z 轴上的 2D png。

我使用以下代码来创建我的自定义生成器。

import numpy as np
from skimage.io import imread
from keras.utils import to_categorical

def load_img(file_list):
    images = []
    for i in range(len(file_list)):
        x = imread(file_list[i])
        norm_img = (x - np.min(x)) / (np.max(x) - np.min(x))
        images.append(norm_img)
    images = np.array(images)

    return (images)


def load_mask(file_list):
    masks = []
    for i in range(len(file_list)):
        mask = imread(file_list[i])
        enc_mask = to_categorical(mask, num_classes=4)
        masks.append(enc_mask)
    masks = np.array(masks)

    return masks


def imageLoader(img_list, mask_list, batch_size):
    L = len(img_list)

    while True:

        batch_start = 0
        batch_end = batch_size

        while batch_start < L:
            limit = min(batch_end, L)

            X = load_img(img_list[batch_start:limit])
            Y = load_mask(mask_list[batch_start:limit])

            yield (X, Y)  # tuple

            batch_start += batch_size
            batch_end += batch_size

\'to_categorical\' 步骤存在问题,我认为这是因为每当它到达没有 4 个当前类的图像时,它就会崩溃。

我接触的 Unet 架构是 https://github.com/jordan-colman/DR-Unet104/blob/main/Dr_Unet104_model.py 的略微修改版本 我对此所做的修改是更改它的输出以给我我所追求的多通道语义掩码。

outputs = Conv2D(num_classes, (1, 1), name=\'output_layer\', activation=\'softmax\')(X)

我对分割任务的想法是使用这个 Unet 并训练其中的四个。每个模态(flair,t1,t1c,t2)的每个,然后冻结它们的权重并将它们连接成一个整体。

Input 0 of layer \"conv2d_106\" is incompatible with the layer: expected min_ndim=4, found ndim=3. Full shape received: (None, None, None)

Call arguments received by layer \"model_5\" (type Functional):
  • inputs=tf.Tensor(shape=(None, None, None), dtype=uint8)
  • training=True
  • mask=None

我知道它要求我交换我的输入以适应它的输入,但我不确定如何继续。我一直在尝试使用 tensorflow.expand_dims() 命令扩展图像 2D 输入的尺寸,但没有成功。任何指向解决方案或阅读材料的指针将不胜感激。

  • 图像可能具有 HxW 尺寸,但网络希望它们是 HxWx1。要为网络提供 m 个图像,您应该有 mxHxWx1。我没有通过您的代码,但看起来这就是问题所在。
  • 哦..所以我应该试着让我的输入像 [N , H , W, X1 , X2] ? N:样本总数,或者可能是批次总数。 H:高度。 W:宽度。 X1:用于遮罩的通道。 X2:为掩码上的类数。
  • 是的 [N, H, W, ...]。对于 ... 部分,将取决于您的网络,2D Unet 或 3D Unet。
  • 我明白了,我看到 3D 实现有 2 个 args 并采用 5D 输入,所以我猜因为我只想做 2D 样式,所以我应该只使用 N、H、W 和 X2 来处理 num 个类。我会尽快尝试更新
  • 好的多个错误之后,我将输入输入到一个包含[N,Img,Mask,X2]的元组中。 N 只是一个数组,其中包含第一个 elementx 的位置,该元素x 朝着自身和批次的总和迈进)img 是 mri 切片的返回张量,mask 是 mri 掩码的张量,x2 只是一个从 0 开始的数组到 4. 我得到这个返回:ValueError: Data is expected to be in format `x`, `(x,)`, `(x, y)`, or `(x, y, sample_weight)`, found: ([1], &lt;tf.Tensor: shape=(1, 240, 240), dtype=float32, numpy=(the arrays)。我不太确定 img 究竟是如何变成 3D 张量的

标签: python conv-neural-network bioinformatics semantic-segmentation imagedatagenerator


【解决方案1】:

我为此做了一些非常需要的阅读和工作,它奏效了:

  1. 通过手动使用小脚本修复了分类问题
  2. 修复了来自 tensorflow 的未知 py 崩溃导致它找不到 zlibstat (pycharm没有显示错误它只是返回了一个非常长的退出代码,这没有任何意义,总是尝试从终端孩子运行你的脚本,从我的错误中学习)
  3. 修复了另一个来自 tensorflow 的错误,因为我的 GPU 只有 4GB VRAM,不足以运行这样的模型,方法是请求访问更好的 GPU,因为显然 CUDA 不会使用共享内存。
  4. 通过适当扩展输入的轴来解决输入问题,最后输入样本是四重模态[flair,t1,t1ce,t2] 2D 堆叠 numpy 数组,正如我看到的“Dr. Sreenivas Bhattiprolu' 在https://www.youtube.com/watch?v=oB35sV1npVI 做。网络的最终输入是 [H,W, X1, X2] ,从左到右,H:高度,W:宽度,X1:numpy 堆栈中不同模式的数量(又名图像通道),X2:数量需要在掩码上注释的不同类。对于我来说,这是一个 [240,240,4,4] 输入形状。

    顺便说一句,我发现要训练一个具有 74.6m 参数的模型,您需要大量数据,所以我恳请您研究 keras 数据增强技术。我相当确定我的模型在我让它运行的 100 个 epoch 时过度拟合。

    我会在发布后的某个时候回来并发布一个 git repo 的链接,我会上传它,以防其他人发现自己陷入困境。

【讨论】:

    猜你喜欢
    • 2021-09-08
    • 1970-01-01
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 2020-08-28
    • 2020-04-08
    • 2018-05-18
    相关资源
    最近更新 更多