gpt4 book ai didi

javascript - 使用 Tensorflow.js 和 tf.Tensor 处理大数据的最佳方式是什么?

转载 作者:搜寻专家 更新时间:2023-10-31 23:19:20 24 4
gpt4 key购买 nike

问题

我正在使用 tf.Tensortf.concat() 来处理大型训练数据,而且我发现连续使用 tf.concat() 会变慢。将大数据从文件加载到 tf.Tensor 的最佳方法是什么?

背景

我认为这是在 Javascript 中按数组处理数据的常见方式。要实现这一目标,请执行以下粗略步骤。

从文件加载数据到数组的步骤

  1. 从文件中读取行
  2. 将行解析为 Javascript 的对象
  3. 通过Array.push()将该对象添加到数组
  4. 读完一行后,我们可以用for循环使用那个数组。

所以我想我可以像上面那样使用tf.concat()

从文件加载数据到 tf.Tensor 的步骤

  1. 从文件中读取行
  2. 将行解析为 Javascript 的对象
  3. 将对象解析为 tf.Tensor
  4. 通过tf.concat()将张量添加到原始张量中
  5. 读完一行后,我们可以使用那个 tf.Tensor

一些代码

这里有一些代码可以测量 Array.push()tf.concat() 的速度

import * as tf from "@tensorflow/tfjs"

let t = tf.tensor1d([1])
let addT = tf.tensor1d([2])

console.time()
for (let idx = 0; idx < 50000; idx++) {
if (idx % 1000 == 0) {
console.timeEnd()
console.time()
console.log(idx)
}
t = tf.tidy(() => t.concat(addT))
}


let arr = []
let addA = 1
console.time()
for (let idx = 0; idx < 50000; idx++) {
if (idx % 1000 == 0) {
console.timeEnd()
console.time()
console.log(idx)
}
arr.push(addA)
}

测量

我们可以在 Array.push() 上看到稳定的过程,但它在 tf.concat()

上变慢

对于 tf.concat()

default: 0.150ms
0
default: 68.725ms
1000
default: 62.922ms
2000
default: 23.199ms
3000
default: 21.093ms
4000
default: 27.808ms
5000
default: 39.689ms
6000
default: 34.798ms
7000
default: 45.502ms
8000
default: 94.526ms
9000
default: 51.996ms
10000
default: 76.529ms
11000
default: 83.662ms
12000
default: 45.730ms
13000
default: 89.119ms
14000
default: 49.171ms
15000
default: 48.555ms
16000
default: 55.686ms
17000
default: 54.857ms
18000
default: 54.801ms
19000
default: 55.312ms
20000
default: 65.760ms

对于 Array.push()

default: 0.009ms
0
default: 0.388ms
1000
default: 0.340ms
2000
default: 0.333ms
3000
default: 0.317ms
4000
default: 0.330ms
5000
default: 0.289ms
6000
default: 0.299ms
7000
default: 0.291ms
8000
default: 0.320ms
9000
default: 0.284ms
10000
default: 0.343ms
11000
default: 0.327ms
12000
default: 0.317ms
13000
default: 0.329ms
14000
default: 0.307ms
15000
default: 0.218ms
16000
default: 0.193ms
17000
default: 0.234ms
18000
default: 1.943ms
19000
default: 0.164ms
20000
default: 0.148ms

最佳答案

虽然 tf.concatArray.push 函数看起来和行为相似,但有一个很大的区别:

  • tf.concat 从输入创建一个新张量
  • Array.push 将输入添加到第一个数组

例子

tf.concat

const a = tf.tensor1d([1, 2]);
const b = tf.tensor1d([3]);
const c = tf.concat([a, b]);

a.print(); // Result: Tensor [1, 2]
b.print(); // Result: Tensor [3]
c.print(); // Result: Tensor [1, 2, 3]

结果变量 c 是一个新的张量,而 ab 没有改变。

Array.push

const a = [1,2];
a.push(3);

console.log(a); // Result: [1,2,3]

这里直接修改变量a

对运行时的影响

对于运行时速度,这意味着 tf.concat 在添加输入之前将所有张量值复制到新张量。显然,需要复制的数组越大,花费的时间就越多。与此相反,Array.push 不会创建数组的副本,因此无论数组有多大,运行时都或多或少相同。

请注意,这是“设计使然”的,因为张量是不可变的,因此对现有张量的每次操作都会创建一个新的张量。引自 docs :

Tensors are immutable, so all operations always return new Tensors and never modify input Tensors.

因此,如果您需要从输入数据创建一个大张量,建议您先从您的文件中读取所有数据并将其与“普通”JavaScript 函数合并,然后再从中创建一个张量。

处理内存太大的数据

如果您的数据集太大以至于由于内存限制需要分块处理,您有两个选择:

  1. 使用trainOnBatch功能
  2. 使用数据集生成器

选项 1:trainOnBatch

trainOnBatch函数允许训练一批数据,而不是使用完整的数据集。因此,您可以在训练代码之前将代码分成合理的批处理,这样就不必一次将所有数据合并在一起。

选项 2:数据集生成器

另一个答案已经涵盖了基础知识。这将允许您使用 JavaScript generator function准备数据。我建议使用生成器语法而不是迭代器工厂(在另一个答案中使用),因为它是更现代的 JavaScript 语法。

示例(取自 docs ):

function* dataGenerator() {
const numElements = 10;
let index = 0;
while (index < numElements) {
const x = index;
index++;
yield x;
}
}

const ds = tf.data.generator(dataGenerator);

然后您可以使用 fitDataset训练模型的函数。

关于javascript - 使用 Tensorflow.js 和 tf.Tensor 处理大数据的最佳方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55929960/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com