index.html完整代码

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>TensorFlow.js Tutorial</title>
  5. <!-- Import TensorFlow.js -->
  6. <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@2.0.0/dist/tf.min.js"></script>
  7. <!-- Import tfjs-vis -->
  8. <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-vis@1.0.2/dist/tfjs-vis.umd.min.js"></script>
  9. <!-- Import the main script file -->
  10. <script src="script.js"></script>
  11. </head>
  12. <body>
  13. </body>
  14. </html>

script.js完整代码

  1. /**
  2. * Get the car data reduced to just the variables we are interested
  3. * and cleaned of missing data.
  4. */
  5. async function getData() {
  6. const carsDataResponse = await fetch('https://storage.googleapis.com/tfjs-tutorials/carsData.json');
  7. const carsData = await carsDataResponse.json();
  8. const cleaned = carsData.map(car => ({
  9. mpg: car.Miles_per_Gallon,
  10. horsepower: car.Horsepower,
  11. }))
  12. .filter(car => (car.mpg != null && car.horsepower != null));
  13. return cleaned;
  14. }
  15. async function run() {
  16. // Load and plot the original input data that we are going to train on.
  17. const data = await getData();
  18. const values = data.map(d => ({
  19. x: d.horsepower,
  20. y: d.mpg,
  21. }));
  22. tfvis.render.scatterplot({ name: 'Horsepower v MPG' }, { values }, {
  23. xLabel: 'Horsepower',
  24. yLabel: 'MPG',
  25. height: 300
  26. });
  27. // More code will be added below
  28. const model = createModel();
  29. tfvis.show.modelSummary({ name: 'Model Summary' }, model);
  30. // Convert the data to a form we can use for training.
  31. const tensorData = convertToTensor(data);
  32. const { inputs, labels } = tensorData;
  33. // Train the model
  34. await trainModel(model, inputs, labels);
  35. console.log('Done Training');
  36. // Make some predictions using the model and compare them to the
  37. // original data
  38. testModel(model, data, tensorData);
  39. }
  40. document.addEventListener('DOMContentLoaded', run);
  41. function createModel() {
  42. // Create a sequential model
  43. const model = tf.sequential();
  44. // Add a single input layer
  45. // dense 是一种层,可将输入与矩阵(称为“权重”)相乘,并向结果添加一个数字(称为“偏差”)
  46. // inputShape 是 [1],因为我们将 1 数字用作输入(某辆指定汽车的马力)
  47. // units 用于设置权重矩阵在层中的大小。将其设置为 1 即表示数据的每个输入特征的权重为 1
  48. model.add(tf.layers.dense({ inputShape: [1], units: 1, useBias: true }));
  49. model.add(tf.layers.dense({ units: 10, activation: 'sigmoid' }));
  50. model.add(tf.layers.dense({ units: 20, activation: 'sigmoid' }));
  51. // model.add(tf.layers.dense({ units: 50, activation: 'sigmoid' }));
  52. // Add an output layer
  53. model.add(tf.layers.dense({ units: 1, useBias: true }));
  54. return model;
  55. }
  56. /**
  57. * Convert the input data to tensors that we can use for machine
  58. * learning. We will also do the important best practices of _shuffling_
  59. * the data and _normalizing_ the data
  60. * MPG on the y-axis.
  61. * 数据重排和归一化
  62. */
  63. function convertToTensor(data) {
  64. // Wrapping these calculations in a tidy will dispose any
  65. // intermediate tensors.
  66. return tf.tidy(() => {
  67. // Step 1. Shuffle the data
  68. tf.util.shuffle(data);
  69. // Step 2. Convert data to Tensor
  70. const inputs = data.map(d => d.horsepower)
  71. const labels = data.map(d => d.mpg);
  72. const inputTensor = tf.tensor2d(inputs, [inputs.length, 1]);
  73. const labelTensor = tf.tensor2d(labels, [labels.length, 1]);
  74. //Step 3. Normalize the data to the range 0 - 1 using min-max scaling
  75. const inputMax = inputTensor.max();
  76. const inputMin = inputTensor.min();
  77. const labelMax = labelTensor.max();
  78. const labelMin = labelTensor.min();
  79. const normalizedInputs = inputTensor.sub(inputMin).div(inputMax.sub(inputMin));
  80. const normalizedLabels = labelTensor.sub(labelMin).div(labelMax.sub(labelMin));
  81. return {
  82. inputs: normalizedInputs,
  83. labels: normalizedLabels,
  84. // Return the min/max bounds so we can use them later.
  85. inputMax,
  86. inputMin,
  87. labelMax,
  88. labelMin,
  89. }
  90. });
  91. }
  92. // 创建模型实例并将数据表示为张量之后,我们就可以开始训练过程了。
  93. async function trainModel(model, inputs, labels) {
  94. // Prepare the model for training.
  95. model.compile({
  96. optimizer: tf.train.adam(),
  97. loss: tf.losses.meanSquaredError,
  98. metrics: ['mse'],
  99. });
  100. const batchSize = 32;
  101. const epochs = 50;
  102. return await model.fit(inputs, labels, {
  103. batchSize,
  104. epochs,
  105. shuffle: true,
  106. callbacks: tfvis.show.fitCallbacks({ name: 'Training Performance' }, ['loss', 'mse'], { height: 200, callbacks: ['onEpochEnd'] })
  107. });
  108. }
  109. // 预测
  110. function testModel(model, inputData, normalizationData) {
  111. const { inputMax, inputMin, labelMin, labelMax } = normalizationData;
  112. // Generate predictions for a uniform range of numbers between 0 and 1;
  113. // We un-normalize the data by doing the inverse of the min-max scaling
  114. // that we did earlier.
  115. const [xs, preds] = tf.tidy(() => {
  116. const xs = tf.linspace(0, 1, 100);
  117. const preds = model.predict(xs.reshape([100, 1]));
  118. const unNormXs = xs
  119. .mul(inputMax.sub(inputMin))
  120. .add(inputMin);
  121. const unNormPreds = preds
  122. .mul(labelMax.sub(labelMin))
  123. .add(labelMin);
  124. // Un-normalize the data
  125. return [unNormXs.dataSync(), unNormPreds.dataSync()];
  126. });
  127. const predictedPoints = Array.from(xs).map((val, i) => {
  128. return { x: val, y: preds[i] }
  129. });
  130. const originalPoints = inputData.map(d => ({
  131. x: d.horsepower,
  132. y: d.mpg,
  133. }));
  134. tfvis.render.scatterplot({ name: 'Model Predictions vs Original Data' }, { values: [originalPoints, predictedPoints], series: ['original', 'predicted'] }, {
  135. xLabel: 'Horsepower',
  136. yLabel: 'MPG',
  137. height: 300
  138. });
  139. }