最终目标:对象中点计算。
我有一个小的数据集(约120张图像),其中有一个对象(在所有情况下都相同),标签是图像中对象中点的归一化x,y坐标(始终在0到0之间) 1)
例如x = image_005;对于对象放置在左下角附近的图像,y =(0.1,0.15)
我正在尝试使用ResNet架构,但已针对我的图像大小进行了自定义(所有都是相同的图像)。由于两个坐标的输出值始终在0到1之间,因此我想知道是否可以在最后一层中使用Sigmoid激活:
X = Dense(2, activation='sigmoid', name='fc', kernel_initializer = glorot_uniform(seed=0))(X)
而不是线性激活(通常在尝试获得回归结果时建议这样做)
对于损失函数,我使用了带有“ rmsprop”优化器的MSE,除了准确性和MSE外,我还编写了一个自定义指标来告诉我预测点是否与标签相距超过5% >
model.compile(optimizer='rmsprop', loss='mean_squared_error', metrics=['mse','acc',perc_midpoint_err])
在大约150个时期训练模型后,我没有得到很好的结果(我也尝试了不同的批量大小)
我应该将激活层更改为线性吗?还是可以对模型进行其他修改?还是ResNet完全不适合此任务?
答案 0 :(得分:1)
您的任务与对象检测有关。区别在于,每个图像中似乎只有一个对象,而在检测中可能有多个对象或不存在任何对象。对于对象检测,有诸如YOLOv3(https://pjreddie.com/media/files/papers/YOLOv3.pdf)或Single Shot Multibox Detector-SSD(https://arxiv.org/pdf/1512.02325.pdf)之类的网络,但是ResNet也可以作为对象检测网络进行训练(如本文所述:{{ 3}})
我将简要介绍YOLO如何解决边界x,y坐标的回归问题:
原则上,您的设置对我来说很好。但是有很多事情可能导致性能降低,因为您没有告知数据集的范围:您使用的是预先训练的网络还是从头开始训练?它是您要学习的新类别还是网络以前见过的对象类别?等等
以下是您可以尝试的一些想法:
希望您能从中得到启发。
答案 1 :(得分:0)
除了您已完成的工作外,您还可以做很多其他事情:
这里是 Resnet 的简单实现:
def unit(x, filters, pool=False):
res = x
if pool:
x = MaxPooling2D(pool_size=(2, 2))(x)
res = Conv2D(filters=filters, kernel_size=(1, 1), strides=(2, 2), padding='same', kernel_initializer='he_normal')(res)
out = BatchNormalization()(x)
out = Activation('relu')(out)
out = Conv2D(filters=filters, kernel_size=(3, 3), strides=(1, 1), padding='same', kernel_initializer='he_normal')(out)
out = BatchNormalization()(out)
out = Activation('relu')(out)
out = Conv2D(filters=filters, kernel_size=(3, 3), strides=(1, 1), padding='same', kernel_initializer='he_normal')(out)
x = keras.layers.add([res, out])
return x
def model(inputs):
inp = Input(inputs)
x = Conv2D(32, (3, 3), padding='same', kernel_initializer='he_uniform')(inp)
x = unit(x, 32)
x = unit(x, 32)
x = unit(x, 32)
x = unit(x, 64, pool=True)
x = unit(x, 64)
x = unit(x, 64)
x = unit(x, 128, pool=True)
x = unit(x, 128)
x = unit(x, 128)
x = unit(x, 256, pool=True)
x = unit(x, 256)
x = unit(x, 256)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Dropout(0.25)(x)
x = AveragePooling2D((3, 3))(x)
x = Flatten()(x)
x = Dense(2, activation='sigmoid')(x)
model = Model(inputs=inp, outputs=x)
optimizer = Adam(lr=0.001)
# model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])
model.compile(optimizer=optimizer, loss=keras.losses.MeanSquaredLogarithmicError(), metrics=['accuracy'])
return model