मेरे पास एक 3D टेंसर x है जो फ्लोट प्रकार का है, और एक 1D टेंसर y जो कि int प्रकार का है। मैं x के दूसरे अक्ष के प्रत्येक स्लाइस का औसत 0 से y के प्रत्येक तत्व से संबंधित इंडेक्स तक प्राप्त करना चाहता हूं। दूसरे शब्दों में, अगर x और y सुन्न सरणियाँ थे, तो मैं चाहूंगा

In [1]: y = [1, 2, 1, 1]

In [2]: x = np.array([[[1,2],[3,4],[5,6]], [[1,2],[3,4],[5,6]], [[1,2],[3,4],[5,6]], [[1,2],[3,4],[5,6]]])

In [3]: np.array([np.mean(x[index, :item], axis=0) for index, item in enumerate(y)])
Out[22]: 
array([[ 1.,  2.],
       [ 2.,  3.],
       [ 1.,  2.],
       [ 1.,  2.]]) 

ऐसा करने का सबसे आसान तरीका क्या है?

2
Alex 6 जुलाई 2017, 08:53

1 उत्तर

सबसे बढ़िया उत्तर

सामान्य स्थिति में, आप tf.while_loop का उपयोग कर सकते हैं:

import numpy as np
import tensorflow as tf

y = tf.constant([1, 2, 1, 1])
x = tf.constant([[[1,2],[3,4],[5,6]],
                 [[1,2],[3,4],[5,6]],
                 [[1,2],[3,4],[5,6]],
                 [[1,2],[3,4],[5,6]]], dtype=np.float32)

y_len = tf.shape(y)[0]
idx = tf.zeros((), dtype=tf.int32)
res = tf.zeros((0,2))
_, res = tf.while_loop(
    lambda idx, res: idx < y_len,
    lambda idx, res: (idx + 1, tf.concat([res, tf.reduce_mean(x[idx, :y[idx]], axis=0)[tf.newaxis]], axis=0)),
    [idx, res],
    shape_invariants=[idx.get_shape(), tf.TensorShape([None, 2])])

sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
res.eval()

# returns
# array([[ 1.,  2.],
#        [ 2.,  3.],
#        [ 1.,  2.],
#        [ 1.,  2.]], dtype=float32)    

कम सामान्य स्थिति में जहां y की लंबाई ग्राफ़ निर्माण समय पर जानी जाती है, आप अपने आप को अजगर में एक tf.while_loop और लूप के उपयोग से बचा सकते हैं (परिणामस्वरूप एक बड़ा ग्राफ हो सकता है यदि y में कई तत्व हैं)।

y_len = y.shape.num_elements()
res = tf.Variable(np.zeros((y_len, 2), dtype=np.float32))
res = tf.tuple([res] + [res[idx].assign(tf.reduce_mean(x[idx, :y[idx]], axis=0))
   for idx in range(y_len)])[0]

ध्यान दें कि आप केवल अपडेट को कैस्केड कर सकते हैं, tf.while_loop के सामान्य मामले के विपरीत नहीं:

y_len = y.shape.num_elements()
res = tf.zeros((0,2))
for idx in range(y_len):
  res = tf.concat([res, tf.reduce_mean(x[idx, :y[idx]], axis=0)[tf.newaxis]], axis=0)

लेकिन अब अपडेट क्रमिक रूप से होने चाहिए। पूर्व समाधान में, प्रत्येक पंक्ति के अपडेट स्वतंत्र होते हैं और समानांतर में चल सकते हैं, जो मुझे लगता है कि बेहतर है।

2
P-Gn 6 जुलाई 2017, 21:46
धन्यवाद! कोड का आपका दूसरा ब्लॉक हालांकि मुझे एक FailedPreconditionError दे रहा है।
 – 
Alex
6 जुलाई 2017, 20:55
मैंने इसे गलत जगह पर चलाया, उफ़, अब समस्या ठीक हो गई है। धन्यवाद।
 – 
Alex
6 जुलाई 2017, 21:03