Как случайным образом выбрать и замаскировать часть Tensor в Tensorflow (python) - PullRequest
0 голосов
/ 08 апреля 2020

Я тренирую шумоподавляющий автоэнкодер в Tensorflow 2, одна часть времени работы тратится на ЦП, выполняющего маскировку части входных данных, случайным образом выбирая индексы, которые должны быть замаскированы, затем устанавливая их значения на ноль. Это моя маскирующая функция, эта маскировка повторяется в начале каждой эпохи при различных значениях v:

import numpy as np

def masking_noise(X, v):

    X_noise = X.copy()

    n_samples = X.shape[0]
    n_features = X.shape[1]
    v = int(np.round(n_features*v))
    for i in range(n_samples):
        mask = np.random.choice(n_features, v, replace=False)

        for m in mask:
            X_noise[i][m] = np.repeat(0.,X.shape[2])

    return X_noise

Вот пример игрушки:

a = np.array([[[1., 0.],
        [1., 0.],
        [1., 0.],
        [1., 0.],
        [0., 1.]],

       [[1., 0.],
        [1., 0.],
        [1., 0.],
        [1., 1.],
        [0., 1.]],

       [[1., 0.],
        [1., 0.],
        [1., 0.],
        [1., 0.],
        [1., 1.]]])

masking_noise(a, 0.40)

Вывод:

array([[[1., 0.],
        [0., 0.],
        [1., 0.],
        [1., 0.],
        [0., 0.]],

       [[0., 0.],
        [0., 0.],
        [1., 0.],
        [1., 1.],
        [0., 1.]],

       [[1., 0.],
        [1., 0.],
        [1., 0.],
        [0., 0.],
        [0., 0.]]])

Мой вопрос: как я могу сделать ту же операцию маскировки в Tensorflow?

1 Ответ

0 голосов
/ 09 апреля 2020

Думаю, я наконец-то понял это, было легко отладить эту проблему с Tensorflow 2, поэтому я смог решить эту проблему, когда перешел с TF1 на TF2:

def mask_data(y_true, mask_ratio, verbose=0):

    nf = tf.cast(tf.shape(y_true)[1], tf.float32)
    mask_portion = tf.math.round( tf.math.multiply(nf,(1-mask_ratio)) )
    mask_portion = tf.cast(mask_portion, tf.int32)

    z = -tf.math.log(-tf.math.log(tf.random.uniform(tf.shape(y_true)[0:-1],0,1))) 
    _, indices = tf.nn.top_k(z, mask_portion)
    one_hots = tf.one_hot(indices, tf.shape(y_true)[1])
    mask = tf.reduce_max(one_hots, axis=1)
    mask = tf.expand_dims(mask,axis=-1)
    mask_tiles = tf.tile(mask,[1,1,tf.shape(y_true)[-1]]) 
    masked = tf.multiply(mask_tiles,toy_example)
    if(verbose>0):
        print("\nRandomly selected indices:", indices)
        print("\n2D mask (per variant)", mask)
        print("\n3D mask (per allele)", mask_tiles)
        print("\nmasked results", masked)

    return masked

Тогда я могу запустить это так:

toy_example = np.array([[[1., 0.],
    [1., 0.],
    [1., 0.],
    [1., 0.],
    [0., 1.]],

   [[1., 0.],
    [1., 0.],
    [1., 0.],
    [1., 1.],
    [0., 1.]],

   [[1., 0.],
    [1., 0.],
    [1., 0.],
    [1., 0.],
    [1., 1.]]])

mask_ratio = 0.40
result = mask_data(toy_example, mask_ratio, verbose=0)
print(result)

Результат будет выглядеть так:

tf.Tensor(
[[[1. 0.]
  [1. 0.]
  [0. 0.]
  [1. 0.]
  [0. 0.]]

 [[1. 0.]
  [0. 0.]
  [0. 0.]
  [1. 1.]
  [0. 1.]]

 [[0. 0.]
  [0. 0.]
  [1. 0.]
  [1. 0.]
  [1. 1.]]], shape=(3, 5, 2), dtype=float32)
...