大多数TensorFlow JS示例在浏览器中使用预训练模型进行预测。
我在这里尝试在浏览器中创建自己的数据并用它来训练模型。
最终,我觉得我已经接近于创建一个可以用于model.fit()训练模型的数据集了。
我有两个数组,一个包含图像,另一个包含标签。
let images = []let labels = []
我使用一种方法从画布上捕获图像并将其推送到图像数组中。
function getImage() { return tf.tidy(() => { const image = tf.browser.fromPixels($('#mycanvas')[0]); const batchedImage = image.expandDims(0); const norm = batchedImage.toFloat().div(tf.scalar(255)).sub(tf.scalar(1)); return norm; }); }
所以每当我按下任何箭头键时,我都会将一个图像和一个标签推送到数组中。
let collectData = (label) =>{ tf.tidy(() => { const img = getImage(); img.print() // 检查它是否是一个张量 //imges.concat(img) images.push(img) labels.push(label) // 标签是0,1,2 }) }
创建包含训练数据集的数组后,我将这些数据传递给model.fit()方法以开始训练。
let fitModel = async () => { let imageSet = tf.stack(images); let labelSet = tf.oneHot(tf.tensor1d(lables, 'int32'), 3); if (currentModel == null) { currentModel = createModel(); currentModel.summary(); } await currentModel.fit(imageSet, labelSet, { batchSize: 4, epochs: 20, shuffle: true, validationSplit: 0.1, callbacks: { onTrainBegin: () => console.log("训练开始"), onTrainEnd: () => console.log("训练结束"), onBatchEnd: async (num, log) => { await tf.nextFrame(); console.log(log) } } }) }
在这里,tf.stack(images); 抛出错误,显示 – Tensor has disposed。我不明白为什么会这样发生。从技术上讲,这应该像官方文档中所说的那样工作。
const a = tf.tensor1d([1, 2]);const b = tf.tensor1d([3, 4]);const c = tf.tensor1d([5, 6]);let p = []p.push(a)p.push(b)p.push(c)console.log(p)tf.stack(p).print();
所以我尝试了另一件事 – tf.stack(tf.tensor(images)),我得到的错误是Tensor has disposed。
我还尝试了另一件事 – tf.concat(),这也没用。有人知道如何像这样创建可训练的数据集吗?
我的第一个隐藏层有conv2d,输入形状为(150,300,3),输出层有3个单元。
任何帮助将不胜感激。请详细解释您的回答,以便更好地理解。
回答:
张量被释放是因为你在使用它们之前调用了tf.tidy
。要使用张量img
并清理所有中间张量,必须从tf.tidy
的回调中明确返回它。
const img = tf.tidy(() => { const im = getImage(); return im; // 由于im被返回,它不会被释放; // 但所有未使用的中间张量将被清理 })images.push(img)labels.push(label) // 标签是0,1,2