2015-12-18 9 views
9

Üç tensörleri, tensorflow içinde A, B and C, A ve BC şekli (m, n, 1) bir ikili tensör olduğunu, şekil (m, n, r) arasında her ikisi de var.Bir tensörün tensorflow'da başka bir şekle uyması için nasıl açıkça yayınlanır?

I C değerine göre A veya B ya da elemanları seçmek istiyorum. bariz bir araç anlambilim yayın yok ancak, tf.select, bu yüzden ilk açıkça Bu Bunun nasıl benim ilk denemem olacak A ve B

aynı şekle C yayın gerekir, ancak o değil Bir tensörü (tf.shape(A)[2]) şekil listesine karıştırmama benzemiyorum.

import tensorflow as tf 
A = tf.random_normal([20, 100, 10]) 
B = tf.random_normal([20, 100, 10]) 
C = tf.random_normal([20, 100, 1]) 
C = tf.greater_equal(C, tf.zeros_like(C)) 

C = tf.tile(C, [1,1,tf.shape(A)[2]]) 
D = tf.select(C, A, B) 

Doğru yaklaşım nedir?

+2

Bir kesmek: 'kirli kesmek sa 'C = Genişletici * C' – wxs

cevap

9

DÜZENLEME: 0.12rc0'den beri TensorFlow'un tüm sürümlerinde, söz konusu kod doğrudan çalışır. TensorFlow, tensörleri ve Python sayılarını otomatik olarak bir tensör argümanına yerleştirir. Aşağıdaki çözüm, tf.pack() kullanarak yalnızca 0.12rc0'den önceki sürümlerde gereklidir. tf.pack() TensorFlow 1.0 tf.stack() yeniden adlandırıldı unutmayın.


Çözümünüz çalışmaya çok yakın. Çizgiyi değiştirmelisiniz: ile ...

C = tf.tile(C, [1,1,tf.shape(C)[2]]) 

aşağıdadır:

C = tf.tile(C, tf.pack([1, 1, tf.shape(A)[2]])) 

(konuyla nedeni TensorFlow örtülü bir içine tensörlerle ve Python değişmezleri listesini dönüştürmez olmasıdır her bir eleman, bir skaler olduğu için, sonuç için bir vektör olacaktır. tensörü. tf.pack() tensörlerinin listesini alır, bu yüzden bir tensör için girişine (1, 1 ve tf.shape(C)[2]) elemanların her dönüştürür.)

+1

sana fazladan' [ 've ben * tf oturumu çalıştırmak * zaman bir') ', ama sonra biraz şifreli hata alıyorum eksik olduğunu düşünüyorum: işletilmesi Select_13 için Girişler:' InvalidArgumentError Select türü aynı boyuta ve şekle sahip olmalıdır. Giriş 0: dim {boyutu: 20} loş {boyutu: 100} loş {boyutu: 1} = giriş 1: loş {boyutu: 20} loş {boyutu: 100} loş {boyutu: 10} ' – wxs

+0

İyi bir nokta ve Cevabı güncelledim - ayrıca, tf.shape() 'nin argümanı' A '(veya' B ') olmalıydı. Bu benim için çalışıyor - Ne hata görüyorsun? – mrry

+0

Evet, şimdi düzeltildi :) yanlış parametreyi 'tf.shape() 'olarak görmedi. Teşekkürler! – wxs

2

Burada Daha sonra, ` ` Genişletici = tf.ones_like (B): Ben * çarpma * yayın semantiğini kullanabilir ve böylece olanlar tarafından tensör çarpın: çalışır

import tensorflow as tf 

def broadcast(tensor, shape): 
    return tensor + tf.zeros(shape, dtype=tensor.dtype) 

A = tf.random_normal([20, 100, 10]) 
B = tf.random_normal([20, 100, 10]) 
C = tf.random_normal([20, 100, 1]) 

C = broadcast(C, A.shape) 
D = tf.select(C, A, B) 
0
import tensorflow as tf 

def broadcast(tensor, shape): 
    """Broadcasts ``x`` to have shape ``shape``. 
                    | 
    Uses ``tf.Assert`` statements to ensure that the broadcast is 
    valid. 

    First calculates the number of missing dimensions in 
    ``tf.shape(x)`` and left-pads the shape of ``x`` with that many 
    ones. Then identifies the dimensions of ``x`` that require 
    tiling and tiles those dimensions appropriately. 

    Args: 
     x (tf.Tensor): The tensor to broadcast. 
     shape (Union[tf.TensorShape, tf.Tensor, Sequence[int]]): 
      The shape to broadcast to. 

    Returns: 
     tf.Tensor: ``x``, reshaped and tiled to have shape ``shape``. 

    """ 
    with tf.name_scope('broadcast') as scope: 
     shape_x = tf.shape(x) 
     rank_x = tf.shape(shape0)[0] 
     shape_t = tf.convert_to_tensor(shape, preferred_dtype=tf.int32) 
     rank_t = tf.shape(shape1)[0] 

     with tf.control_dependencies([tf.Assert(
      rank_t >= rank_x, 
      ['len(shape) must be >= tf.rank(x)', shape_x, shape_t], 
      summarize=255 
     )]): 
      missing_dims = tf.ones(tf.stack([rank_t - rank_x], 0), tf.int32) 

     shape_x_ = tf.concat([missing_dims, shape_x], 0) 
     should_tile = tf.equal(shape_x_, 1) 

     with tf.control_dependencies([tf.Assert(
      tf.reduce_all(tf.logical_or(tf.equal(shape_x_, shape_t), should_tile), 
      ['cannot broadcast shapes', shape_x, shape_t], 
      summarize=255 
     )]): 
      multiples = tf.where(should_tile, shape_t, tf.ones_like(shape_t)) 
      out = tf.tile(tf.reshape(x, shape_x_), multiples, name=scope) 

     try: 
      out.set_shape(shape) 
     except: 
      pass 

     return out 

A = tf.random_normal([20, 100, 10]) 
B = tf.random_normal([20, 100, 10]) 
C = tf.random_normal([20, 100, 1]) 

C = broadcast(C, A.shape) 
D = tf.select(C, A, B) 
İlgili konular