训练数据归一化后如何预测?
How to predict after training data is normalized?
我正在学习 TensorFlow.js 使用官方文档并修改代码 mentioned in Codelab 以在给定公斤值作为输入时输出磅数。
所以我有一个 run
函数,它在加载 DOM 时 运行s。
async function run() {
const model = createModel();
const data = createData();
const tensorData = convertToTensor(data);
const { inputs, labels } = tensorData;
// Train Model
await trainModel(model, inputs, labels);
console.log('Training Complete');
// Predict
const normalizedPredictData = normalizeData([5]);
const { normalizedPredictDataVal, predictValMax, predictValMin } = normalizedPredictData;
const output = model.predict(normalizedPredictDataVal);
const finalOutput = unNormalizeData(output, predictValMax, predictValMin);
console.log(finalOutput.print());
}
document.addEventListener('DOMContentLoaded', run);
createModel 创建一个具有 2 层的简单顺序模型 - 一个隐藏层和一个输出层。
function createModel() {
const model = tf.sequential();
// Hidden Layer
model.add(tf.layers.dense({ units: 1, inputShape: [1] }));
// Output Layer
model.add(tf.layers.dense({ units: 1 }));
return model;
}
createData 是一个生成 500 个训练值的函数。
function createData() {
const data = {
inputs: Array.from({ length: 500 }, (x, i) => i),
labels: Array.from({ length: 500 }, (x, i) => i * 2.2)
};
return data;
}
输入 运行 从 0 到 499 和标签只是输入 * 2.2 因为我想在给定公斤值作为输入时预测磅数。
convertToTensor
函数将生成的数据转换为张量后对其进行归一化。
function convertToTensor(data) {
return tf.tidy(() => {
tf.util.shuffle(data);
const inputs = data.inputs;
const labels = data.labels;
const inputTensor = tf.tensor2d(inputs, [inputs.length, 1]);
const labelTensor = tf.tensor2d(labels, [labels.length, 1]);
// Normalize Data
const inputMax = inputTensor.max();
const inputMin = inputTensor.min();
const labelMax = inputTensor.max();
const labelMin = inputTensor.min();
const normalizedInputs = inputTensor.sub(inputMin).div(inputMax.sub(inputMin));
const normalizedLabels = labelTensor.sub(labelMin).div(labelMax.sub(labelMin));
return {
inputs: normalizedInputs,
labels: normalizedLabels,
inputMax,
inputMin,
labelMax,
labelMin
};
});
}
最后使用trainModel
训练数据
async function trainModel(model, inputs, labels) {
model.compile({
optimizer: tf.train.adam(),
loss: tf.losses.meanSquaredError,
metrics: ['mse']
});
const batchSize = 32;
const epochs = 50;
return await model.fit(inputs, labels, {
batchSize,
epochs,
shuffle: true,
callbacks: tfvis.show.fitCallbacks(
{ name: 'Training Performance' },
['loss', 'mse'],
{ height: 200, callbacks: ['onEpochEnd'] }
)
});
}
现在数据已经训练好了,是时候预测值了。由于模型是用归一化值训练的,我只将归一化输入值传递给预测函数。
function normalizeData(value) {
const predictValTensor = tf.tensor2d(value, [value.length, 1]);
const predictValMax = predictValTensor.max();
const predictValMin = predictValTensor.min();
const normalizedPredictDataVal = predictValTensor.sub(predictValMin).div(predictValMax.sub(predictValMin));
return {
normalizedPredictDataVal,
predictValMax,
predictValMin
};
}
上述函数将值转换为张量,对其进行归一化,然后将结果 returns 传递给预测函数以获得输出值。由于输入已标准化,因此需要对输出进行非标准化,因此创建了一个函数来对其进行非标准化。
function unNormalizeData(value, predictMax, predictMin) {
const unNormPredictVal = value.mul(predictMax.sub(predictMin)).add(predictMin);
return unNormPredictVal;
}
一旦输出未规范化,我只是将其记录到控制台。但它只是输出我作为输入给出的值。在本例中,该值为 5.
编码直到训练数据工作正常。我认为错误在于我试图规范化和非规范化预测值的地方。
应使用训练样本的最大值和最小值对预测值进行归一化。
不应该有predictValMax
(分别predictValMin
)不同于inputMax
(分别inputMin
)
const predictValMax = predictValTensor.max();
const predictValMin = predictValTensor.min();
特征的预测应该是特征数据集不变的。
特征训练集
[-5, 5], inputMin = -5, inputMax = 5; normalized = [0, 0.5]
鉴于这两个测试集的特征:
[5, 6], predictMin = 5, predictMax = 6; normalized = [0, 1];
[5], predictMin = 5, predictMax = 6; normalize = [1] // ( though a division by zero occurs here).
5 的归一化值在测试集中不同。它也不同于训练数据中的归一化值。该模型每次出现时都会为相同的特征 5 预测不同的值,因为它的归一化值取决于数据集。
如果对每个预测值应用相同的归一化参数(inputMin
、inputMax
),则不会发生这种情况。
function createModel() {
const model = tf.sequential();
// Hidden Layer
model.add(tf.layers.dense({ units: 1, inputShape: [1] }));
// Output Layer
model.add(tf.layers.dense({ units: 1 }));
return model;
}
let inputMin, inputMax, labelMin, labelMax
function createData() {
const data = {
inputs: Array.from({ length: 500 }, (x, i) => i),
labels: Array.from({ length: 500 }, (x, i) => i * 2.2)
};
return data;
}
function convertToTensor(data) {
return tf.tidy(() => {
tf.util.shuffle(data);
const inputs = data.inputs;
const labels = data.labels;
const inputTensor = tf.tensor2d(inputs, [inputs.length, 1]);
const labelTensor = tf.tensor2d(labels, [labels.length, 1]);
inputTensor.print();
labelTensor.print()
// Normalize Data
inputMax = inputTensor.max();
inputMin = inputTensor.min();
labelMax = inputTensor.max();
labelMin = inputTensor.min();
const normalizedInputs = inputTensor.sub(inputMin).div(inputMax.sub(inputMin));
const normalizedLabels = labelTensor.sub(labelMin).div(labelMax.sub(labelMin));
return {
inputs: normalizedInputs,
labels: normalizedLabels,
inputMax,
inputMin,
labelMax,
labelMin
};
});
}
async function trainModel(model, inputs, labels) {
const learningRate = 0.01;
const optimizer = tf.train.sgd(learningRate);
// tf.train.adam()
model.compile({
optimizer: optimizer ,
loss: tf.losses.meanSquaredError,
metrics: ['mse']
});
const batchSize = 32;
const epochs = 200;
inputs.print()
labels.print()
return await model.fit(inputs, labels, {
batchSize,
epochs,
shuffle: true,
callbacks: tfvis.show.fitCallbacks(
{ name: 'Training Performance' },
['loss', 'mse'],
{ height: 200, callbacks: ['onEpochEnd'] }
)
});
}
function normalizeData(value) {
const predictValTensor = tf.tensor2d(value, [value.length, 1]);
//const predictValMax = predictValTensor.max();
//const predictValMin = predictValTensor.min();
const normalizedPredictDataVal = predictValTensor.sub(inputMin).div(inputMax.sub(inputMin));
return {
normalizedPredictDataVal,
inputMax,
inputMin
};
}
function unNormalizeData(value, predictMax, predictMin) {
const unNormPredictVal = value.mul(inputMax.sub(inputMin)).add(inputMin);
return unNormPredictVal;
}
async function run() {
const model = createModel();
const data = createData();
const tensorData = convertToTensor(data);
const { inputs, labels } = tensorData;
await trainModel(model, inputs, labels);
console.log('Training Complete');
const normalizedPredictData = await normalizeData([1000, 6, 7]);
console.log('normalizedinput')
normalizedPredictData.normalizedPredictDataVal.print()
const { normalizedPredictDataVal, predictValMax, predictValMin } = normalizedPredictData;
const output = await model.predict(normalizedPredictDataVal);
console.log(output.print());
const finalOutput = await unNormalizeData(output, predictValMax, predictValMin);
console.log(finalOutput.print());
}
document.addEventListener('DOMContentLoaded', run);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.0.0/dist/tf.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-vis@1.0.2/dist/tfjs-vis.umd.min.js"></script>
<script src="index.js"></script>
</body>
</html>
我正在学习 TensorFlow.js 使用官方文档并修改代码 mentioned in Codelab 以在给定公斤值作为输入时输出磅数。
所以我有一个 run
函数,它在加载 DOM 时 运行s。
async function run() {
const model = createModel();
const data = createData();
const tensorData = convertToTensor(data);
const { inputs, labels } = tensorData;
// Train Model
await trainModel(model, inputs, labels);
console.log('Training Complete');
// Predict
const normalizedPredictData = normalizeData([5]);
const { normalizedPredictDataVal, predictValMax, predictValMin } = normalizedPredictData;
const output = model.predict(normalizedPredictDataVal);
const finalOutput = unNormalizeData(output, predictValMax, predictValMin);
console.log(finalOutput.print());
}
document.addEventListener('DOMContentLoaded', run);
createModel 创建一个具有 2 层的简单顺序模型 - 一个隐藏层和一个输出层。
function createModel() {
const model = tf.sequential();
// Hidden Layer
model.add(tf.layers.dense({ units: 1, inputShape: [1] }));
// Output Layer
model.add(tf.layers.dense({ units: 1 }));
return model;
}
createData 是一个生成 500 个训练值的函数。
function createData() {
const data = {
inputs: Array.from({ length: 500 }, (x, i) => i),
labels: Array.from({ length: 500 }, (x, i) => i * 2.2)
};
return data;
}
输入 运行 从 0 到 499 和标签只是输入 * 2.2 因为我想在给定公斤值作为输入时预测磅数。
convertToTensor
函数将生成的数据转换为张量后对其进行归一化。
function convertToTensor(data) {
return tf.tidy(() => {
tf.util.shuffle(data);
const inputs = data.inputs;
const labels = data.labels;
const inputTensor = tf.tensor2d(inputs, [inputs.length, 1]);
const labelTensor = tf.tensor2d(labels, [labels.length, 1]);
// Normalize Data
const inputMax = inputTensor.max();
const inputMin = inputTensor.min();
const labelMax = inputTensor.max();
const labelMin = inputTensor.min();
const normalizedInputs = inputTensor.sub(inputMin).div(inputMax.sub(inputMin));
const normalizedLabels = labelTensor.sub(labelMin).div(labelMax.sub(labelMin));
return {
inputs: normalizedInputs,
labels: normalizedLabels,
inputMax,
inputMin,
labelMax,
labelMin
};
});
}
最后使用trainModel
async function trainModel(model, inputs, labels) {
model.compile({
optimizer: tf.train.adam(),
loss: tf.losses.meanSquaredError,
metrics: ['mse']
});
const batchSize = 32;
const epochs = 50;
return await model.fit(inputs, labels, {
batchSize,
epochs,
shuffle: true,
callbacks: tfvis.show.fitCallbacks(
{ name: 'Training Performance' },
['loss', 'mse'],
{ height: 200, callbacks: ['onEpochEnd'] }
)
});
}
现在数据已经训练好了,是时候预测值了。由于模型是用归一化值训练的,我只将归一化输入值传递给预测函数。
function normalizeData(value) {
const predictValTensor = tf.tensor2d(value, [value.length, 1]);
const predictValMax = predictValTensor.max();
const predictValMin = predictValTensor.min();
const normalizedPredictDataVal = predictValTensor.sub(predictValMin).div(predictValMax.sub(predictValMin));
return {
normalizedPredictDataVal,
predictValMax,
predictValMin
};
}
上述函数将值转换为张量,对其进行归一化,然后将结果 returns 传递给预测函数以获得输出值。由于输入已标准化,因此需要对输出进行非标准化,因此创建了一个函数来对其进行非标准化。
function unNormalizeData(value, predictMax, predictMin) {
const unNormPredictVal = value.mul(predictMax.sub(predictMin)).add(predictMin);
return unNormPredictVal;
}
一旦输出未规范化,我只是将其记录到控制台。但它只是输出我作为输入给出的值。在本例中,该值为 5.
编码直到训练数据工作正常。我认为错误在于我试图规范化和非规范化预测值的地方。
应使用训练样本的最大值和最小值对预测值进行归一化。
不应该有predictValMax
(分别predictValMin
)不同于inputMax
(分别inputMin
)
const predictValMax = predictValTensor.max();
const predictValMin = predictValTensor.min();
特征的预测应该是特征数据集不变的。 特征训练集
[-5, 5], inputMin = -5, inputMax = 5; normalized = [0, 0.5]
鉴于这两个测试集的特征:
[5, 6], predictMin = 5, predictMax = 6; normalized = [0, 1];
[5], predictMin = 5, predictMax = 6; normalize = [1] // ( though a division by zero occurs here).
5 的归一化值在测试集中不同。它也不同于训练数据中的归一化值。该模型每次出现时都会为相同的特征 5 预测不同的值,因为它的归一化值取决于数据集。
如果对每个预测值应用相同的归一化参数(inputMin
、inputMax
),则不会发生这种情况。
function createModel() {
const model = tf.sequential();
// Hidden Layer
model.add(tf.layers.dense({ units: 1, inputShape: [1] }));
// Output Layer
model.add(tf.layers.dense({ units: 1 }));
return model;
}
let inputMin, inputMax, labelMin, labelMax
function createData() {
const data = {
inputs: Array.from({ length: 500 }, (x, i) => i),
labels: Array.from({ length: 500 }, (x, i) => i * 2.2)
};
return data;
}
function convertToTensor(data) {
return tf.tidy(() => {
tf.util.shuffle(data);
const inputs = data.inputs;
const labels = data.labels;
const inputTensor = tf.tensor2d(inputs, [inputs.length, 1]);
const labelTensor = tf.tensor2d(labels, [labels.length, 1]);
inputTensor.print();
labelTensor.print()
// Normalize Data
inputMax = inputTensor.max();
inputMin = inputTensor.min();
labelMax = inputTensor.max();
labelMin = inputTensor.min();
const normalizedInputs = inputTensor.sub(inputMin).div(inputMax.sub(inputMin));
const normalizedLabels = labelTensor.sub(labelMin).div(labelMax.sub(labelMin));
return {
inputs: normalizedInputs,
labels: normalizedLabels,
inputMax,
inputMin,
labelMax,
labelMin
};
});
}
async function trainModel(model, inputs, labels) {
const learningRate = 0.01;
const optimizer = tf.train.sgd(learningRate);
// tf.train.adam()
model.compile({
optimizer: optimizer ,
loss: tf.losses.meanSquaredError,
metrics: ['mse']
});
const batchSize = 32;
const epochs = 200;
inputs.print()
labels.print()
return await model.fit(inputs, labels, {
batchSize,
epochs,
shuffle: true,
callbacks: tfvis.show.fitCallbacks(
{ name: 'Training Performance' },
['loss', 'mse'],
{ height: 200, callbacks: ['onEpochEnd'] }
)
});
}
function normalizeData(value) {
const predictValTensor = tf.tensor2d(value, [value.length, 1]);
//const predictValMax = predictValTensor.max();
//const predictValMin = predictValTensor.min();
const normalizedPredictDataVal = predictValTensor.sub(inputMin).div(inputMax.sub(inputMin));
return {
normalizedPredictDataVal,
inputMax,
inputMin
};
}
function unNormalizeData(value, predictMax, predictMin) {
const unNormPredictVal = value.mul(inputMax.sub(inputMin)).add(inputMin);
return unNormPredictVal;
}
async function run() {
const model = createModel();
const data = createData();
const tensorData = convertToTensor(data);
const { inputs, labels } = tensorData;
await trainModel(model, inputs, labels);
console.log('Training Complete');
const normalizedPredictData = await normalizeData([1000, 6, 7]);
console.log('normalizedinput')
normalizedPredictData.normalizedPredictDataVal.print()
const { normalizedPredictDataVal, predictValMax, predictValMin } = normalizedPredictData;
const output = await model.predict(normalizedPredictDataVal);
console.log(output.print());
const finalOutput = await unNormalizeData(output, predictValMax, predictValMin);
console.log(finalOutput.print());
}
document.addEventListener('DOMContentLoaded', run);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.0.0/dist/tf.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-vis@1.0.2/dist/tfjs-vis.umd.min.js"></script>
<script src="index.js"></script>
</body>
</html>