【问题标题】:Better way than T.eye in theano在 theano 中比 T.eye 更好的方法
【发布时间】:2015-01-07 21:35:18
【问题描述】:

问题是,给定任意一维向量 y,将其扩展为具有 n 维度的 d 基向量。

展开的规则是:y中的每个元素都是n*n单位矩阵中列的索引。

例如:

 y = [3, 0, 1]
 n = 4

由于n = 4,我们有4*4 单位矩阵:

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

使用规则展开每个元素y,我们有:

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

我想用theano来解决这个问题,n(>50k)很大,y(>10k)很长,所以效率很重要。

使用 numpy 的解决方案是微不足道的,但是 numpy.eye 函数可能会花费太多,我们可以使用另一种方法使其更快。比较以下方法:

import numpy as np
import theano
import theano.tensor as T

n = 25500
y_value = np.asarray([2, 0, 10, 4], dtype='int32')

# method 1
%timeit np.eye(n)[y_value]  
# 10 loops, best of 3: 56.9 ms per loop

# method 2
def vec(i):
    e = np.zeros(n)
    e[i] = 1
    return e
%timeit np.vstack([vec(i) for i in y_value])  
# 100 loops, best of 3: 16.3 ms per loop

但是,第二种方法在 theano 中可能不起作用,因为符号变量中的循环可能不是微不足道的。有没有办法避免使用T.eye?

y_value 可以是任意一维向量。

【问题讨论】:

    标签: python numpy theano


    【解决方案1】:

    您可以尝试另一种方法。在我的电脑上:

    >>> %timeit np.eye(n)[y_value]
    1 loops, best of 3: 544 ms per loop
    

    但是,如果您事先知道所需的行,则无需创建整个数组。你可以这样做:

    >>> n = 25500
    >>> n_rows = y_value.size
    >>> r = np.zeros((n_rows, n))
    >>> r[range(n_rows), y_value] = 1
    

    您创建了一个更小的数组,只有y x n 其中y 是您的索引向量的大小,并在每一行中填充它。我电脑中的时间是:

    >>> %%timeit 
    ..: r = np.zeros((n_rows, n))
    ..: r[range(n_rows), y_value] = 1
    
    100 loops, best of 3: 3.8 ms per loop
    

    x151 在我的笔记本电脑中加速。

    此外,如果您不希望在后部(x 轴)出现一个充满零的数组,您可以这样做:

    >>> %%timeit 
    ..: r = np.zeros((n_rows, y_value.max()+1))
    ..: r[range(n_rows), y_value] = 1
    
    100000 loops, best of 3: 16 µs per loop
    

    哪个更快,但结果数组是y x ymax,在本例中为99 x 100,这可能不是您想要的。

    【讨论】:

      猜你喜欢
      • 2017-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-23
      • 2019-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多