Как добавить случайность в каждой итерации тензорного потока DataSet? - PullRequest
1 голос
/ 24 октября 2019

Я использую API оценщика. Я хочу обрабатывать каждый мини-пакет (или каждый элемент) динамически в каждой итерации через DataSet.

Например, я хотел бы добавлять случайный шум к каждому элементу в наборе данных каждый раз, когда он пакетируется и подается в model_fn.

dataset.map() кажется вызванным только один раз, и последующие проходы через dataset.repeat() являются статическими. Вот что я попробовал:

import tensorflow as tf
import numpy as np
import random 

dx = tf.data.Dataset.from_tensor_slices([10.0, 20.0, 30.0])
dx = dx.map(lambda x: x + random.uniform(0, 1)).repeat(2)
for next_element in dx:
    print(next_element.numpy())

Вывод

10.426203
20.426203
30.426203
10.426203
20.426203
30.426203

Один из способов сделать это - добавить случайность к необработанным данным, которые считываются input_fn, но затем данные выигрываютне меняются между разными эпохами.

Ответы [ 3 ]

1 голос
/ 24 октября 2019

Этот бит кода должен дать вам желаемый результат

import tensorflow as tf
import numpy as np
import random 

def add_noise(x):
    noise = tf.random.uniform(shape=(), minval=0, maxval=1)
    return x + noise

dx = tf.data.Dataset.from_tensor_slices([10.0, 20.0, 30.0])
dx = dx.map(add_noise).repeat(2)
for next_element in dx:
    print(next_element.numpy())
10.931375
20.01276
30.051556
10.825275
20.22412
30.7365
1 голос
/ 24 октября 2019

Существует некоторая проблема с пониманием функции map. Функция карты применяет логику внутри нее отдельно к каждому элементу, но набор данных создается только один раз. random.uniform(0, 1) генерирует случайное значение с плавающей точкой. Поэтому, когда вы используете random.uniform() внутри функции карты, набор данных создается с фиксированной числовой константой с плавающей точкой. Теперь каждый раз, когда это же числовое значение будет добавляться к каждому элементу внутри функции карты.

Чтобы преодолеть эту проблему, вы должны использовать tf.random.uniform(), который соединит тензор в наборе данных. Этот тензор будет оцениваться каждый раз, когда функция map применяется к каждому элементу, генерируя разные случайные значения, хотя набор данных создается только один раз.

Итак, ваш код должен быть:

import tensorflow as tf
import numpy as np
import random

dx = tf.data.Dataset.from_tensor_slices([10.0, 20.0, 30.0])
dx = dx.map(lambda x: x + tf.random.uniform([], 0, 1)).repeat(2)
for next_element in dx:
    print(next_element.numpy())
0 голосов
/ 24 октября 2019

Один из обходных путей, который я могу придумать, - сначала создать шум и выполнить повторный набор данных. Может быть, есть и другие лучшие решения.

import tensorflow as tf
import numpy as np
import random 

dx = tf.data.Dataset.from_tensor_slices(np.array([10.0, 20.0, 30.0]))
noise = tf.data.Dataset.from_tensor_slices(np.random.randn(6))
dx = dx.repeat(2)
new_dx = tf.data.Dataset.zip((dx, noise))
for next_element in new_dx:
    data = next_element[0]
    ns = next_element[1]
    input_ = data+ns
    print(input_.numpy())

# 10.969622987669728
# 19.77313649149436
# 30.09365081990082
# 9.950256200151752
# 19.36040356387037
# 29.6192768988015
...