minimizing loss in tensorflow.js for feed forward neural network
我正在尝试在 tensorflow.js 中创建一个示例前馈神经网络,最初使用一个小数据集(仅用于 POC)。有 5 个输入节点和 1 个输出节点。数据与有多个输入的住房相关,我们正在预测价格。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | 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]); } } |
模型编译良好。但是训练模型时的损失是巨大的
1 2 3 4 5 6 7 8 9 10 11 12 13 | Model Successfully Compiled Epoch 1 / 10 eta=0.0 ====================================================================> 1058ms 235us/step - acc=0.00 loss=1648912629760.00 val_acc=0.00 val_loss=1586459705344.00 Epoch 2 / 10 eta=0.0 ====================================================================> 700ms 156us/step - acc=0.00 loss=1648913285120.00 val_acc=0.00 val_loss=1586459705344.00 Epoch 3 / 10 eta=0.0 ====================================================================> 615ms 137us/step - acc=0.00 loss=1648913022976.00 val_acc=0.00 val_loss=1586459705344.00 Epoch 4 / 10 eta=0.0 ====================================================================> 852ms 189us/step - acc=0.00 loss=1648913285120.00 val_acc=0.00 val_loss=1586459705344.00 |
我认为这可能是因为训练数据未标准化。所以我取数据的平均值并对其进行划分
1 2 3 4 5 6 7 | 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], ..., |
损失变化不大
1 2 3 4 5 6 7 8 9 10 | 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 |
然后我也将输出标准化,
1 2 3 4 5 6 7 8 9 10 11 12 | 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 次迭代也不会显着减少损失。例如
1 2 3 4 5 6 7 8 9 10 | 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 中有没有其他方法可以做到这一点?
我将假设您没有尝试线性回归,因为 Sigmoidal 激活。如果您正在尝试线性回归,请删除所有地方的 sigmoidal 激活。将尝试解决我能看到的所有错误:
从输出中删除 sigmoid 激活。 sigmoid 函数将输入压缩到 0 到 1 之间,因此它不用于回归。您的最后一层不需要激活。
你的学习率太高了,所以我怀疑学习算法能否收敛。从大约 0.001 - 0.01 等值开始,并根据需要进行调整。
不,你没有正确规范化。通常,数据被归一化为均值为零和标准差为 1。这是针对每个特征列完成的,仅使用该列的平均值和标准差,而不是所有数据。例如特征列
您提供的性能指标"准确度"用于分类,而不是回归,并且毫无意义(如果提供的话)。最小化均方误差或绝对平方误差是量化模型性能的最佳方法。