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.

1tf.util.shuffle( data );

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

1// Mapping x values to Tensor inputs
2const inputs = values.map( obj => obj.x );
3// Mapping y values to Tensor labels
4const labels = values.map( obj => obj.y );
5 
6// Converting inputs and labels to 2d tensors
7const inputTensor = tf.tensor2d( inputs, [ inputs.length, 1 ] );
8const labelTensor = tf.tensor2d( labels, [ labels.length, 1 ] );

Data Normalization
Data should be normalized before being used in a neural network. A range of 0 - 1 using min-max are often best for numerical data:

1const inputMin = inputTensor.min( );
2const inputMax = inputTensor.max( );
3const labelMin = labelTensor.min( );
4const labelMax = labelTensor.max( );
5const nmInputs = inputTensor.sub( inputMin ).div( inputMax.sub( inputMin ) );
6const nmLabels = labelTensor.sub( labelMin ).div( labelMax.sub( labelMin ) );

http://undcemcs01.und.edu/~wen.chen.hu/course/525/13/car.html
001<html>
002 <head>
003  <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script>
005  <title>Car TensorFlow.js</title>
006 </head>
007 <body>
008  <form>
009   Horsepower:
010   <input name="hp" id="hp" size="7" value="85" />
011   <input type="button" onClick="runTF( )" value="Train and test" />
012   <input type="reset" />
013   The predicted MPG is <span id="answer">0.00</span> miles per gallon.
014   <div id="plot1"></div>
015   <div id="plot2"></div>
016  </form>
017 
018  <script>
019   // Extracting the required data
020   function extractData( obj ) {
021    return { x:obj.Horsepower, y:obj.Miles_per_Gallon };
022   }
023   function removeErrors( obj ) {
024    return ( ( obj.x != null ) && ( obj.y != null ) );
025   }
026 
027   // Plotting the extracted data
028   function tfPlot( values, surface ) {
029    tfvis.render.scatterplot( surface,
030     { values:values, series:[ 'Original', 'Predicted' ] },
031     { xLabel:'Horsepower', yLabel:'MPG' } );
032   }
033 
034   // Main function
035   async function runTF( ) {
036    const jsonData = await fetch( "carsData.json" );
037    let values = await jsonData.json( );
038    values = values.map( extractData ).filter( removeErrors );
039 
040    // Plotting the Data
041    const surface1 = document.getElementById( "plot1" );
042    const surface2 = document.getElementById( "plot2" );
043    tfPlot( values, surface1 );
044 
045    // Converting the input to Tensors
046    const inputs = values.map( obj => obj.x );
047    const labels = values.map( obj => obj.y );
048    const inputTensor = tf.tensor2d( inputs, [inputs.length, 1] );
049    const labelTensor = tf.tensor2d( labels, [labels.length, 1] );
050    const inputMin = inputTensor.min( ); 
051    const inputMax = inputTensor.max( );
052    const labelMin = labelTensor.min( );
053    const labelMax = labelTensor.max( );
054    const nmInputs = inputTensor.sub(inputMin).div( inputMax.sub(inputMin) );
055    const nmLabels = labelTensor.sub(labelMin).div( labelMax.sub(labelMin) );
056 
057    // Creating a Tensorflow model
058    const model = tf.sequential( );
059    model.add( tf.layers.dense( { inputShape:[1], units:1, useBias:true } ) );
060    model.add( tf.layers.dense( { units: 1, useBias: true } ) );
061    model.compile( { loss:'meanSquaredError', optimizer:'sgd' } );
062 
063    // Starting training
064    await trainModel( model, nmInputs, nmLabels, surface2 );
065 
066    // Un-normalizing the data
067    let unX = tf.linspace( 0, 1, 100 );     
068    let unY = model.predict( unX.reshape( [100, 1] ) );     
069    const unNormunX = unX
070     .mul( inputMax.sub( inputMin ) )
071     .add( inputMin );
072    const unNormunY = unY
073     .mul( labelMax.sub( labelMin ) )
074     .add( labelMin );
075    unX = unNormunX.dataSync( );
076    unY = unNormunY.dataSync( );
077 
078    // Testing the model
079    const predicted = Array.from(unX).map( (val, i) => {
080     return { x: val, y: unY[i] }
081    } );
082    tfPlot( [values, predicted], surface1 );
083 
084    // Finding the MPG of the input horsepower 
085    var hp = parseInt( document.getElementById( "hp" ).value );
086    unX.sort( ( a, b ) => a[0] - b[0] );
087    let x1 = unX[0];
088    for ( let i = 1; i < unX.length-1; i++ ) {
089     let x2 = unX[i];
090     if ( ( x1 <= hp ) && ( hp < x2 ) ) {
091      document.getElementById("answer").innerHTML = Math.round( unY[i-1] );
092      break;
093     }
094     x1 = x2;
095    }
096   }     // End of the main function runTF( )
097 
098   // Asyncronous function to train the model
099   async function trainModel( model, inputs, labels, surface ) {
100    const batchSize = 25;
101    const epochs = 50;
102    const callbacks = tfvis.show.fitCallbacks(
103     surface, ['loss'], { callbacks:['onEpochEnd'] } );
104    return await model.fit( inputs, labels,
105     { batchSize, epochs, shuffle:true, callbacks:callbacks } );
106   }     // End of trainModel
107  </script>
108 </body>
109</html>