【问题标题】:Can the sigmoid activation function be used to solve regression problems in Keras?sigmoid 激活函数可以用来解决 Keras 中的回归问题吗?
【发布时间】:2018-02-25 17:32:48
【问题描述】:

我已经用 R 实现了简单的神经网络,但这是我第一次用 Keras 这样做,所以不胜感激。

我在 Keras 中开发了一个神经网络函数来预测汽车销量(数据集在 here 可用)。 CarSales 是因变量。

据我所知,Keras 用于开发用于分类而非回归的神经网络。到目前为止,在我看到的所有示例中,输出都在 0 和 1 之间。

这是我开发的代码,你会看到我在输出中使用了“sigmoid”函数:

from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Dense
from tensorflow.python.keras.wrappers.scikit_learn import KerasRegressor
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import MinMaxScaler

import os;
path="C:/Users/cars.csv"
os.chdir(path)
os.getcwd()

#Variables
dataset=np.loadtxt("cars.csv", delimiter=",")
x=dataset[:,0:5]
y=dataset[:,5]
y=np.reshape(y, (-1,1))
scaler = MinMaxScaler()
print(scaler.fit(x))
print(scaler.fit(y))
xscale=scaler.transform(x)
yscale=scaler.transform(y)

model = Sequential()
model.add(Dense(12, input_dim=5, kernel_initializer='normal', activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.summary()

model.compile(loss='mse', optimizer='adam', metrics=['mse','mae','mape','cosine','accuracy'])
model.fit(xscale, yscale, epochs=150, batch_size=50,  verbose=1, validation_split=0.2)

如您所见,我使用 MaxMinScaler 将变量和输出绑定在 0 和 1 之间。

当我生成 150 个 Epoch 时,mean_squared_errormean_absolute_error 等值非常低。然而,mean_absolute_percentage_error 相当高 - 但我怀疑这不是评估 sigmoid 输出时使用的好指标。

将输出变量限制在 0 和 1 之间,然后运行模型是尝试使用神经网络预测区间变量的可接受方式吗?

【问题讨论】:

    标签: python tensorflow neural-network keras


    【解决方案1】:

    要使用神经网络执行回归,您应该使用 最终输出中的线性激活函数。

    试试下面的代码。

    model = Sequential()
    model.add(Dense(12, input_dim=5, kernel_initializer='normal', activation='relu'))
    model.add(Dense(8, activation='relu'))
    model.add(Dense(1, activation='linear'))
    model.summary()
    

    【讨论】:

      【解决方案2】:

      将输出变量限制在 0 和 1 之间,然后运行模型是尝试使用神经网络预测区间变量的可接受方式吗?

      如果您事先知道输出可以采用的值的范围,我想这可以工作。不过这肯定不常见。

      使用以下代码,您实际上是在作弊。您正在使用所有数据(训练和验证)来计算缩放器的界限,而应该只使用训练数据。

      dataset=np.loadtxt("cars.csv", delimiter=",")
      x=dataset[:,0:5]
      y=dataset[:,5]
      y=np.reshape(y, (-1,1))
      scaler = MinMaxScaler()
      print(scaler.fit(x))
      print(scaler.fit(y))
      xscale=scaler.transform(x)
      yscale=scaler.transform(y)
      

      如果您不那样作弊,您可能会在验证数据中获得超出您界限的值。如果您仍然使用 sigmoid,您将无法做出正确的预测(如果根据仅由训练数据确定的范围进行缩放,则该预测应位于 [0, 1] 之外)。

      像 Hemen 建议的那样,简单地以线性层结束回归任务更为常见。

      您的学习过程仍可能受益于将训练数据中的输出缩放到[0, 1],但是如果训练数据之外的输出稍微超过在训练数据中观察到的所有值,则可能会映射到例如1.1

      【讨论】:

      • 非常感谢。是的,我知道我需要对数据进行分区,例如train_test_split。我的重点是先让模型工作,然后再继续这一步。
      • 对,所以当你这样做时,你可能会遇到一个问题,即你可能无法正确知道可能的输出范围。即使你这样做了,我仍然不知道 sigmoid 在回归中很常见,所以我仍然不推荐它。虽然我认为在这种情况下,您可以尝试评估它与更常见的线性输出相比的表现。
      • 其实,一个问题。我一直在回顾代码,我删除 train_test_split 的原因是因为 validation_split 已经在我的代码的最后一行执行,不是吗? X_train, X_test, y_train, y_test = train_test_split(xscale, yscale)
      • 当然可以,但那是你适合你的缩放器之后。因此,您的定标器使用来自两组的信息(不是您的神经网络,只是定标器)。这已经可以被认为是“轻微”作弊
      • 非常感谢您的帮助。我只在训练数据上再次运行模型:model.fit(X_train, y_train, epochs=150, batch_size=50, verbose=1, validation_split=0.2)。我使用“线性”作为激活函数,如下所示。我得到了类似的均方误差 (+/-0.0172)。我可以接受 mean_absolute_percentage_error 的高值吗,例如170.16 是由于使用 MaxMinScaler 设置变量的方式,这种测量在这里根本不合适?
      猜你喜欢
      • 2020-12-05
      • 2018-08-14
      • 2020-01-14
      • 2021-03-23
      • 2020-04-25
      • 1970-01-01
      • 2018-04-15
      • 2012-08-21
      • 2020-02-13
      相关资源
      最近更新 更多