Лаборатория кода «Создание прогнозов из 2D-данных» дает случайные результаты при каждом обновлении - PullRequest
2 голосов
/ 02 мая 2020

Я следил за этой кодовой лабораторией , но результат, который я получаю при тестировании обученной модели, выглядит неверно, кодовая лаборатория показывает эту диаграмму

enter image description here

но когда я запускаю приведенный ниже код, взятый непосредственно из лаборатории кода, моя диаграмма выглядит следующим образом ..

enter image description here

если я перефразирую sh снова, я получаю enter image description here

и еще раз enter image description here

Почему результаты так сильно различаются в каждая страница refre sh?

Я пытался отложить тестирование, но без лучших результатов

      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;

1 Ответ

2 голосов
/ 02 мая 2020

Значения прогноза отличаются при каждом рефре sh, потому что при каждом рефре sh происходит новое обучение. Веса модели инициализируются случайными значениями. Во время тренировки веса могут либо сходиться к оптимальным значениям, либо расходиться. Это зависит от многих параметров. На самом деле, даже лучшая модель не всегда будет сходиться при фиксированном количестве обучающих эпох.

Чтобы всегда иметь одинаковое значение, начальные значения весов могут быть установлены с фиксированными данными. Но опять же, как найти эти данные, которые приведут к лучшему прогнозу? Это не всегда легко найти эти веса. Простой способ инициализации весов слоя состоит в использовании kernelInitializer слоя.

model.add(tf.layers.dense({inputShape: [1], units: 1, useBias: true, kernelInitializer : 'zeros'}));

Этот новый слой будет иметь веса, инициализированные с 0. Можно также использовать ones , Возможны другие инициализаторы. При фиксированных весах прогноз не изменится. Но на практике веса редко инициализируются из-за того, что упомянуто выше, если не знать наверняка, какие возможные значения приведут к хорошей точности. С другой стороны, необходимо отслеживать точность модели и создавать контрольную точку, если модель имеет удовлетворительную точность.

...