Błąd w ML5, Cannot convert undefined or null to object.

0

Witam,
z góry przepraszam za tytuł, ale dopiero zaczynam z tą biblioteką i jeszcze dobrze tych błędów nie rozumiem. Problem jest taki, że wyskakuje mi błąd
TypeError: Cannot convert undefined or null to object. (błąd rejestrowany jest w gotResults w console.error, a odnosi się do index.js:1079)
Zrobiłem sobie jakiś przykładowy projekt, który po podaniu liczby parzystej ma w wyniku zwrócić następną liczbę nieparzystą. Wiem, że prawdopodobnie w moim kodzie jest trochę błędów, więc byłbym wdzięczny za ich wytknięcie. Dodam jeszcze, że po usunięciu ifa w gotResults, zwracana wartość to undefined.

let classifier;

let data = [
    {number: 2, result: 3},
    {number: 4, result: 5},
    {number: 8, result: 9},
    {number: 12, result: 13},
    {number: 16, result: 17},
    {number: 32188, result: 32189},
    {number: 2458, result: 2459},
    {number: 5554, result: 5555},
    {number: 2886, result: 2887},
    {number: 198, result: 199},
    {number: 152, result: 153},
    {number: 6486, result: 6487},
    {number: 22, result: 23},
    {number: 3690, result: 3691},
];

const options = {
    inputs: ['number'],
    outputs: ['result'],
    task: "regression",
    debug: true
};

let nn = ml5.neuralNetwork(options);
data.forEach(item => {
    const input = {
        number: item.number
    };
    const output = {
        result: item.result
    };
    nn.addData(input, output);
});

nn.normalizeData();
trainModel();

function trainModel(){
    const trainingOptions = {
        epochs: 40,
        bathSize: 12
    };
    nn.train(trainingOptions, finishedTraining);
}

function finishedTraining(){
    let input = {
        number: 24
    };
    nn.classify(input, gotResult);
}

function gotResult(err, result){
    if(err){
        console.error(err);
        return;
    }
    console.log(result)
}

EDIT
Sugerując się tym wpisem na StackOverflow, zamieniłem results na stringi. I wszystko "działa". Problem jest jednak taki, że zamiast dostać następną liczbę nieparzystą, wyświetla się prawdopodobieństwo dla każdej liczby z data.result. Co robię źle?

[
    {
        "3": 0.07814767956733704,
        "label": "3",
        "confidence": 0.07814767956733704
    },
    {
        "199": 0.07750645279884338,
        "label": "199",
        "confidence": 0.07750645279884338
    },
    {
        "2459": 0.07698856294155121,
        "label": "2459",
        "confidence": 0.07698856294155121
    },
    {
        "5555": 0.07664407789707184,
        "label": "5555",
        "confidence": 0.07664407789707184
    },
    {
        "17": 0.0766131654381752,
        "label": "17",
        "confidence": 0.0766131654381752
    },
    {
        "13": 0.07611173391342163,
        "label": "13",
        "confidence": 0.07611173391342163
    },
    {
        "2887": 0.07566121965646744,
        "label": "2887",
        "confidence": 0.07566121965646744
    },
    {
        "153": 0.07556954026222229,
        "label": "153",
        "confidence": 0.07556954026222229
    },
    {
        "5": 0.07550838589668274,
        "label": "5",
        "confidence": 0.07550838589668274
    },
    {
        "23": 0.07540042698383331,
        "label": "23",
        "confidence": 0.07540042698383331
    },
    {
        "3691": 0.0745004266500473,
        "label": "3691",
        "confidence": 0.0745004266500473
    },
    {
        "9": 0.07380974292755127,
        "label": "9",
        "confidence": 0.07380974292755127
    },
    {
        "6487": 0.04403751716017723,
        "label": "6487",
        "confidence": 0.04403751716017723
    },
    {
        "32189": 0.0435011200606823,
        "label": "32189",
        "confidence": 0.0435011200606823
    }
]
2

To cały kod?
Nie rozumiem, w którym miejscu dokładnie ci się to wywala.

a odnosi się do index.js:1079)

A co tam jest dokładnie? Ta linijka 1079 znajduje się w zewnętrznej bibliotece? Jeśli tak, to jaki tam jest kod dokładnie w środku biblioteki, który powoduje błąd?

0

@LukeJL: funkcja z biblioteki

async classifyInternal(_input) {
  const { meta } = this.neuralNetworkData;
  const headers = Object.keys(meta.inputs);

  let inputData;

  if (this.options.task === 'imageClassification') {
    // get the inputData for classification
    // if it is a image type format it and
    // flatten it
    inputData = this.searchAndFormat(_input);
    if (Array.isArray(inputData)) {
      inputData = inputData.flat();
    } else {
      inputData = inputData[headers[0]];
    }

    if (meta.isNormalized) {
      // TODO: check to make sure this property is not static!!!!
      const { min, max } = meta.inputs[headers[0]];
      inputData = this.neuralNetworkData.normalizeArray(Array.from(inputData), { min, max });
    } else {
      inputData = Array.from(inputData);
    }

    inputData = tf.tensor([inputData], [1, ...meta.inputUnits]);
  } else {
    inputData = this.formatInputsForPredictionAll(_input, meta, headers);
  }

  const unformattedResults = await this.neuralNetwork.classify(inputData);
  inputData.dispose();

  if (meta !== null) {
    const label = Object.keys(meta.outputs)[0];
    const vals = Object.entries(meta.outputs[label].legend);

    const formattedResults = unformattedResults.map(unformattedResult => {
      return vals
        .map((item, idx) => {
          return {
            [item[0]]: unformattedResult[idx],
            label: item[0],
            confidence: unformattedResult[idx],
          };
        })
        .sort((a, b) => b.confidence - a.confidence);
    });

    // return single array if the length is less than 2,
    // otherwise return array of arrays
    if (formattedResults.length < 2) {
      return formattedResults[0];
    }
    return formattedResults;
  }

  return unformattedResults;
}

linijka 36

const vals = Object.entries(meta.outputs[label].legend);
1

Możesz sprawdzić, co dokładnie jest undefined. Np.

debugger;
const vals = Object.entries(meta.outputs[label].legend);

i użyć step debuggera w dev toolsach w przeglądarce, żeby obczaić, co dokładnie jest undefined albo null.
Albo zmodyfikować bezpośrednio plik tej biblioteki wrzucając jakiś console.log.

0

@LukeJL: Nie mam dostępu do tego pliku, jednak po wstrzymaniu skryptu w miejscu błędu dostaję dane jak na zdjęciu poniżej:Bez tytułu.png

0

@LukeJL: Chyba wiem. Po sprawdzeniu jak wygląda obiekt meta (screen "Budowa"), widzę, że nie istniene "legend". "label" ma wartość "result", po czym odwoływane jest do legend klucza, który nie istnieje.Budowa.pngkod.png

1

Problem rozwiązany!
Bawiąc się w detektywa krok po kroku prześledziłem możliwe opcje i znalazłem. Do spełnienia mojego celu i typu danych powinienem używać predit(), a nie classify().

1 użytkowników online, w tym zalogowanych: 0, gości: 1