I have been watching several videos from the series above. They seems really crystal clear. Unfortunately, I could find (yet) the fix for my issue.
I’m working on a simplified data use case.
For each 15 rows of data, I have :
- a normalized float value
- a oneHot value [x, x, x]
- a oneHot label [x, x, x, x]
I’m really stuck on transforming my data into the correct shape for a training dataset or maybe the model itself is not correctly set!
I currently got the following error :
ValueError: Input 0 is incompatible with layer dense_Dense1: expected min_ndim=2, found ndim=1.
const tf = require("@tensorflow/tfjs-node");
let data = [
{ value: 95.1, categorical_value_as_string: "cat 1", label: "string label" },
{ value: 5.1, categorical_value_as_string: "cat 2", label: "string label" },
{ value: 0.0, categorical_value_as_string: "cat 3", label: "string label" },
{ value: 94.1, categorical_value_as_string: "cat 1", label: "string label" },
{ value: 100.0, categorical_value_as_string: "cat 2", label: "string label" },
{ value: 12.2, categorical_value_as_string: "cat 3", label: "string label" },
{ value: 21.5, categorical_value_as_string: "cat 3", label: "string label" },
{ value: 18.8, categorical_value_as_string: "cat 2", label: "string label" },
{ value: 82.6, categorical_value_as_string: "cat 1", label: "string label" },
{ value: 23.2, categorical_value_as_string: "cat 2", label: "string label" },
{ value: 46.2, categorical_value_as_string: "cat 3", label: "string label" },
{ value: 46.9, categorical_value_as_string: "cat 1", label: "string label" },
{ value: 71.5, categorical_value_as_string: "cat 1", label: "string label" },
{ value: 55.1, categorical_value_as_string: "cat 2", label: "string label" },
{ value: 38.2, categorical_value_as_string: "cat 3", label: "string label" }
];
let min = 0.0;
let max = 100.0;
let batchSize = 50;
let epochs = 100;
let splitIdx = 10; // take the 10 first for training
let features = ["value", "categorical_value_as_string"]; // because I need to be flexible on the features list
let categoricalFeats = ["cat 1", "cat 2", "cat 3"]; // 3 classes in that feature ; it will be oneHotEncoded
let labelsClasses = ["class 1", "class 2", "class 3", "class 4"]; // actual label for ML ; it will be oneHotEncoded
const buildModel = async function() {
return await new Promise((resolve) => {
const model = tf.sequential();
model.add(tf.layers.dense({
inputShape: [features.length], // 2
units: 1,
activation: "relu"
}));
model.add(tf.layers.dense({
units: labelsClasses.length, // 4
activation: "sigmoid"
}));
model.compile({
optimizer: tf.train.adam(0.001),
loss: "meanSquaredError",
metrics: ['accuracy']
});
console.debug("Model.weights:");
model.weights.forEach(w => {
console.debug(" ", w.name, w.shape);
/*
Model.weights:
dense_Dense1/kernel [ 2, 16 ]
dense_Dense1/bias [ 16 ]
dense_Dense2/kernel [ 16, 4 ]
dense_Dense2/bias [ 4 ]
*/
});
resolve(model);
});
};
const oneHotEncode = (classIndex, classes) => {
return tf.oneHot(classIndex, classes.length).dataSync();
};
const x = data.map((r, index) => {
return features.map((f) => {
if (f === "value") {
return parseFloat((r.value - min)/(max - min), 10); // normalize
} else if (f === "categorical_value_as_string") {
return oneHotEncode(categoricalFeats.indexOf(r.categorical_value_as_string), categoricalFeats);
}
});
});
const y = data.map((r, index) => {
return oneHotEncode(labelsClasses.indexOf(r.label), labelsClasses);
});
const featureTensor = tf.tensor(x);
const labelTensor = tf.tensor(y);
x.map((f, index) => {
console.log(`x ${index}`, f);
});
const ds = tf.data
.zip({ xs: tf.data.array(featureTensor), ys: tf.data.array(labelTensor) })
.shuffle(data.length);
buildModel().then((model) => {
console.log("MODEL BUILT");
model.fitDataset( (ds.take(splitIdx).batch(batchSize)), {epochs: epochs})
.then((trained) => {
console.log("TRAINED");
return trained;
});
});
Can you give me some hints to debug ?