Tensorflow Js - optimize.minimize 找不到任何变量与损失函数结果之间的联系
Tensorflowjs - optimize.minimize cannot find a connection between any variable and the resulr of the loss function
我正在尝试使用 tensorflowjs (https://www.youtube.com/watch?v=NZR-N_dhK2M) 调整 Daniel Shiffman 的线性回归示例,以使用多项式方程而不是线性方程。但我正在为预测功能而苦苦挣扎。
在我的第一个版本中(见下文),optimize.minimze 函数在我的函数和我的 tf.variables(存储在我的系数数组中)之间找不到 link。
另一方面,我的第二个版本可以运行,但有一个我无法修复的内存泄漏
这是非工作版本:
const WIDTH = 800, HEIGHT = 400;
const x_vals = [];
const y_vals = [];
let coefficients = [];
let degree = 5;
let lr = 0.2;
let optimizer = tf.train.adamax(lr);
function setup() {
createCanvas(WIDTH, HEIGHT);
background(0);
initCoeffs();
let up = false;
for (let i = 0; i < WIDTH; i += WIDTH / 10) {
x_vals.push(map(i, 0, WIDTH, -1, 1));
y_vals.push(map((up) ? 0 : HEIGHT, 0, HEIGHT, -1, 1));
up = !up;
}
}
function initCoeffs() {
for (let i = 0; i < degree; i++)
coefficients.push(tf.variable(tf.scalar(random(1))));
}
function loss(pred, labels) {
return tf.losses.meanSquaredError(labels, pred);
}
function predict(x) {
const xs = tf.tensor1d(x);
const ys = tf.variable(tf.zerosLike(xs));
for (let i = 0; i < degree; i++) {
const coef = coefficients[i];
const pow_ts = tf.fill(xs.shape, degree - i);
const sum = tf.add(ys, coef.mul(xs.pow(pow_ts)));
ys.assign(sum);
}
ys.print();
return ys;
}
function draw() {
noFill();
background(0);
stroke(255);
strokeWeight(8);
for (let i = 0; i < x_vals.length; i++) {
point(map(x_vals[i], -1, 1, 0, WIDTH), map(y_vals[i], -1, 1, 0, HEIGHT));
}
strokeWeight(4);
if (x_vals.length > 0) {
tf.tidy(() => {
const ys = tf.tensor1d(y_vals);
optimizer.minimize(() => loss(predict(x_vals), ys));
});
}
let lineX = [];
for (let x = -1.1; x <= 1.1; x += 0.01)
lineX.push(x);
const ys = tf.tidy(() => predict(lineX));
let lineY = ys.dataSync();
ys.dispose();
beginShape();
for (let i = 0; i < lineY.length; i++)
curveVertex(map(lineX[i], -1, 1, 0, WIDTH), map(lineY[i], -1, 1, 0, HEIGHT));
endShape();
for (let i = 0; i < lineY.length; i++) {
stroke(200, 100, 100);
point(map(lineX[i], -1, 1, 0, WIDTH), map(lineY[i], -1, 1, 0, HEIGHT));
}
}
function mousePressed() {
x_vals.push(map(mouseX, 0, WIDTH, -1, 1));
y_vals.push(map(mouseY, 0, HEIGHT, -1, 1));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tensorflow/0.11.2/tf.min.js"></script>
如您所见,我在控制台中遇到此错误:
Cannot find a connection between any variable and the result of the loss function y=f(x). Please make sure the operations that use variables are inside the function f passed to minimize().
但如果我像这样更改我的预测函数,它就会起作用:
function predict(x) {
const xs = tf.tensor1d(x);
let ys = tf.variable(tf.zerosLike(xs));
for (let i = 0; i < degree; i++) {
const coef = coefficients[i];
const pow_ts = tf.fill(xs.shape, degree - i);
const sum = tf.add(ys, coef.mul(xs.pow(pow_ts)));
ys = sum;
}
ys.print();
return ys;
}
问题是当我使用 let 声明我的 ys tf.variable.
时,第二个版本会造成内存泄漏
如何修复我的代码以避免内存泄漏,而不会出现 optimize.minimizer 错误?
谢谢
我通过在将 ys 变量分配给 tf.add 函数的结果之前手动处理它,设法让我的代码在没有内存泄漏的情况下工作。
这是我的工作解决方案
const WIDTH = 800, HEIGHT = 400;
const x_vals = [];
const y_vals = [];
let coefficients = [];
let degree = 15;
let lr = 0.2;
let optimizer = tf.train.adamax(lr);
function setup() {
createCanvas(WIDTH, HEIGHT);
background(0);
initCoeffs();
let up = false;
for (let i = 0; i < WIDTH; i += WIDTH / 10) {
x_vals.push(map(i, 0, WIDTH, -1, 1));
y_vals.push(map((up) ? 0 : HEIGHT, 0, HEIGHT, -1, 1));
up = !up;
}
}
function initCoeffs() {
for (let i = 0; i < degree; i++)
coefficients.push(tf.variable(tf.scalar(random(1))));
}
function loss(pred, labels) {
return tf.losses.meanSquaredError(labels, pred);
}
function predict(x) {
const xs = tf.tensor1d(x);
let ys = tf.variable(tf.zerosLike(xs));
for (let i = 0; i < degree; i++) {
const coef = coefficients[i];
const pow_ts = tf.fill(xs.shape, degree - i);
const sum = tf.add(ys, coefficients[i].mul(xs.pow(pow_ts)));
ys.dispose();
ys = sum.clone();
}
return ys;
}
function draw() {
noFill();
background(0);
stroke(255);
strokeWeight(8);
for (let i = 0; i < x_vals.length; i++) {
point(map(x_vals[i], -1, 1, 0, WIDTH), map(y_vals[i], -1, 1, 0, HEIGHT));
}
strokeWeight(4);
if (x_vals.length > 0) {
tf.tidy(() => {
const ys = tf.tensor1d(y_vals);
optimizer.minimize(() => loss(predict(x_vals), ys), coefficients);
});
}
let lineX = [];
for (let x = -1.1; x <= 1.1; x += 0.01)
lineX.push(x);
const ys = tf.tidy(() => predict(lineX));
let lineY = ys.dataSync();
ys.dispose();
beginShape();
for (let i = 0; i < lineY.length; i++)
curveVertex(map(lineX[i], -1, 1, 0, WIDTH), map(lineY[i], -1, 1, 0, HEIGHT));
endShape();
for (let i = 0; i < lineY.length; i++) {
stroke(200, 100, 100);
point(map(lineX[i], -1, 1, 0, WIDTH), map(lineY[i], -1, 1, 0, HEIGHT));
}
//console.log(tf.memory().numTensors);
}
function mousePressed() {
x_vals.push(map(mouseX, 0, WIDTH, -1, 1));
y_vals.push(map(mouseY, 0, HEIGHT, -1, 1));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tensorflow/0.11.2/tf.min.js"></script>
我不确定这些是否是错误:
- 使用 ys = tf.add() 创建一个未被 tidy() 处理的新张量
- 使用 ys.assign(tf.add()) 阻止 optimizer.minimize() 函数查找与变量的关系
我正在尝试使用 tensorflowjs (https://www.youtube.com/watch?v=NZR-N_dhK2M) 调整 Daniel Shiffman 的线性回归示例,以使用多项式方程而不是线性方程。但我正在为预测功能而苦苦挣扎。 在我的第一个版本中(见下文),optimize.minimze 函数在我的函数和我的 tf.variables(存储在我的系数数组中)之间找不到 link。 另一方面,我的第二个版本可以运行,但有一个我无法修复的内存泄漏
这是非工作版本:
const WIDTH = 800, HEIGHT = 400;
const x_vals = [];
const y_vals = [];
let coefficients = [];
let degree = 5;
let lr = 0.2;
let optimizer = tf.train.adamax(lr);
function setup() {
createCanvas(WIDTH, HEIGHT);
background(0);
initCoeffs();
let up = false;
for (let i = 0; i < WIDTH; i += WIDTH / 10) {
x_vals.push(map(i, 0, WIDTH, -1, 1));
y_vals.push(map((up) ? 0 : HEIGHT, 0, HEIGHT, -1, 1));
up = !up;
}
}
function initCoeffs() {
for (let i = 0; i < degree; i++)
coefficients.push(tf.variable(tf.scalar(random(1))));
}
function loss(pred, labels) {
return tf.losses.meanSquaredError(labels, pred);
}
function predict(x) {
const xs = tf.tensor1d(x);
const ys = tf.variable(tf.zerosLike(xs));
for (let i = 0; i < degree; i++) {
const coef = coefficients[i];
const pow_ts = tf.fill(xs.shape, degree - i);
const sum = tf.add(ys, coef.mul(xs.pow(pow_ts)));
ys.assign(sum);
}
ys.print();
return ys;
}
function draw() {
noFill();
background(0);
stroke(255);
strokeWeight(8);
for (let i = 0; i < x_vals.length; i++) {
point(map(x_vals[i], -1, 1, 0, WIDTH), map(y_vals[i], -1, 1, 0, HEIGHT));
}
strokeWeight(4);
if (x_vals.length > 0) {
tf.tidy(() => {
const ys = tf.tensor1d(y_vals);
optimizer.minimize(() => loss(predict(x_vals), ys));
});
}
let lineX = [];
for (let x = -1.1; x <= 1.1; x += 0.01)
lineX.push(x);
const ys = tf.tidy(() => predict(lineX));
let lineY = ys.dataSync();
ys.dispose();
beginShape();
for (let i = 0; i < lineY.length; i++)
curveVertex(map(lineX[i], -1, 1, 0, WIDTH), map(lineY[i], -1, 1, 0, HEIGHT));
endShape();
for (let i = 0; i < lineY.length; i++) {
stroke(200, 100, 100);
point(map(lineX[i], -1, 1, 0, WIDTH), map(lineY[i], -1, 1, 0, HEIGHT));
}
}
function mousePressed() {
x_vals.push(map(mouseX, 0, WIDTH, -1, 1));
y_vals.push(map(mouseY, 0, HEIGHT, -1, 1));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tensorflow/0.11.2/tf.min.js"></script>
如您所见,我在控制台中遇到此错误:
Cannot find a connection between any variable and the result of the loss function y=f(x). Please make sure the operations that use variables are inside the function f passed to minimize().
但如果我像这样更改我的预测函数,它就会起作用:
function predict(x) {
const xs = tf.tensor1d(x);
let ys = tf.variable(tf.zerosLike(xs));
for (let i = 0; i < degree; i++) {
const coef = coefficients[i];
const pow_ts = tf.fill(xs.shape, degree - i);
const sum = tf.add(ys, coef.mul(xs.pow(pow_ts)));
ys = sum;
}
ys.print();
return ys;
}
问题是当我使用 let 声明我的 ys tf.variable.
时,第二个版本会造成内存泄漏如何修复我的代码以避免内存泄漏,而不会出现 optimize.minimizer 错误?
谢谢
我通过在将 ys 变量分配给 tf.add 函数的结果之前手动处理它,设法让我的代码在没有内存泄漏的情况下工作。
这是我的工作解决方案
const WIDTH = 800, HEIGHT = 400;
const x_vals = [];
const y_vals = [];
let coefficients = [];
let degree = 15;
let lr = 0.2;
let optimizer = tf.train.adamax(lr);
function setup() {
createCanvas(WIDTH, HEIGHT);
background(0);
initCoeffs();
let up = false;
for (let i = 0; i < WIDTH; i += WIDTH / 10) {
x_vals.push(map(i, 0, WIDTH, -1, 1));
y_vals.push(map((up) ? 0 : HEIGHT, 0, HEIGHT, -1, 1));
up = !up;
}
}
function initCoeffs() {
for (let i = 0; i < degree; i++)
coefficients.push(tf.variable(tf.scalar(random(1))));
}
function loss(pred, labels) {
return tf.losses.meanSquaredError(labels, pred);
}
function predict(x) {
const xs = tf.tensor1d(x);
let ys = tf.variable(tf.zerosLike(xs));
for (let i = 0; i < degree; i++) {
const coef = coefficients[i];
const pow_ts = tf.fill(xs.shape, degree - i);
const sum = tf.add(ys, coefficients[i].mul(xs.pow(pow_ts)));
ys.dispose();
ys = sum.clone();
}
return ys;
}
function draw() {
noFill();
background(0);
stroke(255);
strokeWeight(8);
for (let i = 0; i < x_vals.length; i++) {
point(map(x_vals[i], -1, 1, 0, WIDTH), map(y_vals[i], -1, 1, 0, HEIGHT));
}
strokeWeight(4);
if (x_vals.length > 0) {
tf.tidy(() => {
const ys = tf.tensor1d(y_vals);
optimizer.minimize(() => loss(predict(x_vals), ys), coefficients);
});
}
let lineX = [];
for (let x = -1.1; x <= 1.1; x += 0.01)
lineX.push(x);
const ys = tf.tidy(() => predict(lineX));
let lineY = ys.dataSync();
ys.dispose();
beginShape();
for (let i = 0; i < lineY.length; i++)
curveVertex(map(lineX[i], -1, 1, 0, WIDTH), map(lineY[i], -1, 1, 0, HEIGHT));
endShape();
for (let i = 0; i < lineY.length; i++) {
stroke(200, 100, 100);
point(map(lineX[i], -1, 1, 0, WIDTH), map(lineY[i], -1, 1, 0, HEIGHT));
}
//console.log(tf.memory().numTensors);
}
function mousePressed() {
x_vals.push(map(mouseX, 0, WIDTH, -1, 1));
y_vals.push(map(mouseY, 0, HEIGHT, -1, 1));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tensorflow/0.11.2/tf.min.js"></script>
我不确定这些是否是错误:
- 使用 ys = tf.add() 创建一个未被 tidy() 处理的新张量
- 使用 ys.assign(tf.add()) 阻止 optimizer.minimize() 函数查找与变量的关系