Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.3k views
in Technique[技术] by (71.8m points)

tensorflow - TensorflowJS predicts unknown weight and constant

I'm trying to predict 2 things via a Tensorflow model:

  1. an unknown weight (W)
  2. an unknown constant (b)

and I have done following implementations, may refer to code down below.

1st question: how to interpret these 2 parameters when adding layers with model.add?

  1. inputShape - [x,y] where x is the number of row we have; y is how many features each row has? What if only 1 number provided in an array, say [1], does it default to be referring y?
  2. units - the number of output neuron this layer produces?

2nd question: how to implement the similar way of thinking like the 1st attempt (where it clearly defines W & b as variables) in the 2nd Neural Network fashion attempt?

1st attempt defines both W & b as variables (features?) explicitly. However, 2nd attempt only have W as input feature although it still predicts the W correctly and somehow figured out there is a constant b in the equation. Following the 2nd attempt, I cannot know the what is the constant b is, or does it even matter to programmers?

The following is a successful 1st implementation to predict equation y = W * x + b, where x is a variable:

// script.js

// y = W * x + b

const run = async () => {
  const SAMPLE_SIZE = 100;
  const WEIGHT = 2021;
  const B = 110;
  const EPOCH = 200;
  const LEARNING_RATE = 0.3;

  const wData = await tf.randomNormal([SAMPLE_SIZE]); // random training W
  const yData = await wData.mul(WEIGHT).add(B); // label based on training W

  /**
   * define W & b variables the model needs to predict
   */
  const W = tf.scalar(Math.random()).variable(); // generate a tensor with a random value 
  const b = tf.scalar(Math.random()).variable(); // generate a tensor with a random value
  
  const fun = w => W.mul(w).add(b) // show the model how the label is computed
  const loss = (pred, label) => pred.sub(label).square().mean(); // MSE loss function
  
  const optimizer = tf.train.sgd(LEARNING_RATE);
  
  // Train the model.
  for (let i = 0; i < EPOCH; i++) {
    console.log("training");
    optimizer.minimize(() => loss(fun(wData), yData));
  }
  
  console.log(`W: ${W.dataSync()}, b: ${b.dataSync()}`);
  
  const preds = fun(wData).arraySync();
  const origin = yData.arraySync();

  preds.forEach((pred, i) => {
    console.log(`pred: ${pred}, original: ${origin[i]}`);
  });

}

run()

<!-- index.html -->

<!DOCTYPE html>
<html>

<head>
  <title>TensorFlow.js Tutorial</title>

  <!-- Import TensorFlow.js -->
  <script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]/dist/tf.min.js"></script>
  <!-- Import tfjs-vis -->
  <script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]/dist/tfjs-vis.umd.min.js"></script>

  <!-- Import the main script file -->
  <script src="script.js"></script>

</head>

<body>
</body>

</html>

However, I would like to train this in a more "Neural Network" fashion. Here is my 2nd successful attempt:

// script.js   

// y = W * x + b
// train in a neural network way

const SAMPLE_SIZE = 100;
const WEIGHT = 20;
const B = 100;
const BATCH_SIZE = 10;
const EPOCHS = 20;
const LEARNING_RATE = 1;

const loadData = async () => {
  return tf.randomNormal([SAMPLE_SIZE, 1]); // random training W
}

const createModel = () => {
  // Create a sequential model
  const model = tf.sequential();

  // Add a single input layer
  model.add(tf.layers.dense({ inputShape: [1], units: 1, useBias: true }));

  // Add an output layer
  model.add(tf.layers.dense({ units: 1, useBias: true }));

  return model;
}

/** 
 * @param {model} model The model created for training
 * @param {Tensor} inputs The input features
 * @param {Tensor} labels The labels calculated from training data
*/
const trainModel = async (model, inputs, labels) => {
  // Prepare the model for training.  
  model.compile({
    optimizer: tf.train.adagrad(LEARNING_RATE),
    loss: tf.losses.meanSquaredError,
    metrics: ['mse'],
  });

  const batchSize = BATCH_SIZE;
  const epochs = EPOCHS;

  return await model.fit(inputs, labels, {
    batchSize,
    epochs,
    shuffle: true,
    callbacks: tfvis.show.fitCallbacks(
      { name: 'Training Performance' },
      ['loss', 'mse'],
      { height: 200, callbacks: ['onEpochEnd'] }
    )
  });
}

const testModel = (model) => {
  const xs = tf.linspace(1, 100, 100);
  const preds = model.predict(xs.reshape([100, 1]));
  console.log(xs.arraySync());
  console.log(preds.arraySync());
}

const run = async () => {
  let wData = await loadData();
  let yData = await wData.mul(WEIGHT).add(B); // label based on training W

  const model = createModel();
  tfvis.show.modelSummary({ name: 'Model Summary' }, model);

  wData.print();
  console.log(wData.shape);
  yData.print();
  console.log(yData.shape);

  // Train the model  
  await trainModel(model, wData, yData);
  console.log('Done Training');

  testModel(model);
}

document.addEventListener('DOMContentLoaded', run);

<!-- index.html -->
<!DOCTYPE html>
<html>

<head>
  <title>TensorFlow.js Tutorial</title>

  <!-- Import TensorFlow.js -->
  <script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]/dist/tf.min.js"></script>
  <!-- Import tfjs-vis -->
  <script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]/dist/tfjs-vis.umd.min.js"></script>

  <!-- Import the main script file -->
  <script src="script.js"></script>

</head>

<body>
</body>

</html>


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神解答

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...