# 归一化
# 代码展示
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];
}
};