问题
I'd like to change the weights of a supervised model but I get the same exact result after changing the weights. What am I doing wrong?
const model = tf.sequential();
model.add(tf.layers.dense({...}));
model.add(tf.layers.dense({...}));
model.add(tf.layers.dense({...}));
model.compile({...});
model.fit({});
const result1 = model.predict(tf.tensor2d(...)).dataSync();
const newWeights = [];
model.layers.map((layer, i) => {
newWeights[i] = []
const weights = layer.getWeights();
newWeights[i][0] = weights[0].arraySync()
newWeights[i][1] = weights[1].arraySync()
newWeights[i][0].map(tensor => tensor.map(x => {
if (random(1) < 0.5) {
return x + offset();
}
return x;
})
layer.setWeights([tf.tensor2d(newWeights[i][0], [newWeights[i][0].length, newWeights[i][0][0].length]), tf.tensor(newWeights[i][1])])
})
const result2 = model.predict(tf.tensor2d(...)).dataSync();
Code snippets:
const random = (max) => {
return floor(Math.random() * Math.floor(max), 2);
}
const floor = (num, toDecimal) => {
let dec = Math.pow(10, toDecimal);
return Number(Math.floor(num * dec) / dec);
}
const offset = () => {
randomGaussian() * 0.5
}
let previous = false;
let y2 = 0;
const randomGaussian = (mean, sd) => {
let y1, x1, x2, w;
if (previous) {
y1 = y2;
previous = false;
} else {
do {
x1 = random(2) - 1;
x2 = random(2) - 1;
w = x1 * x1 + x2 * x2;
} while (w >= 1);
w = Math.sqrt(-2 * Math.log(w) / w);
y1 = x1 * w;
y2 = x2 * w;
previous = true;
}
let m = mean || 0;
let s = sd || 1;
return y1 * s + m;
};
result1 === result2 but why?
回答1:
Most likely that the new weights are identical to that of the first model.
Example: Simple example to change weights of a model
(async() => {
const model = tf.sequential({
layers: [tf.layers.dense({units: 1, inputShape: [10]})]
});
model.compile({optimizer: 'sgd', loss: 'meanSquaredError'});
for (let i = 1; i < 5 ; ++i) {
const h = await model.fit(tf.ones([8, 10]), tf.ones([8, 1]), {
batchSize: 4,
epochs: 3
});
console.log("Loss after Epoch " + i + " : " + h.history.loss[0]);
}
const p = await model.predict(tf.zeros([1, 10]))
p.print()
const layers = model.layers
layers[0].setWeights([tf.zeros([10, 1]), tf.zeros([1])])
const q = await model.predict(tf.zeros([1, 10]))
q.print()
})()
<html>
<head>
<!-- Load TensorFlow.js -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest"> </script>
</head>
<body>
</body>
</html>
Issue of the code
The newWeights
created is not assigned to newWeights
. map
is not an in-place operator. The array returned by map
should be assigned back to newWeights
.
newWeights[i][0] = newWeights[i][0].map(tensor => tensor.map(x => {
if (random(1) < 0.5) {
return x + offset();
}
return x;
})
来源:https://stackoverflow.com/questions/57917450/how-to-get-set-weights-for-a-supervised-model-in-tensorflow-js