【问题标题】:Creating a Keras CNN for image alteration创建用于图像更改的 Keras CNN
【发布时间】:2020-11-11 05:07:03
【问题描述】:

我正在解决一个问题,该问题涉及计算评估形状为(32, 16, 5) 的三维数据,并以(32, 16, 5) 的形状提供该数据的校正形式。这个问题相对于我的领域来说是相对特定的,但它可以被视为类似于处理彩色图像(只有五个颜色通道而不是三个)。如果有帮助,可以将其视为颜色校正模型。

在我最初的努力中,我为每个输出参数使用XGBoost 创建了一个随机森林模型。我得到了很好的结果,但发现输出参数的绝对数量(32*16*5 = 2560)使这种方法的运行时间太长,所以我正在寻找替代方法。

我正在考虑使用 Keras 来解决这个问题,使用卷积神经网络方法,因为我数据中的相邻“像素”应该有一些关于其邻居的有用信息。请注意,这里的“邻接”既是空间通道,也是颜色通道。到目前为止,我在创建一个简单模型方面做得很好,我认为该模型具有正确形状的输入/输出,但是当我尝试在一些虚拟图像上训练模型时遇到了问题:

#!/usr/bin/env python3
import tensorflow as tf
import pandas as pd
import numpy as np

def create_model(image_shape, batch_size = 10):
    width, height, channels = image_shape
    conv_shape = (batch_size, width, height, channels)
    model = tf.keras.models.Sequential()
    model.add(tf.keras.layers.Conv3D(filters = channels, kernel_size = 3, input_shape = conv_shape, padding = "same"))
    model.add(tf.keras.layers.Dense(channels, activation = "relu"))
    return model


if __name__ == "__main__":
    image_shape = (32, 16, 5)

    # Create test input/output data sets:
    input_img = np.random.rand(*image_shape) # Create one dummy input image
    output_img = np.random.rand(*image_shape) # Create one dummy output image

    # Create a bogus 'training set' by copying the input/output images into lists many times
    inputs = [input_img]*500
    outputs = [output_img]*500

    # Create the model and fit it to the dummy data
    model = create_model(image_shape)
    model.summary()
    model.compile(loss = "mean_squared_error", optimizer = "adam", metrics = ["accuracy"])
    model.fit(input_img, output_img)

但是,当我运行此代码时,我收到以下错误:

ValueError: Input 0 of layer sequential is incompatible with the layer: : expected min_ndim=5, found ndim=3. Full shape received: [32, 16, 5]

我不太确定传递给model.fit() 的数据的其他两个预期维度是什么。我怀疑这是我格式化输入数据的方式的问题。即使我有一个输入/输出图像列表,也只会将我的数据的ndim 带到 4,而不是 5。

我一直试图在文档和网络上找到类似的示例,以查看我做错了什么,但非分类器网络上的 3D 卷积似乎有点不走寻常路,而且我没有非常幸运(或者只是不知道我应该搜索的名称)。

我尝试将虚拟训练集传递给model.fit,而不是两个单独的图像。改为使用model.fit(inputs, outputs),我得到:

ValueError: Layer sequential expects 1 inputs, but it received 500 input tensors.

似乎在这里传递张量列表是不正确的。如果我将输入图像列表转换为 numpy 数组:

inputs = np.array(inputs)
outputs = np.array(outputs)

这确实使我的输入数据中的维数增加到 4,但 Keras 仍然期望 5。我在这种情况下得到的错误与第一个非常相似:

ValueError: Input 0 of layer sequential is incompatible with the layer: : expected min_ndim=5, found ndim=4. Full shape received: [None, 32, 16, 5]

我绝对不明白这里的某些东西,如果有任何帮助,我们将不胜感激。

【问题讨论】:

  • 使用Conv3D 层而不是Conv2D 层的原因是什么?除非您有 2D 图像 + 通道维度而不是 3D 图像 + 时间维度 + 通道维度,否则我建议使用 Con2D 层。请参阅下面的@meTchaikovsky 回答谁比我快。
  • @rftr:我使用 Conv3D 来获得 3D 卷积核。这背后的原因是,例如,我希望通道 3 的输出图像中的一个像素也从通道 2 和通道 4 中的附近像素获取信息。我不确定这个推理是否正确。

标签: python numpy tensorflow keras deep-learning


【解决方案1】:

我认为您在代码中犯了两个错误:

  1. 您需要使用Conv2D,而不是使用Conv3D
  2. model.fit(input_img, output_img) 应该是 model.fit(inputs, outputs)

你需要使用Conv2D的原因是你的数据的形状是(length,width,channel),它没有额外的维度。

试试下面的脚本

#!/usr/bin/env python3
import tensorflow as tf
import pandas as pd
import numpy as np

def create_model(image_shape, batch_size = 10):
    width, height, channels = image_shape
    conv_shape = (width, height, channels)
    model = tf.keras.models.Sequential()
    model.add(tf.keras.layers.Conv2D(filters = channels, kernel_size = 3, input_shape = conv_shape, padding = "same"))
    model.add(tf.keras.layers.Dense(channels, activation = "relu"))
    return model


if __name__ == "__main__":
    image_shape = (32, 16, 5)

    # Create test input/output data sets:
    input_img = np.random.rand(*image_shape) # Create one dummy input image
    output_img = np.random.rand(*image_shape) # Create one dummy output image

    # Create a bogus 'training set' by copying the input/output images into lists many times
    inputs = np.array([input_img]*500)
    outputs = np.array([output_img]*500)

    # Create the model and fit it to the dummy data
    model = create_model(image_shape)
    model.summary()
    model.compile(loss = "mean_squared_error", optimizer = "adam", metrics = ["accuracy"])
    model.fit(inputs, outputs)

【讨论】:

  • 这确实让我的模型训练工作了,所以谢谢!我在想我需要Conv3D,因为我想要一个 3D 卷积核,这样相邻通道就会相互影响。我不确定这个推理是否正确,但我可以把它留到以后的另一个问题。
猜你喜欢
  • 2021-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-07
  • 2020-05-31
  • 2018-11-22
相关资源
最近更新 更多