我正在尝试用 JS 训练张量流模型,但无法获得 MSE 分数。即使在 Epoch 中它也会返回 NaN,所以我不确定它是否按预期进行训练。这是我的代码的一部分:
// Check tensors
checkForNaNs(xs, 'Features');
//returns :
//Features does not contains NaNs
//Features does not contains Infinities
checkForNaNs(ys, 'Labels');
//returns :
//Labels does not contains NaNs
//Labels does not contains Infinities
xs = normalizeTensor(xs);
const optimizerType = 'sgd';
const lossFunction = 'meanSquaredError';
let model = createRegressionModel(features[0].length);
const metrics = 'mse';
await trainModel(model, xs, ys, optimizerType, lossFunction, metrics);
const evalOutput = await model.evaluate(xs, ys);
console.log(`Debug: evalOutput: ${evalOutput}`)
// returns debug: evalOutput: Tensor
// NaN, Tensor
// NaN
const mse = evalOutput[0].dataSync()[0]; // Access the first element for MSE
console.log(`Mean Squared Error (MSE): ${mse}`);
//returns Mean Squared Error (MSE): NaN
//Functions I use:
function createRegressionModel(inputShape) {
return tf.sequential({
layers: [
tf.layers.dense({ inputShape: [inputShape], units: 10, activation: 'relu' }),
tf.layers.dense({ units: 1, activation: 'linear' })
]
});
}
async function trainModel(model, xTrain, yTrain, xValidation, yValidation, optimizerType, lossFunction, metrics) {
model.compile({ optimizer: optimizerType, loss: lossFunction, metrics: metrics });
console.log(`Training model using metrix: ${metrics}`);
// returns Training model using metrix: mse
await model.fit(xTrain, yTrain, {
epochs: 10,
validationData: validationData,
callbacks: {
onEpochEnd: (epoch, logs) => {
console.log(logs);
console.log(`Epoch ${epoch + 1}: loss = ${logs.loss}, MSE = ${logs.mse}, val_loss = ${logs.val_loss}, val_MSE = ${logs.val_mse}`);
// returns for example: Epoch 1: loss = NaN, MSE = NaN, val_loss = undefined, val_MSE = undefined
}
}
});
}
function checkForNaNs(tensor, tensorName) {
if (tensor.isNaN().any().dataSync()[0]) {
console.log(`${tensorName} contains NaNs`);
} else {
console.log(`${tensorName} does not contains NaNs`);
}
if (tensor.isInf().any().dataSync()[0]) {
console.log(`${tensorName} contains Infinities`);
} else {
console.log(`${tensorName} does not contains Infinities`);
}
}
function normalizeTensor(tensor) {
const mean = tensor.mean(0);
const std = tensor.sub(mean).square().mean(0).sqrt();
return tensor.sub(mean).div(std);
}
我认为这就是所有重要的代码。之前的代码只是从 csv 文件中获取数据并将其分成 ys 和 xs,如下所示:
let xs = tf.tensor2d(features, [features.length, features[0].length]);
let ys = tf.tensor2d(labels, [labels.length, 1]);
问题出在优化器类型上,我将其更改为 Adam,第一次尝试就成功了!