TensorFlow:numpy.repeat()替代方案

时间:2016-02-12 11:28:08

标签: tensorflow

我想以成对的方式比较神经网络中的预测值yp,所以我正在使用(回到我原来的numpy实现中):

idx = np.repeat(np.arange(len(yp)), len(yp))
jdx = np.tile(np.arange(len(yp)), len(yp))
s = yp[[idx]] - yp[[jdx]]

这基本上创建了一个索引网格,然后我使用它。 idx=[0,0,0,1,1,1,...] jdx=[0,1,2,0,1,2...]。我不知道是否有更简单的方式......

无论如何,TensorFlow有tf.tile(),但似乎缺少tf.repeat()

idx = np.repeat(np.arange(n), n)
v2 = v[idx]

我收到错误:

TypeError: Bad slice index [  0   0   0 ..., 215 215 215] of type <type 'numpy.ndarray'>

使用TensorFlow常量进行索引也不起作用:

idx = tf.constant(np.repeat(np.arange(n), n))
v2 = v[idx]

-

TypeError: Bad slice index Tensor("Const:0", shape=TensorShape([Dimension(46656)]), dtype=int64) of type <class 'tensorflow.python.framework.ops.Tensor'>

我的想法是将我的RankNet实现转换为TensorFlow。

10 个答案:

答案 0 :(得分:33)

使用tf.tile()tf.reshape()的组合可以达到np.repeat()的效果:

idx = tf.range(len(yp))
idx = tf.reshape(idx, [-1, 1])    # Convert to a len(yp) x 1 matrix.
idx = tf.tile(idx, [1, len(yp)])  # Create multiple columns.
idx = tf.reshape(idx, [-1])       # Convert back to a vector.

您只需使用jdx计算tf.tile()

jdx = tf.range(len(yp))
jdx = tf.tile(jdx, [len(yp)])

对于索引,您可以尝试使用tf.gather()yp张量中提取非连续切片:

s = tf.gather(yp, idx) - tf.gather(yp, jdx)

答案 1 :(得分:2)

看起来您的问题非常受人们欢迎refer it on TF tracker。遗憾的是,TF中仍没有实现相同的功能。

您可以通过合并tf.tiletf.reshapetf.squeeze来实现它。以下是从np.repeat转换示例的方法:

.as-console-wrapper { max-height: 100% !important; top: 0; }

在最后一种情况下,每个元素的重复次数不同,您可能需要loops

答案 2 :(得分:1)

以防任何人对2D方法复制矩阵感兴趣。我认为这可行:

TF_obj = tf.zeros([128, 128])
tf.tile(tf.expand_dims(TF_obj, 2), [1, 1, 2])

答案 3 :(得分:1)

import numpy as np
import tensorflow as tf
import itertools    

x = np.arange(6).reshape(3,2)
x = tf.convert_to_tensor(x)
N = 3 # number of repetition
K = x.shape[0] # for here 3

order = list(range(0, N*K, K))
order = [[x+i for x in order] for i in range(K)]
order = list(itertools.chain.from_iterable(order))
x_rep = tf.gather(tf.tile(x, [N, 1]), order)

结果来自:

   [0, 1],
   [2, 3],
   [4, 5]]

收件人:

  [[0, 1],
   [0, 1],
   [0, 1],
   [2, 3],
   [2, 3],
   [2, 3],
   [4, 5],
   [4, 5],
   [4, 5]]

如果需要:

  [[0, 1],
   [2, 3],
   [4, 5],
   [0, 1],
   [2, 3],
   [4, 5],
   [0, 1],
   [2, 3],
   [4, 5]]

只需使用tf.tile(x, [N, 1])

答案 4 :(得分:1)

仅针对一维张量,我已经实现了此功能

def tf_repeat(y,repeat_num)   
        return tf.reshape(tf.tile(tf.expand_dims(y,axis=-1),[1,repeat_num]),[-1]) 

答案 5 :(得分:1)

根据tf api documenttf.keras.backend.repeat_elements()np.repeat()做相同的工作。例如,

x = tf.constant([1, 3, 3, 1], dtype=tf.float32)
rep_x = tf.keras.backend.repeat_elements(x, 5, axis=0)
# result: [1. 1. 1. 1. 1. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 1. 1. 1. 1. 1.]

