我在编写一个脚本,有时会出现张量泄漏的情况。这可能发生在多种情况下,例如当我在训练神经网络时,如果训练过程中崩溃,训练会被中断,无法正确释放张量。这会导致内存泄漏,我试图通过释放未使用的张量来清理这些泄漏。
示例
在下面的代码片段中,我在训练两个(非常简单的)模型。第一次运行会正常进行,不会导致张量泄漏(训练前张量数量 = 训练后张量数量)。第二次,我使用了一个无效的reshape
层来强制在训练过程中崩溃。因此,会抛出一个错误,我猜测数据集中的张量不会被正确释放。这段代码只是为了展示张量可能如何泄漏的一个例子。
async function train(shouldCrash) { console.log(`Training, shouldCrash=${shouldCrash}`); const dataset = tf.data.zip({ // setup data xs: tf.data.array([[1],[1]]), ys: tf.data.array([1]), }).batch(1); const model = tf.sequential({ // setup model layers: [ tf.layers.dense({units: 1, inputShape: [1]}), tf.layers.reshape({targetShape: [(shouldCrash ? 2 : 1)]}), // use invalid shape when crashing ], }); model.compile({ optimizer: 'sgd', loss: 'meanSquaredError' }); console.log(' Tensors before:', tf.memory().numTensors); try { const history = await model.fitDataset(dataset, { epochs: 1 }); } catch (err) { console.log(` Error: ${err.message}`); } console.log(' Tensors after:', tf.memory().numTensors);}(async () => { await train(false); // normal training await train(true); // training with error})();
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]/dist/tf.min.js"></script>
问题
有tf.tidy
方法,在某些情况下可以帮助我释放未使用的张量,但它只能用于同步函数调用。因此,在调用await model.fitDataset(...)
时无法使用它。
有没有办法释放任何未使用的张量?或者,有没有办法在不重新加载页面情况下释放页面上所有现有的张量?
回答:
在异步代码中清理任何未使用张量的方法是,将创建它们的代码包装在startScope()
和endScope()
调用之间。
tf.engine().startScope()// do your thingtf.engine().endScope()