reactjs - “从 2D 数据进行预测”代码实验室在每次刷新时给出随机结果
问题描述
我一直在关注这个代码实验室,但是我在测试经过训练的模型时得到的结果看起来很错误,代码实验室显示了这个图表
但是当我运行下面的代码时,直接取自代码实验室,我的图表看起来像这样..
为什么每次页面刷新的结果差异如此之大?
我曾尝试延迟测试,但没有更好的结果
setTimeout(function(){
console.log('Testing');
testModel(model, data, tensorData);
}, 6000);
我不明白为什么它们看起来如此不同,我的代码如下......
import React, { useEffect } from "react";
import * as tf from "@tensorflow/tfjs";
import * as tfvis from "@tensorflow/tfjs-vis";
function App() {
useEffect(() => {
const testModel = (model: any, inputData: any, normalizationData: any) => {
const {inputMax, inputMin, labelMin, labelMax} = normalizationData;
// Generate predictions for a uniform range of numbers between 0 and 1;
// We un-normalize the data by doing the inverse of the min-max scaling
// that we did earlier.
const [xs, preds] = tf.tidy(() => {
const xs = tf.linspace(0, 1, 100);
const preds = model.predict(xs.reshape([100, 1]));
const unNormXs = xs
.mul(inputMax.sub(inputMin))
.add(inputMin);
const unNormPreds = preds
.mul(labelMax.sub(labelMin))
.add(labelMin);
// Un-normalize the data
return [unNormXs.dataSync(), unNormPreds.dataSync()];
});
const predictedPoints = Array.from(xs).map((val, i) => {
return {x: val, y: preds[i]}
});
const originalPoints = inputData.map((d:any) => ({
x: d.horsepower, y: d.mpg,
}));
tfvis.render.scatterplot(
{name: 'Model Predictions vs Original Data'},
{values: [originalPoints, predictedPoints], series: ['original', 'predicted']},
{
xLabel: 'Horsepower',
yLabel: 'MPG',
height: 300
}
);
}
function convertToTensor(data:any) {
// Wrapping these calculations in a tidy will dispose any
// intermediate tensors.
return tf.tidy(() => {
// Step 1. Shuffle the data
tf.util.shuffle(data);
// Step 2. Convert data to Tensor
const inputs = data.map((d:any) => d.horsepower)
const labels = data.map((d:any) => d.mpg);
const inputTensor = tf.tensor2d(inputs, [inputs.length, 1]);
const labelTensor = tf.tensor2d(labels, [labels.length, 1]);
//Step 3. Normalize the data to the range 0 - 1 using min-max scaling
const inputMax = inputTensor.max();
const inputMin = inputTensor.min();
const labelMax = labelTensor.max();
const labelMin = labelTensor.min();
const normalizedInputs = inputTensor.sub(inputMin).div(inputMax.sub(inputMin));
const normalizedLabels = labelTensor.sub(labelMin).div(labelMax.sub(labelMin));
return {
inputs: normalizedInputs,
labels: normalizedLabels,
// Return the min/max bounds so we can use them later.
inputMax,
inputMin,
labelMax,
labelMin,
}
});
}
const trainModel = async(model:any, inputs:any, labels:any) => {
// Prepare the model for training.
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'] }
)
});
}
const createModel = () => {
// Create a sequential model
const model = tf.sequential();
// Add a single input layer
model.add(tf.layers.dense({inputShape: [1], units: 1, useBias: true}));
// Add an output layer
model.add(tf.layers.dense({units: 1, useBias: true}));
return model;
}
const getData = async () => {
const carsDataReq = await fetch("https://storage.googleapis.com/tfjs-tutorials/carsData.json");
const carsData = await carsDataReq.json();
const cleaned = carsData.map((car: any) => ({
mpg: car.Miles_per_Gallon,
horsepower: car.Horsepower
}))
.filter((car:any) => car.mpg != null && car.horsepower != null);
return cleaned;
}
const run = async () => {
const data = await getData();
const values = data.map((d:any) => ({
x: d.horsepower,
y: d.mpg,
}));
tfvis.render.scatterplot(
{name: 'Horsepower v MPG'},
{values},
{
xLabel: 'Horsepower',
yLabel: 'MPG',
height: 300
}
);
const model = createModel();
tfvis.show.modelSummary({name: 'Model Summary'}, model);
const tensorData = convertToTensor(data);
const {inputs, labels} = tensorData;
// Train the model
await trainModel(model, inputs, labels);
console.log('Done Training');
testModel(model, data, tensorData);
}
run();
});
return <div className="App"></div>;
}
export default App;
解决方案
每次刷新的预测值都不同,因为每次刷新都有新的训练。模型权重用随机值初始化。在训练期间,权重可以收敛到最佳值或发散。这取决于许多参数。实际上,即使是最好的模型也不会总是在固定数量的训练时期收敛。
为了始终具有相同的值,可以使用固定数据设置权重的初始值。但同样如何找到能够产生最佳预测的数据呢?找到这些权重并不总是那么容易。初始化层权重的一种简单方法是使用层权重kernelInitializer
。
model.add(tf.layers.dense({inputShape: [1], units: 1, useBias: true, kernelInitializer : 'zeros'}));
这个新层的权重将初始化为 0。也可以使用ones
。其他初始化器是可能的。使用固定权重,预测不会改变。但实际上,由于上述原因,权重很少被初始化,除非人们确定哪些可能的值会导致良好的准确性。另一方面,跟踪模型的准确性并在模型具有令人满意的准确性时创建一个检查点。
推荐阅读
- angularjs - 更改颜色按钮并设置文本Angular js
- java - 在 CalendarView 中更改“月份”文本颜色
- javascript - 如何从 devextreme-reactive 反应网格中的列选择器中删除列?
- mysql - 使用 SQL 处理“非常大”库存的最佳方法是什么?
- authentication - 使用 Elastic Search X-Pack 进行最终用户身份验证
- java - 输入带有点的字符或数字时发送垃圾邮件
- c - 我需要分别接收两个数据包 - linux将它们合并为一个并发送给应用程序
- windows - 找不到方法 getWindowMaximumSize 的实现(window_size 颤动桌面)
- python - 有没有办法在 python 中创建 base13 编号系统?
- ssh - 使用 .ssh/config 与 Nautilus 建立 ssh 隧道