В вашем коде есть две основные проблемы.
Проблема 1: Не дожидается завершения Обещания
linearModel.fit
возвращает Обещание, которое будет решенокогда обучение закончено.Это означает, что сейчас модель начнет обучение, но до того, как обучение закончится, вы уже запрашиваете прогнозы.
Вам нужно дождаться разрешения Обещания.Самый простой способ сделать это - поместить свой код в функцию async
и использовать await
следующим образом:
(async () => {
var linearModel = tf.sequential();
// ...
await linearModel.fit(xs, ys);
// ...
})();
Проблема 2. Плохая скорость обучения
Обучение по умолчаниюставка для sgd
составляет 0.01
, что является слишком высоким в вашем случае.Обучение вашей модели с этим значением увеличивало значение loss
для каждой итерации обучения для меня, указывая, что скорость обучения слишком высока.Если вам нужна дополнительная информация по теме, ознакомьтесь с этим руководством по «Оценка оптимальной скорости обучения» .
. Вы можете изменить скорость обучения с помощью tf.train.sgd
функция (вместо использования строки) и прохождение скорости обучения, как это:
linearModel.compile({ loss: 'meanSquaredError', optimizer: tf.train.sgd(0.0001) });
Дальнейшее улучшение: тренировка для более чем одной эпохи
Хотя вышеупомянутые советы уже должны датьрезультаты, близкие к 50
, позволяют дополнительно улучшить вашу модель, обучаясь более одной эпохи.Вы можете передать параметр epochs
следующим образом:
await linearModel.fit(xs, ys, {
epochs: 10
});
Попробуйте сами
Я добавил улучшения в ваш код в следующем фрагменте кода.Вы можете изменить значения epochs
и learning rate
, чтобы увидеть, как это влияет на итоговый прогноз 50
.
document.querySelector('button').addEventListener('click', async () => {
const learningRate = document.querySelector('#learning_rate').value;
const epochs = document.querySelector('#epochs').value;
const linearModel = tf.sequential();
linearModel.add(tf.layers.dense({ units: 1, inputShape: [1] }));
linearModel.compile({ loss: 'meanSquaredError', optimizer: tf.train.sgd(learningRate) });
const xs = tf.tensor1d([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,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100]);
const ys = tf.tensor1d([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,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100]);
await linearModel.fit(xs, ys, {
epochs,
callbacks: {
onEpochEnd: (epoch, logs) => console.log(`Loss, epoch ${epoch}: ${logs.loss}`),
},
});
function linearPrediction(val) {
const output = linearModel.predict(tf.tensor1d([val]));
const prediction = Array.from(output.dataSync())[0];
console.log(`Prediction for 50: ${prediction}`);
}
linearPrediction(50);
});
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.0.0/dist/tf.min.js"></script>
epochs: <input type="number" id="epochs" value="1" />
learning rate: <input type="number" id="learning_rate" value="0.0001" />
<button id="train">Train</button>