tensorflow.js中的错误多重回归sgd最小化

时间:2018-07-17 12:30:56

标签: javascript node.js tensorflow linear-regression tensorflow.js

这是我的第一篇文章。我在tensorflow.js中拟合曲线时遇到错误,但似乎无法修复。到目前为止,我已经花了两天时间。由于tensorflow.js相当新,因此对于此类问题并没有很多答案,所以我相信很多人对此感兴趣。我试图从tensorflow.js项目的网站复制示例:

https://js.tensorflow.org/tutorials/fit-curve.html

区别在于我正在使用多个预测变量来预测结果变量。我有20个价格,我正在使用之前的4个价格来预测第5个价格。因此,我从价格编号5开始,一直到价格编号20,其中在加权时间序列预测模型中由价格1至4预测价格5,依此类推。我使用的是多元线性回归框架,在该框架中,我设置了4个随机参数(之前四个价格中的每一个权重)。我的目标是训练变量以使损失函数最小化(使用最小最小二乘准则)。我尝试过尽可能接近链接中的示例。每当我运行代码时,我都会得到:

错误:在variableGrads(f)中传递的f必须是一个函数

,它是由第59行中的.minimize调用生成的(最后一次返回train函数之前)。基本上,我正在做的事情是拟合线性回归,这可以在R中更轻松地完成,但我们的目标是非常大的数据集和更复杂的机器学习过程。我相信这对很多刚开始使用tensorflow.js的人很有趣。

这是我的代码,带有一些注释:

const tf = require('@tensorflow/tfjs');

require('@tensorflow/tfjs-node');

module.exports = function tensorFlow() {
//the trainable variable with initial random numbers
let lag = tf.variable(tf.tensor([Math.random(), Math.random(), Math.random(), Math.random()], [4])); 

//20 observed prices
let priceData = [21.00397, 21.29068, 22.80492, 23.40646, 24.06598, 23.89722, 25.40211, 24.63436, 25.83449, 26.44832, 26.25194, 27.34009, 27.90455, 27.14175, 28.12549, 29.99411, 30.43631, 30.39753, 30.16104, 31.14931]; 

//the prices from price 5 on that are to be predicted
let toBePredictedList = [24.06598, 23.89722, 25.40211, 24.63436, 25.83449, 26.44832, 26.25194, 27.34009, 27.90455, 27.14175, 28.12549, 29.99411, 30.43631, 30.39753, 30.16104, 31.14931];

//set up tensor of labels to compare predictions with
let toBePredicted = tf.tensor(toBePredictedList, [16]);

//a list of predictors with 16 rows and four columns for 16 predictions to be made using 4 previous prices each
let predictorsList = [];

for (let predictorIndex = 0; predictorIndex < 16; predictorIndex++) {
    for (let predictionsIndex = 0; predictionsIndex < 4; predictionsIndex++) {
        predictorsList.push(priceData[predictorIndex + predictionsIndex]);
    }
}

//make it a tensor
let predictors = tf.tensor(predictorsList, [16, 4]);

//predict multiplies all predictors in all lines with the parameters from lag to be trained and adds up the four elements to generate an estimate of the fifth price
function predict(predictors) {
    function modelMaker() {
        let modelList = [];

        for (let rowIndex = 0; rowIndex < 16; rowIndex++) {
            let prediction = 0;

            for (let colIndex = 0; colIndex < 4; colIndex++) {
                prediction += lag.get(colIndex) * predictors.get(rowIndex, colIndex);
                console.log({prediction});
            }
            modelList.push(prediction);
        }
        return tf.tensor(modelList, [16]);
    }

    return tf.tidy(modelMaker);
}

//means square error of my prediction when compared to actual outcome price
function loss(predictions, toBePredicted) {
    return tf.losses.meanSquaredError(toBePredicted, predictions);
}

function train(predictors, toBePredicted, numIterations) {
    function computeLoss (predictors, toBePredicted) {
        let predictions = predict(predictors);
        return loss(predictions, toBePredicted);
    }
    let learningRate = 0.5; //suggested by Google Developers
    const OPTIMIZER = tf.train.sgd(learningRate); //suggested by Google Developers

    for (let iter = 0; iter < numIterations; iter++) {
        OPTIMIZER.minimize(computeLoss(predictors, toBePredicted));
    }
    return {
        a: lag.get(0),
        b: lag.get(1),
        c: lag.get(2),
        d: lag.get(3)
    };
};
//75 suggested by google developers
return train(predictors, toBePredicted, 75);
};

最后我要说的是问题的最小化。上面的代码可以正常工作并计算出应有的一切。

谢谢您的任何建议! 克里斯

1 个答案:

答案 0 :(得分:0)

optimizer.minimize()在每个训练周期内更新权重。为了更新权重,需要使用tf.variable创建权重。使用tf.variable创建的变量是可变的,而tf.tensor创建不可变的变量。

还需要指出的是,predict()应该返回一个函数,该函数的系数是使用tf.variable创建的,将对其进行更新以最小化损失函数。