TensorFlow.js: 训练时保存不同的模型实例
TensorFlow.js: Saving different model instances during training
我在 NODE 上运行 TensorFlow.JS,我希望能够在训练过程中的某个时刻保存模型。
我试图将实际模型复制到全局变量,但 JavaScript 对象是通过引用复制的,最后全局变量与上一个训练时期具有相同的模型。
然后我使用了许多不同的 JavaScript 方法来进行深度克隆(包括 lodash 深度克隆),但是我在复制的模型上遇到错误,例如最终丢失的函数(例如 model.evaluate) .
我想知道我可以保存某个检查点的唯一方法是直接使用 model.save() 还是有任何其他方法可以将模型对象复制(按值而不是引用)到全局或一个 class 属性.
在此致谢!
** 更新**
目前对我有用的最佳解决方案是创建模型的副本:
const copyModel = (model) => {
const copy = tf.sequential();
model.layers.forEach(layer => {
copy.add(layer);
});
copy.compile({ loss: model.loss, optimizer: model.optimizer });
return copy;
}
- 考虑到您可能需要将一些其他设置从原始模型复制到新模型(副本)。
一个 tf.Model
对象包含权重值,通常存在于 GPU 上
(作为 WebGL 纹理)并且不容易复制。所以这不是一个好主意
克隆一个 tf.Model
对象。您应该将其序列化并将其保存在某个地方。
有两个选项:
- 如果您在 Node.js,您应该有相对充足的存储空间 space。只是
使用
Model.save()
到 "snapshot" 模型到磁盘上,可以加载回来
稍后。
- 如果您希望避免通过文件系统,您可以在内存中进行序列化和反序列化。使用方法
tf.io.withSaveHandler
和 tf.io.fromMemory()
。请参阅以下示例:
const tf = require('@tensorflow/tfjs');
require('@tensorflow/tfjs-node');
(async function main() {
const model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [3], useBias: false}));
model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});
const xs = tf.randomUniform([4, 3]);
const ys = tf.randomUniform([4, 1]);
const artifactsArray = [];
// First save, before training.
await model.save(tf.io.withSaveHandler(artifacts => {
artifactsArray.push(artifacts);
}));
// First load.
const model2 = await tf.loadModel(tf.io.fromMemory(
artifactsArray[0].modelTopology, artifactsArray[0].weightSpecs,
artifactsArray[0].weightData));
// Do some training.
await model.fit(xs, ys, {epochs: 5});
// Second save, before training.
await model.save(tf.io.withSaveHandler(artifacts => {
artifactsArray.push(artifacts);
}));
// Second load.
const model3 = await tf.loadModel(tf.io.fromMemory(
artifactsArray[1].modelTopology, artifactsArray[1].weightSpecs,
artifactsArray[1].weightData));
// The two loaded models should have different weight values.
model2.getWeights()[0].print();
model3.getWeights()[0].print();
})();
我在 NODE 上运行 TensorFlow.JS,我希望能够在训练过程中的某个时刻保存模型。
我试图将实际模型复制到全局变量,但 JavaScript 对象是通过引用复制的,最后全局变量与上一个训练时期具有相同的模型。
然后我使用了许多不同的 JavaScript 方法来进行深度克隆(包括 lodash 深度克隆),但是我在复制的模型上遇到错误,例如最终丢失的函数(例如 model.evaluate) .
我想知道我可以保存某个检查点的唯一方法是直接使用 model.save() 还是有任何其他方法可以将模型对象复制(按值而不是引用)到全局或一个 class 属性.
在此致谢!
** 更新**
目前对我有用的最佳解决方案是创建模型的副本:
const copyModel = (model) => {
const copy = tf.sequential();
model.layers.forEach(layer => {
copy.add(layer);
});
copy.compile({ loss: model.loss, optimizer: model.optimizer });
return copy;
}
- 考虑到您可能需要将一些其他设置从原始模型复制到新模型(副本)。
一个 tf.Model
对象包含权重值,通常存在于 GPU 上
(作为 WebGL 纹理)并且不容易复制。所以这不是一个好主意
克隆一个 tf.Model
对象。您应该将其序列化并将其保存在某个地方。
有两个选项:
- 如果您在 Node.js,您应该有相对充足的存储空间 space。只是
使用
Model.save()
到 "snapshot" 模型到磁盘上,可以加载回来 稍后。 - 如果您希望避免通过文件系统,您可以在内存中进行序列化和反序列化。使用方法
tf.io.withSaveHandler
和tf.io.fromMemory()
。请参阅以下示例:
const tf = require('@tensorflow/tfjs');
require('@tensorflow/tfjs-node');
(async function main() {
const model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [3], useBias: false}));
model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});
const xs = tf.randomUniform([4, 3]);
const ys = tf.randomUniform([4, 1]);
const artifactsArray = [];
// First save, before training.
await model.save(tf.io.withSaveHandler(artifacts => {
artifactsArray.push(artifacts);
}));
// First load.
const model2 = await tf.loadModel(tf.io.fromMemory(
artifactsArray[0].modelTopology, artifactsArray[0].weightSpecs,
artifactsArray[0].weightData));
// Do some training.
await model.fit(xs, ys, {epochs: 5});
// Second save, before training.
await model.save(tf.io.withSaveHandler(artifacts => {
artifactsArray.push(artifacts);
}));
// Second load.
const model3 = await tf.loadModel(tf.io.fromMemory(
artifactsArray[1].modelTopology, artifactsArray[1].weightSpecs,
artifactsArray[1].weightData));
// The two loaded models should have different weight values.
model2.getWeights()[0].print();
model3.getWeights()[0].print();
})();