答案 6 :(得分:0)

您可以通过execute()自行设置值来模拟缺少的foreach($inArray as $array) { // build the array of parameters and values $params = [ ':a' => $array['field1'] ':b' => $array['field2'] ':c' => $array['field3'] ':d' => $array['field4'] ':e' => $array['field5'] ]; // execute the prepared query using the new parameters $stmt->execute($params); }

tf.repeat

我建议仅在重复次数较少的情况下使用此功能。

答案 7 :(得分:0)

尽管已经给出了许多干净可行的解决方案,但它们似乎都是基于每次迭代从头开始生成索引集的基础。

尽管在训练过程中生产这些节点的成本通常并不高,但是如果使用模型进行推理可能会很重要。

重复tf.range(如您的示例)已经出现了几次,所以我构建了以下函数创建器。给定最大重复次数和需要重复的最大次数,它返回一个函数,该函数产生的值与np.repeat(np.arange(len(multiples)), multiples)相同。

import tensorflow as tf
import numpy as np


def numpy_style_repeat_1d_creator(max_multiple=100, max_to_repeat=10000):
    board_num_lookup_ary = np.repeat(
        np.arange(max_to_repeat),
        np.full([max_to_repeat], max_multiple))
    board_num_lookup_ary = board_num_lookup_ary.reshape(max_to_repeat, max_multiple)

    def fn_to_return(multiples):
        board_num_lookup_tensor = tf.constant(board_num_lookup_ary, dtype=tf.int32)
        casted_multiples = tf.cast(multiples, dtype=tf.int32)
        padded_multiples = tf.pad(
            casted_multiples,
            [[0, max_to_repeat - tf.shape(multiples)[0]]])

        return tf.boolean_mask(
            board_num_lookup_tensor,
            tf.sequence_mask(padded_multiples, maxlen=max_multiple))

    return fn_to_return

#Here's an example of how it can be used
with tf.Session() as sess:
    repeater = numpy_style_repeat_1d_creator(5,4)
    multiples = tf.constant([4,1,3])

    repeated_values = repeater(multiples)
    print(sess.run(repeated_values))

通常的想法是存储一个重复的张量,然后对其进行遮罩,但这可能有助于从视觉上看到它(这是上面给出的示例):

In the example above the following Tensor is produced:
[[0,0,0,0,0],
 [1,1,1,1,1],
 [2,2,2,2,2],
 [3,3,3,3,3]]

For multiples [4,1,3] it will collect the non-X values:
[[0,0,0,0,X],
 [1,X,X,X,X],
 [2,2,2,X,X],
 [X,X,X,X,X]]

resulting in:
[0,0,0,0,1,2,2,2]

tl; dr:为避免每次都生成索引(可能会很昂贵),请预先重复所有操作,然后每次都屏蔽该张量

答案 8 :(得分:0)

最近从1.13版本开始,在RaggedTensor实用工具中添加了relatively fast实现,但它不是正式导出的API的一部分。您仍然可以使用它,但是它可能会消失。

from tensorflow.python.ops.ragged.ragged_util import repeat

从源代码开始:

# This op is intended to exactly match the semantics of numpy.repeat, with
# one exception: numpy.repeat has special (and somewhat non-intuitive) behavior
# when axis is not specified.  Rather than implement that special behavior, we
# simply make `axis` be a required argument.

答案 9 :(得分:0)

所以我发现tensorflow有一种这样的方法可以重复数组的元素。您正在寻找方法def form_valid(form,request): if form.is_valid(): form.save() if request.user.is_staff: messages.success(request, f'List has been updated!') else: messages.warning(request, f'You do not have Admin access!') else: print(form.errors) context={ "form":form, } return render(request,'movies_list/list_create.html',context) @login_required def Award_list_update(request,award_id): obj=get_object_or_404(Award_list,award_id=award_id) form=Create_Award_list_form( data=(request.POST or None), files=(request.FILES or None), instance=obj, ) form_valid(form,request) 。任何迟到的人都可以节省很多精力。 link对此方法提供了解释,并特别说明了

  

沿着轴重复张量的元素,例如np.repeat

我提供了一个非常简短的示例,它证明了元素的复制与tf.keras.backend.repeat_elements一样。

np.repeat