I'm trying to predict 2 things via a Tensorflow model:
- an unknown weight (W)
- 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
?
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?
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>