前馈神经网络tensorflow.js中的最小化损失

前馈神经网络tensorflow.js中的最小化损失,tensorflow,machine-learning,linear-regression,tensorflow.js,Tensorflow,Machine Learning,Linear Regression,Tensorflow.js,我尝试在tensorflow.js中创建一个样本前馈神经网络,最初使用一个小数据集(仅用于POC)。有5个输入节点和一个输出节点。数据与房屋相关,房屋有多种投入,我们正在预测价格 x_train: [ [ 79545.45857, 5.682861322, 7.009188143, 4.09, 23086.8005 ], [ 79248.64245, 6.002899808, 6.730821019, 3.09, 40173.07217 ], [ 61287.06718, 5.86588

我尝试在tensorflow.js中创建一个样本前馈神经网络,最初使用一个小数据集(仅用于POC)。有5个输入节点和一个输出节点。数据与房屋相关,房屋有多种投入,我们正在预测价格

x_train:
[ [ 79545.45857, 5.682861322, 7.009188143, 4.09, 23086.8005 ],
  [ 79248.64245, 6.002899808, 6.730821019, 3.09, 40173.07217 ],
  [ 61287.06718, 5.86588984, 8.51272743, 5.13, 36882.1594 ],
  [ 63345.24005, 7.188236095, 5.586728665, 3.26, 34310.24283 ],
  [ 59982.19723, 5.040554523, 7.839387785, 4.23, 26354.10947 ],
...
] 

y_train
[ [ 1059033.558 ],
  [ 1505890.915 ],
  [ 1058987.988 ],
  [ 1260616.807 ],
  [ 630943.4893 ],
...
]

const model = tf.sequential();
const config_hidden = {
        inputShape: [5],
        activation: 'sigmoid',
        units: 6
    }

const config_output = {
    units: 1,
    activation: 'sigmoid'
}

const hidden = tf.layers.dense(config_hidden);
const output = tf.layers.dense(config_output);

model.add(hidden);
model.add(output);

const optimizer = tf.train.sgd(0.5);

const config = {
    optimizer: optimizer,
    loss: 'meanSquaredError',
    metrics: ['accuracy']
}

model.compile(config);

train_data().then(function () {
    console.log('Training is Complete');
}

async function train_data() {
    const options = {
        shuffle: true,
        epochs: 10,
        batch_size: 100,
        validationSplit: 0.1
    }

    for (let i = 0; i < 10; i++) {
        const res = await model.fit(xs, ys, options);
        console.log(res.history.loss[0]);
    }
}
我想这可能是因为训练数据没有标准化。所以我取了数据的平均值并进行了分割

xs = xs.div(xs.mean(0));

x_train
[[1.1598413, 0.9507535, 1.003062 , 1.0272969, 0.6384002],
     [1.1555134, 1.0042965, 0.9632258, 0.7761241, 1.1108726],
     [0.8936182, 0.9813745, 1.2182286, 1.2885166, 1.0198718],
     ...,
损失没有多大变化

Model Successfully Compiled
Epoch 1 / 10
eta=0.0 ====================================================================>
841ms 187us/step - acc=0.00 loss=1648912760832.00 val_acc=0.00 val_loss=1586459705344.00
Epoch 2 / 10
eta=0.0 ====================================================================>
613ms 136us/step - acc=0.00 loss=1648913154048.00 val_acc=0.00 val_loss=1586459705344.00
Epoch 3 / 10
eta=0.0 ====================================================================>
646ms 144us/step - acc=0.00 loss=1648913022976.00 val_acc=0.00 val_loss=1586459705344.00
然后我也对输出进行了标准化

ys = ys.div(1000000);

Model Successfully Compiled
Epoch 1 / 10
eta=0.0 ====================================================================>
899ms 200us/step - acc=0.00 loss=0.202 val_acc=0.00 val_loss=0.161
Epoch 2 / 10
eta=0.0 ====================================================================>
667ms 148us/step - acc=0.00 loss=0.183 val_acc=0.00 val_loss=0.160
Epoch 3 / 10
eta=0.0 ====================================================================>
609ms 135us/step - acc=0.00 loss=0.182 val_acc=0.00 val_loss=0.159
这使损失降到了十进位数字。然而,可以看出,即使在训练数据上运行10000次迭代,也不能显著减少损失。e、 g

Epoch 8 / 10
eta=0.0 ====================================================================>
502ms 112us/step - acc=0.00 loss=0.181 val_acc=0.00 val_loss=0.158
Epoch 9 / 10
eta=0.0 ====================================================================>
551ms 122us/step - acc=0.00 loss=0.181 val_acc=0.00 val_loss=0.158
Epoch 10 / 10
eta=0.0 ====================================================================>
470ms 104us/step - acc=0.00 loss=0.181 val_acc=0.00 val_loss=0.158
0.18076679110527039
最后,损失从0.202左右开始,下降到0.180左右。这会导致错误的预测

这是一种非常常见的情况。具有不同范围值的多个输入(例如,如上所述的外壳数据)。多个输入传递给前馈神经网络。预期只有一个输出(本例中的价格)

问题: 1.我在上面的代码中做错了什么? 2.我是否以正确的方式规范化了数据? 3.我是否使用了正确的损失函数/优化器/学习率/激活等。 4.我如何知道模型的性能是否良好
5.在tensorflow.js中还有其他方法可以做到这一点吗?

我假设您没有尝试线性回归,因为S形激活。如果您尝试线性回归,请删除各处的乙状结肠激活。将尝试解决我能看到的所有错误:

  • 从输出中移除sigmoid激活。sigmoid函数将输入压缩到0到1之间,因此它不适用于回归。您的最后一层不需要激活

  • 你的学习率太高了,所以我怀疑学习算法是否能够收敛。从0.001-0.01等值开始,并根据需要进行调整

  • 不,您的数据没有正确正常化。通常,将数据标准化为零的平均值和一的标准偏差。这是针对每个特征列进行的,仅使用该列的平均值和标准偏差,而不是所有数据。例如,特征列
    x
    中的
    i
    公式如下:
    (x_i-x.mean())/x.std()
    。(我不懂javascript)

  • 您提供的性能指标“准确度”用于分类,而不是回归,并且毫无意义(如果提供)。最小化均方误差或绝对平方误差是量化模型性能的最佳方法


  • 我从输出层删除了“sigmoid”,并将学习速率设置为0.1。损失有一定的改善,现在在0.01范围内,并且正在减少。我对隐藏层使用了“relu”激活。希望没问题。对于指标,我使用了“mse”。我还想得到模型的准确率。我怎么知道?关于规范化,我理解您的意思,但是我在tensorflow.js中找不到std()函数。一个建议是使用((x_i-min)/(max-min))。在隐藏层中使用relu是可以的,只需注意,您现在没有实现线性回归,而是增加了模型搜索非线性相关性的能力。仅通过查看tensorflow文档,就可以看到一个度量“Mean AbsolutePercentageError”,这似乎就是您要查找的。您提到的归一化方法只是该过程的另一个变体,也可以使用。只需确保分别对每个功能(列)进行归一化。感谢您的输入。我试图从输入数据中的5个特征来预测房价。所以回归可能是我想要的(我可能错了)。我应该从所有层中删除激活函数吗?Tensorflow.js似乎使用精度:['mse']。我使用['mape']作为meanAbsolutePercentageError的提示,尽管它没有在文档中明确列出它。我得到的输出为{val_loss:[0.007765776012092829],val_mape:[17.398786544799805],loss:[0.008923463523387909],mape:[41699.80859375]}。mape的价值似乎相差很远
    Epoch 8 / 10
    eta=0.0 ====================================================================>
    502ms 112us/step - acc=0.00 loss=0.181 val_acc=0.00 val_loss=0.158
    Epoch 9 / 10
    eta=0.0 ====================================================================>
    551ms 122us/step - acc=0.00 loss=0.181 val_acc=0.00 val_loss=0.158
    Epoch 10 / 10
    eta=0.0 ====================================================================>
    470ms 104us/step - acc=0.00 loss=0.181 val_acc=0.00 val_loss=0.158
    0.18076679110527039