Tensorflow.js 具有 6 个参数的函数的多变量拟合

问题描述 投票:0回答:1

我想寻求帮助。

我的目标是使用 tensorflow.js 中的非线性回归方法确定 R^2 -> R 函数中 6 个参数的值(因此具有两个自变量 x1 和 x2)。

使用TensorFlow可以达到这个结果吗?

现在我写了这个脚本:

<html>
  <head>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest/dist/tf.min.js"></script>

    

  </head>
  <body>
    <h4>Tensorflow.js<hr/></h4>
    
        <script>
    
    // Create a simple model.




const x1 = tf.tensor2d([10, 11, 12], [3, 1]);
const x2 = tf.tensor2d([8, 21, 4], [3, 1]);
const y = tf.tensor2d([8, 21, 4], [3, 1]);

function Ulberg(initial_params, x1, x2, y) {
    [r1_i, r2_i, s_i, t1_i, t2_i, t3_i] = initial_params;
    const Vrev = tf.scalar(1.0);
    const A = tf.scalar(1.0);
    const r1 = tf.variable(tf.scalar(r1_i));
    const r2 = tf.variable(tf.scalar(r2_i));
    const s = tf.variable(tf.scalar(s_i));
    const t1 = tf.variable(tf.scalar(t1_i));
    const t2 = tf.variable(tf.scalar(t2_i));
    const t3 = tf.variable(tf.scalar(t3_i));

    const Blocco1 = tf.div(Vrev, A);
    const Blocco2 = tf.add(r1, tf.mul(r2, x2));
    const Blocco3 = tf.mul(Blocco1, Blocco2, x1);
    const Blocco4 = tf.mul(Blocco3, s);
    const Blocco5 = tf.div(t2, x1);
    const Blocco6 = tf.div(t3, tf.pow(x1, 2));
    const Blocco7 = tf.add(t1, Blocco5)
    const Blocco8 = tf.add(Blocco7, Blocco6);
    const Blocco9 = tf.log(tf.add(Blocco8, 1));
    const funzione = tf.add(Blocco4, Blocco9);

    const error = tf.losses.meanSquaredError(funzione.arraySync(), y.arraySync()).arraySync();
    return error;
}

const initial_params = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0];



console.log(Ulberg(initial_params, x1, x2, y));

const result = tf.train.minimize(() => Ulberg(initial_params, x1, x2, y), true);
console.log(result);
const optimizedParams = result.x.arraySync();
console.log("Optimized Params:", optimizedParams);
</script>
  </body>
</html>

我得到:Uncaught TypeError: tf.train.minimize is not a function

我现在该如何计算这六个参数?

更清楚地说:我有以下功能:Function with parameters

然后我有一个由 Vrev、I 和 T 组成的数据集,我想找到完全适合该函数的参数

javascript math regression tensorflow.js
1个回答
0
投票

我通过自己编写代码解决了这个问题,没有使用 TensorFlow。 老实说,文档非常差,使用使事情复杂化而不是简化事情的库会适得其反。

使用说明

可以通过重命名各处出现的“Ulberg”并插入您选择的函数名称来修改代码。当然,功能本身也必须改变。

如果您想增加或减少参数的数量,只需使用具有不同数量的“1”的initial_params向量开始代码即可。

向量 x1, x2,... xn, y 可以根据您的数据集具有您喜欢的大小,只要它们彼此同构即可。

除了在“ulberg”函数中添加或删除参数之外,不需要更改任何代码。

        <script>
function Ulberg(initial_params, x1, x2, y) {
    result = [];
    if(!((x1.length == x2.length) || (x2.length == y.length))){
    console.log("I vettori hanno grandezze diverse");
    }
    const [r1_i, r2_i, s_i, t1_i, t2_i, t3_i] = initial_params;
    const Vrev = 12;
    const A = 1;

    const r1 = r1_i;
    const r2 = r2_i;
    const s  = s_i ;
    const t1 = t1_i;
    const t2 = t2_i;
    const t3 = t3_i;
    // Prima elaborazione
    for(i = 0; i < y.length; i++){
        //Funzione completa
        const valore_funzione = (Vrev) + ((r1 + r2*x1[i])/A)*x2[i] + s*Math.log10(1 + ((t1 + (t2/x1[i]) + (t3/(x1[i]*x1[i])))/A)*x2[i]);
        result.push(valore_funzione);
    }
    //console.log(result);
    //console.log("Sono stata eseguita");
    return result;
}

    
function meanSquaredError(actual, experimental){
        if(!(actual.length == experimental.length)){
    console.log("I vettori hanno grandezze diverse, impossibile determinare il mean squared error.");
    }
    error = 0;
    
    for(i = 0; i < actual.length; i++){
            error += Math.pow((actual[i] - experimental[i]), 2);
            //console.log("Errore parziale");
            //console.log(error);
    }   

    
    return error/actual.length;
}


