TensorFlow Model (Cont.)


Compiling a Model
Compile the model with a specified optimizer and loss function:

model.compile( { loss: 'meanSquaredError', optimizer:'sgd' } );

Optimizer
Optimizers are algorithms or methods used to minimize a loss function or to maximize the efficiency of production. They are mathematical functions which are dependent on model’s learnable parameters, e.g., weights and biases. Optimizers help to know how to change weights and learning rate of machine learning to reduce the losses. The compiler is set to use the SGD (Stochastic Gradient Descent) optimizer. Other optimizers can be found from here.

Loss Function
The loss function is a method of evaluating how well your machine learning algorithm models your featured data set. If your loss function value is low, your model will provide good results. meanSquaredError is the function we want to use to compare model predictions and true values. Other loss functions could be found from here. Broadly speaking, loss functions can be grouped into two major categories concerning the types of problems we come across in the real world: classification and regression:
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 );

    const hp1 = [ ];
    temp = document.getElementById( "hp" ).value;
    hp1[0] = parseInt( temp );
    const input = tf.tensor2d( hp1, [1,1] );
    const predictOut = model.predict( input );
    const logits = Array.from( predictOut.dataSync( ) );
    if ( logits[0] < 0 )
     document.getElementById("answer").innerHTML = 0.00 + " (" + logits[0] + ")";
    else
     document.getElementById("answer").innerHTML = Math.round( logits[0] );
   }     // End of the main function runTF( )

   // 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>