当前位置: 首页 > 知识库问答 >
问题:

使用Convnet的目标中心检测总是返回图像的中心,而不是目标的中心

訾俊名
2023-03-14

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

Train_X为size150x256x256x3,Train_y为size150x2(此处150表示图像总数)

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

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

观察:即使在训练数据上,训练模型也始终返回图像的归一化中心0.5,0.5作为“对象”的中心。当我在train_X上运行predict函数时,我希望得到一个矩形对象的中心,而不是图像的中心。我得到这个输出是因为我选择了conv层吗?

共有3个答案

高勇
2023-03-14

我认为在最后一层中使用“SoftMax”激活是您的网络不能弱执行的主要原因,因此您可以使用Relu或任何其他线性激活或使用no训练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
  • 使用预训练网络进行特征提取。
  • 使用图像增强来创建更多的图像。
东郭子默
2023-03-14

您基本上是在尝试解决回归问题。除了您所做的之外,您还可以尝试以下几点:

  1. 使用图像增强技术生成更多数据。另外,将图像标准化。
  2. 用更多的卷积层制作更深层次的模型。
  3. 对于卷积层,使用适当的权重初始值设定项可能是正常的。
  4. 在层之间使用BatchNormalization使过滤器值的平均值和标准值分别等于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
刘棋
2023-03-14

由于您在详细信息中未提及,以下建议(如果您尚未实施)可能会有所帮助:

1)规范化输入数据(例如,如果您正在处理输入图像,x_train=x_train/255,然后将输入送入图层)

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

3) 在更高的时期运行配件,并试验不同的批量大小

 类似资料:
  • 我正在使用highcharts(highcharts.js)创建一个使用'bands'特性的图。频段配置如下: 此配置在标签上使用align:center,因此它们应该水平居中。不幸的是,它们正在偏离中心。 您可以在这里找到一个演示这个问题的工具:http://jsfidle.net/mpvsa/。 “一月”标签应该是水平居中的,但它在65%处显示得比在50%处显示得更多。这个问题在我尝试过的所有

  • 我正在使用VEMap API。我有一张地图的左上点和右下点(包围框)的纬度和经度。我要得到中心点。有什么简单的方法可以做到这一点?我在谷歌上搜索也找不到解决办法。 我在想的是,如果我能用上面提到的两点定义地图,那么我就能非常容易地得到中心:

  • 我正在弄清楚如何使用Cocoapods,我发现了这个:pod install在cocoapods版本1.0.0.beta.1中显示错误 它说我必须写以下行:后面跟一些东西。但我对什么是我的“TargetName”感到困惑。 例如,此项目中的目标名称是什么: 或者,我在哪里可以找到我的项目的“目标”?我正在使用最新版本的Xcode。

  • 我想从二值图像中得到圆形状的质心,但输出给出了不止一个质心。我使用的是opencv web教程文档中关于图像时刻和修改的代码。供参考,我使用的是C++API OpenCV。 输出结果是: 我预计,文本输出可能会从3个轮廓中给出3个质心,但实际上是7个轮廓(轮廓[0],...,轮廓[6])。

  • 下面的示例介绍了以下应用程序: 位于BorderLayout北边的按钮会将带有一些组件的GridBagLayout面板添加到BoxLayout中。Y_AXIS在BorderLayout中。CENTER。但是单击按钮后,面板会显示在中心,而不是添加到顶部。 播放锚()将单选按钮和一个标签设置到顶部,但第二个标签仍显示在中间。 如何让面板出现在顶部而不是中心?

  • 问题内容: 所以我的问题是我有一个图片,并将其CSS设置为 它以较低的分辨率缩放(如下面的小提琴所示)。我想要的是使过渡从图像的中心生效。 目前; 从我在大多数涉及规模的过渡中所见,它们从左上角开始扩展。 问题答案: 只需替换为on即可。