# 归一化

# 代码展示

import * as tf from '@tensorflow/tfjs';
import * as tfvis from '@tensorflow/tfjs-vis';

window.onload = async () => {
  const heights = [150, 160, 170];
  const weights = [40, 50, 60];
  /*数据可视化*/
  tfvis.render.scatterplot(
    { name: '身高体重训练数据' },
    {
      values: heights.map((x, i) => {
        return {
          x,
          y: weights[i],
        };
      }),
    },
    {
      xAxisDomain: [140, 180],
      yAxisDomain: [30, 70],
    }
  );

  console.log(
    heights.map((x, i) => {
      return {
        x,
        y: weights[i],
      };
    })
  );

  /*构造归一化训练数据*/
  const heightsMin = Math.min.apply(null, heights);
  const heightsMax = Math.max.apply(null, heights);
  const weightsMin = Math.min.apply(null, weights);
  const weightsMax = Math.max.apply(null, weights);

  const inputs = normalizationData(heights, heightsMax, heightsMin);
  const labels = normalizationData(weights, weightsMax, weightsMin);
  console.log('inputs', inputs.dataSync());
  console.log('labels', labels.dataSync());
  /* 初始化模型 */
  const model = tf.sequential(); // 连续模型

  /*给模型添加层*/
  model.add(
    tf.layers.dense({
      units: 1, // 神经元个数
      inputShape: [1], //
    })
  );

  /*给模型设置损失函数与优化器*/
  model.compile({
    loss: tf.losses.meanSquaredError, // 损失函数-使用均方误差计算
    optimizer: tf.train.sgd(0.1), // 优化器-设置学习率
  });

  /*异步训练模型*/
  await model.fit(inputs, labels, {
    batchSize: 6, // 每次样本需要学习的样本数据量
    epochs: 200,
    callbacks: tfvis.show.fitCallbacks(
      // 可视化模拟训练过程
      { name: '训练过程' },
      ['loss'] // 制定度量单位(制作损失曲线)
    ),
  });

  /*输出预测结果并显示*/
  $('#test')
    .removeAttr('disabled')
    .on('click', function() {
      /*输出预测结果并显示*/
      const output = model.predict(
        normalizationData([Number($('#input').val())], heightsMax, heightsMin)
      ); // 输入一个tensor帮你预测结果并赋值给变量
      const resHeight = unNormalizationData(output, weightsMax, weightsMin);
      console.log(
        `如果身高是${Number($('#input').val())}cm,体重是:${resHeight}公斤`
      );
    });

  /*
   * 归一化数据
   * */
  function normalizationData(arr, max, min) {
    return tf
      .tensor(arr)
      .sub(min)
      .div(max - min);
  }

  /*
   * 反归一化
   * */
  function unNormalizationData(output, max, min) {
    return output
      .mul(max - min)
      .add(min)
      .dataSync()[0];
  }
};

# 重点笔记

  • 训练数据是归一化的,那么预测数据也是要归一化的

  • tensor 的减法sub

  • tensor 的除法div