最小化前馈神经网络 tensorflow.js 中的损失
minimizing loss in tensorflow.js for feed forward neural network
我正在尝试在 tensorflow.js 中创建一个示例前馈神经网络,最初使用一个小数据集(仅用于 POC)。有5个输入节点和1个输出节点。数据与有多个输入的住房相关,我们正在预测价格。
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]);
}
}
模型编译正常。但是训练模型的时候loss很大
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
我想这可能是因为训练数据没有标准化。所以我取了数据的平均值并进行了划分
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 次迭代也不会显着降低损失。例如
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. 我使用正确的 loss function/optimizer/learning rate/activation 等吗?
4.我怎么知道模型是否表现良好
5. 在 tensorflow.js 中还有其他方法可以做到这一点吗?
我假设你没有尝试线性回归,因为 S 形激活。如果您正在尝试线性回归,请移除所有位置的 S 形激活函数。将尝试解决我能看到的所有错误:
从输出中移除 sigmoid 激活函数。 sigmoid 函数将输入压缩到 0 到 1 之间,因此它不适合回归。你的最后一层不需要激活。
你的学习率太高了,所以我怀疑学习算法是否能够收敛。从大约 0.001 - 0.01 等的值开始,并根据需要进行调整。
不,你没有正确规范化。通常,数据被归一化为零平均值和一标准偏差。这是针对每个特征列完成的,仅使用该列的均值和标准差,而不是所有数据。例如特征列x
中的i
的公式如下:(x_i - x.mean()) / x.std()
。 (我不知道javascript)
您提供的性能指标 "accuracy" 用于分类,而不是回归,并且将毫无意义(如果提供的话)。最小化均方误差或绝对平方误差是量化模型性能的最佳方式。
我正在尝试在 tensorflow.js 中创建一个示例前馈神经网络,最初使用一个小数据集(仅用于 POC)。有5个输入节点和1个输出节点。数据与有多个输入的住房相关,我们正在预测价格。
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]);
}
}
模型编译正常。但是训练模型的时候loss很大
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
我想这可能是因为训练数据没有标准化。所以我取了数据的平均值并进行了划分
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 次迭代也不会显着降低损失。例如
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. 我使用正确的 loss function/optimizer/learning rate/activation 等吗? 4.我怎么知道模型是否表现良好 5. 在 tensorflow.js 中还有其他方法可以做到这一点吗?
我假设你没有尝试线性回归,因为 S 形激活。如果您正在尝试线性回归,请移除所有位置的 S 形激活函数。将尝试解决我能看到的所有错误:
从输出中移除 sigmoid 激活函数。 sigmoid 函数将输入压缩到 0 到 1 之间,因此它不适合回归。你的最后一层不需要激活。
你的学习率太高了,所以我怀疑学习算法是否能够收敛。从大约 0.001 - 0.01 等的值开始,并根据需要进行调整。
不,你没有正确规范化。通常,数据被归一化为零平均值和一标准偏差。这是针对每个特征列完成的,仅使用该列的均值和标准差,而不是所有数据。例如特征列
x
中的i
的公式如下:(x_i - x.mean()) / x.std()
。 (我不知道javascript)您提供的性能指标 "accuracy" 用于分类,而不是回归,并且将毫无意义(如果提供的话)。最小化均方误差或绝对平方误差是量化模型性能的最佳方式。