TensorFlow Model


Shuffling Data
Always shuffle data before training.

When a model is trained, the data is divided into small sets (batches). Each batch is then fed to the model. Shuffling is important to prevent the model getting the same data over again. If using the same data twice, the model will not be able to generalize the data and give the right output. Shuffling gives a better variety of data in each batch.

tf.util.shuffle( data );

The shuffle() function is used to shuffle the stated array in order with the help of Fisher-Yates algorithm.

TensorFlow Tensors
To use TensorFlow, input data needs to be converted to tensor data:

// Mapping x values to Tensor inputs
const inputs = values.map( obj => obj.x );
// Mapping y values to Tensor labels
const labels = values.map( obj => obj.y );

// Converting inputs and labels to 2d tensors
const inputTensor = tf.tensor2d( inputs, [ inputs.length, 1 ] );
const labelTensor = tf.tensor2d( labels, [ labels.length, 1 ] );
const inputs = values.map( obj => obj.x );
JavaScript arrow function => allows us to write shorter function syntax.

const inputTensor = tf.tensor2d( inputs, [ inputs.length, 1 ] );
The tensor2d() function is used to create a new 2-dimensional tensor with the parameter namely value, shape, and datatype.
http://undcemcs01.und.edu/~wen.chen.hu/course/525/13/car.html
<html>
 <head>
  <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script>
  <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-vis"></script>
  <title>Car TensorFlow.js</title>
 </head>
 <body>
  <form>
   Horsepower:
   <input name="hp" id="hp" size="7" value="85" />
   <input type="button" onClick="runTF( )" value="Train and test" />
   <input type="reset" />
   The predicted MPG is <span id="answer">0.00</span> miles per gallon.
   <div id="plot1"></div>
   <div id="plot2"></div>
  </form>

  <script>
   // Extracting the required data 
   function extractData( obj ) {
    return { x:obj.Horsepower, y:obj.Miles_per_Gallon };
   }
   function removeErrors( obj ) {
    return ( ( obj.x != null ) && ( obj.y != null ) );
   }

   // Plotting the extracted data
   function tfPlot( values, surface ) {
    tfvis.render.scatterplot( surface,
     { values:values, series:[ 'Original', 'Predicted' ] },
     { xLabel:'Horsepower', yLabel:'MPG' } );
   }

   // Main function
   async function runTF( ) {
    const jsonData = await fetch( "carsData.json" );
    let values = await jsonData.json( );
    values = values.map( extractData ).filter( removeErrors );

    // Plotting the Data
    const surface1 = document.getElementById( "plot1" );
    const surface2 = document.getElementById( "plot2" );
    tfPlot( values, surface1 );

    // Converting the input to Tensors
    const inputs = values.map( obj => obj.x );
    const labels = values.map( obj => obj.y );
    const inputTensor = tf.tensor2d( inputs, [inputs.length, 1] );
    const labelTensor = tf.tensor2d( labels, [labels.length, 1] );
    const inputMin = inputTensor.min( );  
    const inputMax = inputTensor.max( );
    const labelMin = labelTensor.min( );
    const labelMax = labelTensor.max( );
    const nmInputs = inputTensor.sub(inputMin).div( inputMax.sub(inputMin) );
    const nmLabels = labelTensor.sub(labelMin).div( labelMax.sub(labelMin) );

    // Creating a Tensorflow model
    const model = tf.sequential( ); 
    model.add( tf.layers.dense( { inputShape:[1], units:1, useBias:true } ) );
    model.add( tf.layers.dense( { units: 1, useBias: true } ) );
    model.compile( { loss:'meanSquaredError', optimizer:'sgd' } );

    // Starting training
    await trainModel( model, nmInputs, nmLabels, surface2 );

    // Un-normalizing the data
    let unX = tf.linspace( 0, 1, 100 );      
    let unY = model.predict( unX.reshape( [100, 1] ) );      
    const unNormunX = unX
     .mul( inputMax.sub( inputMin ) )
     .add( inputMin );
    const unNormunY = unY
     .mul( labelMax.sub( labelMin ) )
     .add( labelMin );
    unX = unNormunX.dataSync( );
    unY = unNormunY.dataSync( );

    // Testing the model
    const predicted = Array.from(unX).map( (val, i) => {
     return { x: val, y: unY[i] }
    } );
    tfPlot( [values, predicted], surface1 );

    // Finding the MPG of the input horsepower
    var hp = parseInt( document.getElementById( "hp" ).value );
    unX.sort( ( a, b ) => a[0] - b[0] );
    let x1 = unX[0];
    for ( let i = 1; i < unX.length-1; i++ ) {
     let x2 = unX[i];
     if ( ( x1 <= hp ) && ( hp < x2 ) ) {
      document.getElementById("answer").innerHTML = Math.round( unY[i-1] );
      break;
     }
     x1 = x2;
    }

   // Asyncronous function to train the model
   async function trainModel( model, inputs, labels, surface ) {
    const batchSize = 25;
    const epochs = 50;
    const callbacks = tfvis.show.fitCallbacks(
     surface, ['loss'], { callbacks:['onEpochEnd'] } );
    return await model.fit( inputs, labels,
     { batchSize, epochs, shuffle:true, callbacks:callbacks } );
   }     // End of trainModel
  </script>
 </body>
</html>




      If you are on a long drive, it is helpful to stop and take    
      forty winks (a short nap) every few hours if you can.