使用Convnet的对象中心检测总是返回图像的中心而不是对象的中心

时间:2018-03-06 08:04:01

标签: python computer-vision deep-learning keras conv-neural-network

我有一个约150张图像的小数据集。每个图像都有一个放在地板上的物体(白色和黑色矩形框)。所有图像中的对象相同,但地板的图案不同。目标是训练网络以找到图像的中心。每张图片的尺寸为256x256x3

Train_X的大小为150x256x256x3,Train_y的大小为150x2(此处150表示图片总数)

我知道150张图片的数据集太小了,但我可以放弃一些准确性,所以我在Conv网上训练了数据。这是我使用的网络的架构

  • Conv2D层(过滤器大小为32)
  • 激活Relu
  • Conv2D图层(过滤器大小为64)
  • 激活Relu
  • Flattern layer
  • 密集(64)层
  • 激活Relu
  • 密集(2)
  • 激活Softmax
  • model.compile(loss =' mse',optimizer =' sgd')

观察:训练有素的模型总是返回标准化的图像中心0.5,0.5作为对象的中心'甚至在训练数据上。当我在train_X上运行预测函数时,我希望得到一个矩形对象的中心而不是图像的中心。我是否因为我的转换层选择而得到此输出?

3 个答案:

答案 0 :(得分:0)

由于您没有在细节中提及它,因此以下建议(如果尚未实现)可能会有所帮助:

1)标准化输入数据(例如,例如,如果您正在处理输入图像,则在将输入提供给图层之前x_train = x_train / 255)

2)尝试对最后一个输出层进行线性激活

3)在更高的时期进行拟合,并尝试不同的批量大小

答案 1 :(得分:0)

您基本上是在尝试解决回归问题。除了您已完成的工作外,您还可以尝试其他一些事情:

  1. 使用ImageAugmentation技术生成更多数据。另外,对图像进行归一化。
  2. 制作一个具有更多卷积层的更深层次的模型。
  3. 对于卷积层,使用适当的 weight初始值设定项(也许是He-normal)。
  4. 在各层之间使用BatchNormalization,以使过滤器值的平均值 std 分别等于0和1。
  5. 使用交叉熵损失,因为它有助于更​​好地计算梯度。在MSE中,梯度似乎随着时间的流逝而变得很小,尽管它似乎是回归问题的首选。
  6. 尝试将优化程序更改为 Adam
  7. 以防万一,您的数据集中还有更多的类,并且存在类不平衡问题,您可以使用聚焦损失,它是交叉熵损失的一种变体,对错误分类的标签的处罚要比对正确分类的惩罚更大。分类标签。另外,减小批量大小上采样也应有所帮助。
  8. 使用贝叶斯优化技术对模型进行超参数调整。

示例模型代码:

with open(os.path.join(DATA_DIR, 'mnist.pickle'), 'rb') as fr:
    X_train, Y_train, X_val, Y_val = pickle.load(fr)
X_train = X_train.reshape(60000, 784)
X_val = X_val.reshape(10000, 784)
X_train = X_train.astype('float32')
X_val = X_val.astype('float32')
X_train /= 255
X_val /= 255
nb_classes = 10
Y_train = to_categorical(Y_train, nb_classes)
Y_val = to_categorical(Y_val, nb_classes)
return X_train, Y_train, X_val, Y_val

def build_model(input_shape, dropout=True):
    model = Sequential()
    model.add(Conv2D(32, (5,5), activation='relu', kernel_initializer='he_uniform', padding='valid', input_shape=input_shape))
    model.add(BatchNormalization())
    model.add(MaxPooling2D((2,2), strides=1, padding='valid'))
    if dropout:
        model.add(Dropout(0.2))
    model.add(Conv2D(64, (3,3), activation='relu', kernel_initializer='he_uniform', padding='valid'))
    model.add(Conv2D(128, (3,3), activation='relu', kernel_initializer='he_uniform', padding='valid'))
    model.add(BatchNormalization())
    model.add(MaxPooling2D((2,2), strides=2, padding='valid'))
    if dropout:
        model.add(Dropout(0.2))
    model.add(Flatten())
    model.add(Dense(100, activation='relu', kernel_initializer='he_uniform'))
    model.add(BatchNormalization())
    model.add(Dense(classes, activation='softmax', kernel_initializer='he_uniform'))
    # optimizer = SGD(lr=0.01, decay-1e-6, momentum=0.9)
    optimizer = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False)
    model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])
    return model

答案 2 :(得分:0)

我认为在最后几层使用“ SoftMax”激活是您的网络性能不佳的主要原因,因此您可以使用Relu或任何其他线性激活,也可以不使用。我也建议您使用像VGG这样的PreTrained网络中间输出,这样您就不需要训练Conv部分而只需训练密集部分。如果您的数据很少,则可以使用keras图像生成器来增加更多图像,如下所示。

(x_train, y_train), (x_test, y_test) = cifar10.load_data()
y_train = np_utils.to_categorical(y_train, num_classes)
y_test = np_utils.to_categorical(y_test, num_classes)
datagen = ImageDataGenerator(
    featurewise_center=True,
    featurewise_std_normalization=True,
    rotation_range=20,
    width_shift_range=0.2,
    height_shift_range=0.2,
    horizontal_flip=True)
# compute quantities required for featurewise normalization
# (std, mean, and principal components if ZCA whitening is applied)
datagen.fit(x_train)
# fits the model on batches with real-time data augmentation:
model.fit(datagen.flow(x_train, y_train, batch_size=32),
          steps_per_epoch=len(x_train) / 32, epochs=epochs)
# here's a more "manual" example
for e in range(epochs):
    print('Epoch', e)
    batches = 0
    for x_batch, y_batch in datagen.flow(x_train, y_train, batch_size=32):
        model.fit(x_batch, y_batch)
        batches += 1
        if batches >= len(x_train) / 32:
            # we need to break the loop by hand because
            # the generator loops indefinitely
            break

因此,只需执行以下操作即可:

  • 删除 Softmax激活,或使用线性ReluLeakyRelu
  • 使用预先训练的网络进行特征提取。
  • 使用图像增强创建更多图像。