# 归一化任务
把大数量级特征转化到较小的数量级下,通常是[0, 1]或[-1, 1]
# 为何要归一化
- 绝大多数 tensorflow.js 的模型都不是给特别大的数设计的
- 将不同数量级的特征转换到同一数量级,防止某个特征影响过大
# 初始数据
import * as tf from "@tensorflow/tfjs";
import * as tfvis from "@tensorflow/tfjs-vis";
window.onload = () => {
const heigths = [150, 160, 170];
const weights = [40, 50, 60];
tfvis.render.scatterplot(
{ name: "身高体重训练数据" },
{ values: heigths.map((x, i) => ({ x, y: weights[i] })) },
{ xAxisDomain: [140, 180], yAxisDomain: [30, 70] }
);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 归一化操作
import * as tf from "@tensorflow/tfjs";
import * as tfvis from "@tensorflow/tfjs-vis";
window.onload = () => {
const heigths = [150, 160, 170];
const weights = [40, 50, 60];
tfvis.render.scatterplot(
{ name: "身高体重训练数据" },
{ values: heigths.map((x, i) => ({ x, y: weights[i] })) },
{ xAxisDomain: [140, 180], yAxisDomain: [30, 70] }
);
// ----------------------------------------------------------------
// 归一化操作
// 输入值归一化
// 数组的数据先减去最小值 150,然后再除以间距 20 ,这样数据就被处理成了归一化的 [0,1]之间的数了
const inputs = tf
.tensor(heigths)
.sub(150)
.div(20);
inputs.print(); // Tensor [0, 0.5, 1]
const labels = tf
.tensor(weights)
.sub(40)
.div(20);
labels.print(); // Tensor [0, 0.5, 1]
// ----------------------------------------------------------------
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 训练,预测,反归一化
import * as tf from "@tensorflow/tfjs";
import * as tfvis from "@tensorflow/tfjs-vis";
import { mod, input } from "@tensorflow/tfjs";
window.onload = async () => {
const heigths = [150, 160, 170];
const weights = [40, 50, 60];
tfvis.render.scatterplot(
{ name: "身高体重训练数据" },
{ values: heigths.map((x, i) => ({ x, y: weights[i] })) },
{ xAxisDomain: [140, 180], yAxisDomain: [30, 70] }
);
// 归一化操作
// 输入值归一化
// 数组的数据先减去最小值 150,然后再除以间距 20 ,这样数据就被处理成了归一化的 [0,1]之间的数了
const inputs = tf
.tensor(heigths)
.sub(150)
.div(20);
const labels = tf
.tensor(weights)
.sub(40)
.div(20);
// 训练,预测,反归一化
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: 3,
epochs: 100,
callbacks: tfvis.show.fitCallbacks({ name: "训练过程" }, ["loss"])
});
// 预测数据需要归一化
const output = model.predict(
tf
.tensor([180])
.sub(150)
.div(20)
);
alert(
`如果身高为 180cm, 那么预测体重为 ${
output
.mul(20)
.add(40)
.dataSync()[0]
}`
);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58