CNN具有RGB输入和BW二进制输出

时间:2018-01-15 05:06:40

标签: arrays tensorflow keras

我是深度学习的初学者,我正在与Tensorflow之上构建的Keras合作。我正在尝试使用RGB图像(540 x 360)分辨率来预测边界框。

我的标签是二维(黑/白)2维np维数(540,360),其中所有像素都是0,除了盒子边缘是1。 像这样:

   [[0 0 0 0 0 0 ... 0]
    [0 1 1 1 1 0 ... 0]
    [0 1 0 0 1 0 ... 0]
    [0 1 0 0 1 0 ... 0]
    [0 1 1 1 1 0 ... 0]
    [0 0 0 0 0 0 ... 0]]

每张照片中都可以有多个边界框。典型的图片可能如下所示:FRCBox

因此,我的输入的维度为(None, 540, 360, 3),输出的维度为(None, 540, 360),但如果添加内部数组,我可以将形状更改为(None, 540, 360, 1)

我如何定义CNN模型以使我的模型符合此标准?如何设计具有这些输入和输出的CNN?

3 个答案:

答案 0 :(得分:1)

这是如何编写中间层以实现输出的简单示例。您可以将其用作入门代码。

def model_360x540(input_shape=(360, 540, 3),num_classes=1):

    inputs = Input(shape=input_shape)
    # 360x540x3

    downblock0 = Conv2D(32, (3, 3), padding='same')(inputs)
    # 360x540x32
    downblock0 = BatchNormalization()(block0)
    downblock0 = Activation('relu')(block0)
    downblock0_pool = MaxPooling2D((2, 2), strides=(2, 2))(block0)
    # 180x270x32

    centerblock0 = Conv2D(1024, (3, 3), padding='same')(downblock0_pool)
    #180x270x1024
    centerblock0 = BatchNormalization()(center)
    centerblock0 = Activation('relu')(center)


    upblock0 = UpSampling2D((2, 2))(centerblock0)
    # 180x270x32
    upblock0 = concatenate([downblock0 , upblock0], axis=3)
    upblock0 = Activation('relu')(upblock0)
    upblock0 = Conv2D(32, (3, 3), padding='same')(upblock0)
    # 360x540x32
    upblock0 = BatchNormalization()(upblock0)
    upblock0 = Activation('relu')(upblock0)


    classify = Conv2D(num_classes, (1, 1), activation='sigmoid')(upblock0)
    #360x540x1

    model = Model(inputs=inputs, outputs=classify)

    model.compile(optimizer=RMSprop(lr=0.001), loss=bce_dice_loss, metrics=[dice_coeff])

    return model

downblock 表示执行下采样的图层块(MaxPooling2D)。

中心块没有采样层。

upblock 表示执行采样的图层块(UpSampling2D)。

所以在这里你可以看到(360,540,3)如何转换为(360,540,1)

基本上,您可以添加此类图层块来创建模型。

同时查看Holistically-Nested Edge Detection,这将有助于您更好地完成边缘检测任务。

希望这有帮助!

答案 1 :(得分:1)

我没有使用过keras,但我会以更通用的方式提供一种可用于任何框架的解决方案。 这是完整的程序。

  1. 数据准备:我知道你的标签是盒子的边缘也可以工作但是我会建议你用样品中给出的数据集标记完整盒子而不是边缘(我标记了两个盒子)。现在,您的数据集有三个类(Box,边框和背景)。创建两个列表,图像和标签。 Image Labeling Scheme

  2. 获取预先训练的模型(RESNET-51推荐)求解器并从here训练原型,移除fc1000层并添加去卷积/上采样层以匹配您的输入大小。在第一层中使用paddding使其成为正方形并在去卷积层中裁剪以匹配输入输出尺寸。

  3. 从之前训练过的网络传输权重(原始)并训练您的网络。

  4. 测试数据集并使用检测到的blob创建边界框。

答案 2 :(得分:1)

您可以区分对象检测和对象分割。虽然两者都可以用于类似的问题,但基础CNN架构看起来非常不同。

对象检测模型使用CNN分类/回归架构,其中输出指的是边界框的坐标。通常的做法是使用属于每个边界框的垂直中心,水平中心,宽度和高度的4个值。搜索更快的R-CNN,SSD或YOLO以查找keras的流行对象检测模型。在您的情况下,您需要定义一个函数,将当前标签转换为我提到的4个坐标。

对象分割模型通常使用称为编码器 - 解码器网络的架构,其中原始图像在前半部分缩小并压缩,然后恢复到其原始分辨率以预测完整图片。搜索SegNet,U-Net或Tiramisu以查找keras的流行对象分割模型。我可以找到我自己的U-Net实现here。在你的情况下,你需要定义一个自定义函数,用1s填充你的边界框内的所有0。了解此解决方案不会预测边界框,而是显示感兴趣区域的分割图。

什么是适合你的,取决于你想要达到的目标。要获取实际的边界框,您需要执行对象检测。但是,如果您想要突出显示超出矩形窗口的感兴趣区域,则分割可能更适合。理论上,您可以使用矩形标签进行分割,只要您有足够的数据,网络将学会创建比基本事实的不准确分割更好的掩模。