首页 文章

如何在keras中将回归输出限制在0到1之间

提问于
浏览
1

我试图检测图像中单个对象的单个像素位置 . 我有一个keras CNN回归网络,我的图像张量作为输入,一个3项向量作为输出 .

First item :是1(如果找到了对象)或0(未找到对象)

Second item :是一个介于0和1之间的数字,表示沿x轴的距离是对象

Third item :是一个介于0和1之间的数字,表示沿y轴的距离是对象

我已经在2000个测试图像和500个验证图像上训练了网络,val_loss远小于1,val_acc最好在0.94左右 . 优秀 .

但是当我预测输出时,我发现所有三个输出项的值都不在0和1之间,它们实际上介于-2和3之间 . 所有三个项目应介于0和1之间 .

我没有在输出层上使用任何非线性激活函数,并且已经将relus用于所有非输出层 . 我应该使用softmax,即使它是非线性的吗?第二项和第三项预测图像的x轴和y轴,这在我看来是线性量 .

这是我的keras网络:

inputs = Input((256, 256, 1))

base_kernels = 64 

 # 256
conv1 = Conv2D(base_kernels, 3, activation='relu', padding='same', kernel_initializer='he_normal')(inputs)
conv1 = BatchNormalization()(conv1)
conv1 = Conv2D(base_kernels, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv1)
conv1 = BatchNormalization()(conv1)
conv1 = Dropout(0.2)(conv1)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)

# 128
conv2 = Conv2D(base_kernels * 2, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool1)
conv2 = BatchNormalization()(conv2)
conv2 = Conv2D(base_kernels * 2, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv2)
conv2 = BatchNormalization()(conv2)
conv2 = Dropout(0.2)(conv2)
pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)

# 64
conv3 = Conv2D(base_kernels * 4, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool2)
conv3 = BatchNormalization()(conv3)
conv3 = Conv2D(base_kernels * 4, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv3)
conv3 = BatchNormalization()(conv3)
conv3 = Dropout(0.2)(conv3)
pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)

flat = Flatten()(pool3)

dense = Dense(256, activation='relu')(flat)
output = Dense(3)(dense)

model = Model(inputs=[inputs], outputs=[output])

optimizer = Adam(lr=1e-4)
model.compile(optimizer=optimizer, loss='mean_absolute_error', metrics=['accuracy'])

有人可以帮忙吗?谢谢! :) 克里斯

1 回答

  • 3

    sigmoid激活产生0到1之间的输出,因此如果您将其用作最后一层(输出)的激活,则网络的输出将介于0和1之间 .

    output = Dense(3, activation="sigmoid")(dense)
    

相关问题