function addVector(a, b){
    return a.map((e,i) => e + b[i]);
}

function subtractVector(a, b){
    return a.map((e,i) => e - b[i]);
}

function multiplyVector(a, b){
    return a.map((e,i) => e * b[i]);
}

function divideVector(a, b){
    return a.map((e,i) => e / b[i]);
}

function elevateVector(a, power){
    return a.map((e,i) => Math.pow(e, power));
}

function sqrtVector(a){
    return a.map((e,i) => Math.sqrt(e));
}

function multiplyScalar(a, vector){
    return vector.map((e,i) => e * a);
}

/* Your data. Please make sure that all vectors have the same dimension */
const x1 = [55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55];
const x2 = [0.001256,0.007716,0.01337,0.019026,0.027493,0.033133,0.050034,0.066534,0.086245,0.105553,0.125261,0.156229,0.189204,0.232631,0.265603,0.28812,0.32109,0.345216,0.377782,0.410752,0.433669,0.467039,0.488748];
const y = [15.5113,16.3797,17.1882,18.0416,18.8204,19.2249,19.8249,20.4399,20.9205,21.386,21.8068,22.3632,22.8748,23.4324,23.8543,24.1107,24.4727,24.7592,25.0613,25.4084,25.6349,25.9222,26.0588];


const h = 0.01;
const lambda = 0.01;
const beta1 = 0.9;
const beta2 = 0.999;

const noi = 100000; /*  Number of iterations */


//let initial_params =      [ 1, 1, 1, 1, 1, 1 ];

let m =             [0, 0, 0, 0, 0, 0];
let v =             [0, 0, 0, 0, 0, 0];
let m_hat =             [0, 0, 0, 0, 0, 0];
let v_hat =             [0, 0, 0, 0, 0, 0];
let epsilon =           [0.00000001, 0.00000001, 0.00000001, 0.00000001, 0.00000001, 0.00000001, 0.00000001, 0.00000001];

/* Se vuoi ottenere l'immagine della funzione */
//console.log(Ulberg(initial_params, x1, x2, y));

var empty_array = [];
var explore_params = [];
var gradient = [];
//Calcolo le derivate parziali
console.log(Ulberg(initial_params, [55], [0.5], [9999999]));

for(j = 0; j < noi; j++){
    for(t = 0; t < initial_params.length; t++){
    //console.log(initial_params.length);
        explore_params = initial_params.slice();
        explore_params[t] = explore_params[t] + h;
y) - meanSquaredError(Ulberg(initial_params, x1, x2, y), y))/h);
        gradient.push(     ((meanSquaredError(Ulberg(explore_params, x1, x2, y), y) - meanSquaredError(Ulberg(initial_params, x1, x2, y), y))/h )        );
        }

    m = addVector(multiplyScalar(beta1, m), multiplyScalar((1 - beta1), gradient));
    v = addVector(multiplyScalar(beta2, v), multiplyScalar((1 - beta2), multiplyVector(gradient, gradient)));
    
    m_hat.slice();
    v_hat.slice();
    
    m_hat = multiplyScalar((1/(1 - Math.pow(beta1, j+1))), m);
    v_hat = multiplyScalar((1/(1 - Math.pow(beta2, j+1))), v);

    initial_params = subtractVector(initial_params, divideVector(multiplyScalar(lambda, m_hat), addVector(epsilon, elevateVector(v_hat, 0.5))));
    
    /*for(k = 0; k < initial_params.length; k++){
        initial_params[k] = initial_params[k] - Math.random() * lambda * gradient[k];
        }
        */
    gradient = empty_array.slice();
    console.log("Sto per stampare i parametri iniziali modificati:");
    console.log(initial_params);
    console.log("Errore:");
    console.log(meanSquaredError(Ulberg(initial_params, x1, x2, y), y));
}
   

有趣的是,如果不使用 ADAM 优化器,代码无法收敛。

© www.soinside.com 2019 - 2024. All rights reserved.