005 | <title>Car TensorFlow.js</title> |
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> |
020 | function extractData( obj ) { |
021 | return { x:obj.Horsepower, y:obj.Miles_per_Gallon }; |
023 | function removeErrors( obj ) { |
024 | return ( ( obj.x != null ) && ( obj.y != null ) ); |
028 | function tfPlot( values, surface ) { |
029 | tfvis.render.scatterplot( surface, |
030 | { values:values, series:[ 'Original' , 'Predicted' ] }, |
031 | { xLabel: 'Horsepower' , yLabel: 'MPG' } ); |
035 | async function runTF( ) { |
036 | const jsonData = await fetch( "carsData.json" ); |
037 | let values = await jsonData.json( ); |
038 | values = values.map( extractData ).filter( removeErrors ); |
041 | const surface1 = document.getElementById( "plot1" ); |
042 | const surface2 = document.getElementById( "plot2" ); |
043 | tfPlot( values, surface1 ); |
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) ); |
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' } ); |
064 | await trainModel( model, nmInputs, nmLabels, surface2 ); |
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 ) ) |
072 | const unNormunY = unY |
073 | .mul( labelMax.sub( labelMin ) ) |
075 | unX = unNormunX.dataSync( ); |
076 | unY = unNormunY.dataSync( ); |
079 | const predicted = Array.from(unX).map( (val, i) => { |
080 | return { x: val, y: unY[i] } |
082 | tfPlot( [values, predicted], surface1 ); |
085 | var hp = parseInt( document.getElementById( "hp" ).value ); |
086 | unX.sort( ( a, b ) => a[0] - b[0] ); |
088 | for ( let i = 1; i < unX.length-1; i++ ) { |
090 | if ( ( x1 <= hp ) && ( hp < x2 ) ) { |
091 | document.getElementById( "answer" ).innerHTML = Math.round( unY[i-1] ); |
099 | async function trainModel( model, inputs, labels, surface ) { |
100 | const batchSize = 25; |
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 } ); |
|