【问题标题】:How can I limit regression output between 0 to 1 in keras如何在 keras 中将回归输出限制在 0 到 1 之间
【发布时间】:2019-01-12 00:19:34
【问题描述】:

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

第一项:是 1(如果找到对象)或 0(未找到对象)

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

第三项:是一个介于 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'])

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

【问题讨论】:

  • 我个人认为纯 CNN 并不擅长决定距离。你能展示一下你的网络结构吗?
  • 感谢@appleapple,我已将我的网络添加到问题中。
  • 准确度不是一个好的指标,因为你的输出并不全是关于分类的。我想使用 mae/mse 指标。和split the output to 3 part 查看每个部分的错误。
  • 我提供的 link 有例子,基本上你有 3 个输出张量 (ex,dx,dy) 和 model = Model(inputs=[inputs], outputs=[ex,dx,dy])
  • 您可以选择在第一个输出上应用sigmoid

标签: python tensorflow machine-learning keras conv-neural-network


【解决方案1】:

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

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

【讨论】:

  • 这行得通,如果值太小,有没有办法阻止最后一层内的 NaN?
  • 使用 sigmoid 不利于回归,因为它比中间值更偏向 0 和 1(仅对分类有用)。应该使用像 relu 这样的激活函数并将其限制为小于 1。
猜你喜欢
  • 2021-02-22
  • 2020-09-16
  • 2019-10-12
  • 1970-01-01
  • 2016-03-12
  • 2020-05-17
  • 2020-08-15
  • 1970-01-01
  • 2018-11-22
相关资源
最近更新 更多