Можете ли вы эффективно реплицировать tf.random_crop в TensorFlow JS?

#javascript #tensorflow #tensorflow.js

#javascript #tensorflow #tensorflow.js

Вопрос:

Случайная обрезка не реализована в TensorFlow JS, но возможно ли ее реплицировать? Моя идея состояла в том, чтобы использовать Tensor.slice() с тензорами, сгенерированными из tf.randomUniform в качестве параметров, но он принимает только «числа». Итак, мне кажется, что для того, чтобы заставить работать случайную обрезку, мне пришлось бы восстанавливать эту часть графа вычислений на каждой итерации с помощью вновь сгенерированных случайных чисел (например, из Math.random()) в качестве параметров среза. Или есть другой способ?

Вот мой код. Я понимаю, что внутренняя функция создаст случайное смещение rx и ry только один раз, и мне понадобится операция tensorflow для непрерывного получения случайных значений на каждой итерации.

 export function jitter (d) {
  const inner = (tImage) => {
    const tShp = tImage.shape;
    const cropShape = [
      tShp[0], tShp[1]-d,
      tShp[2]-d, tShp[3]];
    const rx = Math.floor(Math.random() * d   0.5);
    const ry = Math.floor(Math.random() * d   0.5);
    const crop = tImage.slice(
      [0, rx, ry, 0],
      [cropShape[0], cropShape[1], cropShape[2], cropShape[3]]);
  }

  return inner;
}
  

Ссылка на документ для Tensor.slice()

Комментарии:

1. Не могли бы вы добавить свой код, чтобы его было легче увидеть из того, что вы сделали?

2. Добавлен мой код. Надеюсь, теперь это понятно.

3. tensorflow.js использует нетерпеливый стиль; график не вычисляется каждый раз

4. Хорошо, спасибо, тогда я просто использую Math.random()

5. смотрите мой ответ о том, как нарезать несколько раз одновременно

Ответ №1:

срез позволит срезать или обрезать часть входных данных. С другой стороны, использование gatherND позволит многократно нарезать фрагменты, если вы хотите избежать повторного использования фрагмента. Но должны быть указаны индексы в месте среза. Ниже функция g генерирует индексы из случайных координат и пытается вычислить индексы всех z * z элементов, которые будут включены в обрезку.

 const g = (r, s, z, n) => {
  const arr = []
  for (let i = 0; i < n; i  ) {
    const c = Math.floor(Math.random() * r)
    const d = Math.floor(Math.random() * s)
    const p = Array.from({length: z}, (_, k) => k   c)
    const q = Array.from({length: z}, (_, k) => k   d)
    arr.push(p.map( e => q.map(f => ([e, f]))).flat())
  }
  return arr
}

const n = 3
const crop = 4
const hsize = 2 // maximum of the height where to start cropping
const wsize = 2 // maximum of the width where to start cropping
// hsize = length_of_height_dimension - crop_size_over_height
// wsize = length_of_width_dimension - crop_size_over_width
const indices = tf.tensor( g(hsize, wsize, crop, n)).toInt()
const input = tf.tensor(Array.from({length: 64 * 3}, (_, k) => k  1), [8, 8, 3]);
tf.gatherND(input, indices).reshape([n, crop, crop, 3]).print()  
 <html>
  <head>
    <!-- Load TensorFlow.js -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest"> </script>
  </head>

  <body>
  </body>
</html>