Theano tensor 模块:操作符和逐元素操作

操作符

In [1]:

  1. import theano
  2. from theano import tensor as T
  1. Using gpu device 1: Tesla C2075 (CNMeM is disabled)

tensor 类型支持很多基本的操作:

In [2]:

  1. # 两个整形三维张量
  2.  
  3. a, b = T.itensor3("a"), T.itensor3("b")

算术操作

In [3]:

  1. print theano.pp(a + 3) # T.add(a, 3) -> itensor3
  2. print theano.pp(3 - a) # T.sub(3, a)
  3. print theano.pp(a * 3.5) # T.mul(a, 3.5) -> ftensor3 or dtensor3 (depending on casting)
  4. print theano.pp(2.2 / a) # T.truediv(2.2, a)
  5. print theano.pp(2.2 // a) # T.intdiv(2.2, a)
  6. print theano.pp(2.2**a) # T.pow(2.2, a)
  7. print theano.pp(b % a) # T.mod(b, a)
  1. (a + TensorConstant{3})
  2. (TensorConstant{3} - a)
  3. (a * TensorConstant{3.5})
  4. (TensorConstant{2.20000004768} / a)
  5. (TensorConstant{2.20000004768} // a)
  6. (TensorConstant{2.20000004768} ** a)
  7. mod(b, a)

比特操作

In [4]:

  1. print theano.pp(a & b) # T.and_(a,b) bitwise and (alias T.bitwise_and)
  2. print theano.pp(a ^ 1) # T.xor(a,1) bitwise xor (alias T.bitwise_xor)
  3. print theano.pp(a | b) # T.or_(a,b) bitwise or (alias T.bitwise_or)
  4. print theano.pp(~a) # T.invert(a) bitwise invert (alias T.bitwise_not)
  1. and_(a, b)
  2. xor(a, TensorConstant{1})
  3. or_(a, b)
  4. invert(a)

原地操作

Theano 不支持原地操作如 += 等,Theano 的图优化解构会自动决定是否使用原地操作。如果需要更新变量的值,可以考虑使用共享变量 theano.shared

逐元素操作

类型转换

T.cast(x, dtype) 用于类型转换:

In [5]:

  1. x = T.matrix()
  2. x_as_int = T.cast(x, 'int32')

T.cast(x, dtype) 的机制与 numpy.asarray(x, dtype) 的机制类似,只有 dtype 不同时才会创建新的变量:

In [6]:

  1. print x_as_int is x
  2. print T.cast(x, theano.config.floatX) is x
  1. False
  2. True

复数取实部,虚部,角度,模:

  • T.real(a)
  • T.imag(a)
  • T.angle(a)
  • T.abs_(a)

比较

Theano 的比较操作也是逐元素的:

  • T.lt(a, b) : <
  • T.gt(a, b) : >
  • T.le(a, b) : <=
  • T.ge(a, b) : >=
  • T.eq(a, b) : ==
  • T.neq(a, b) : != Theano 中没有 bool 类型,所有的 bool 类型都用 int8 表示。

In [7]:

  1. x, y = T.dmatrices('x','y')
  2.  
  3. print theano.pp(T.le(x, y))
  1. le(x, y)

除此之外,还有另一些与 numpy 类似的用法:

  • T.isnan(a) : 是否 NAN
  • T.isinf(a) : 是否 INF
  • T.isclose(a, b) :浮点数是否接近
  • T.allclose(a, b) :浮点数是否很接近

条件

T.switch(cond, ift, iff) 选择 ift (if ture)iff (if false)

T.where(cond, ift, iff)switch 一致。

T.clip(x, min, max) 低于 min 的部分变成 min,超过 max 的部分变成 max

数学操作

In [8]:

  1. a, b = T.matrices("a", "b")
  2.  
  3.  
  4. print theano.pp(T.maximum(a, b)) # max(a, b)
  5. print theano.pp(T.minimum(a, b)) # min(a, b)
  6.  
  7. print theano.pp(T.neg(a)) # -a
  8. print theano.pp(T.inv(a)) # 1.0/a
  9.  
  10. print theano.pp(T.exp(a))
  11. print theano.pp(T.log(a)), theano.pp(T.log2(a)), theano.pp(T.log10(a)) # log10(a)
  12.  
  13. print theano.pp(T.sgn(a)) # sgn(a)
  14. print theano.pp(T.floor(a)) # floor(a)
  15. print theano.pp(T.ceil(a)) # ceil(a)
  16. print theano.pp(T.round(a)) # round(a)
  17. print theano.pp(T.iround(a)) # iround(a)
  18.  
  19. print theano.pp(T.sqr(a)) # sqr(a)
  20. print theano.pp(T.sqrt(a)) # sqrt(a)
  21.  
  22. print theano.pp(T.cos(a)), theano.pp(T.sin(a)), theano.pp(T.tan(a))
  23. print theano.pp(T.cosh(a)), theano.pp(T.sinh(a)), theano.pp(T.tanh(a)) # tan(a)
  24.  
  25. print theano.pp(T.erf(a)), theano.pp(T.erfc(a)) # erf(a), erfc(a)
  26. print theano.pp(T.erfinv(a)), theano.pp(T.erfcinv(a))
  27.  
  28. print theano.pp(T.gamma(a)) # gamma(a)
  29. print theano.pp(T.gammaln(a)) # log(gamma(a))
  30. print theano.pp(T.psi(a)) # digamma(a)
  1. maximum(a, b)
  2. minimum(a, b)
  3. (-a)
  4. inv(a)
  5. exp(a)
  6. log(a) log2(a) log10(a)
  7. sgn(a)
  8. floor(a)
  9. ceil(a)
  10. round_half_away_from_zero(a)
  11. int64(round_half_away_from_zero(a))
  12. sqr(a)
  13. sqrt(a)
  14. cos(a) sin(a) tan(a)
  15. cosh(a) sinh(a) tanh(a)
  16. erf(a) erfc(a)
  17. erfinv(a) erfcinv(a)
  18. gamma(a)
  19. gammaln(a)
  20. psi(a)

其中 erf, erfc 定义如下:https://en.wikipedia.org/wiki/Error_function

\operatorname{erf}(x) = \frac{2}{\sqrt\pi} \int_0^x e^{-t^2} dt\begin{align} \operatorname{erfc}(x) & = 1-\operatorname{erf}(x) \ & = \frac{2}{\sqrt\pi} \int_x^{\infty} e^{-t^2}\,\mathrm dt \ & = e^{-x^2} \operatorname{erfcx}(x)\end{align}

erfinv, erfcinv 为其反函数:1https://en.wikipedia.org/wiki/Error_function#Inverse_functions

Broadcasting

09.17 Theano tensor 模块:操作符和逐元素操作 - 图1

图示如上。

线性代数

矩阵乘法:T.dot(x, y)

向量外积:T.outer(x, y)

张量乘法:tensordot(a, b, axes=2)

axes 参数表示 a b 对应要去掉的维度。

In [9]:

  1. import numpy as np
  2.  
  3. a = np.random.random((2,3,4))
  4. b = np.random.random((5,6,4,3))
  5.  
  6. #tensordot
  7. c = np.tensordot(a, b, [[1,2],[3,2]])
  8.  
  9.  
  10. #loop replicating tensordot
  11. a0, a1, a2 = a.shape
  12. b0, b1, _, _ = b.shape
  13. cloop = np.zeros((a0,b0,b1))
  14.  
  15. #loop over non-summed indices -- these exist
  16. #in the tensor product.
  17. for i in range(a0):
  18. for j in range(b0):
  19. for k in range(b1):
  20. #loop over summed indices -- these don't exist
  21. #in the tensor product.
  22. for l in range(a1):
  23. for m in range(a2):
  24. cloop[i,j,k] += a[i,l,m] * b[j,k,m,l]
  25.  
  26. assert np.allclose(c, cloop)
  27.  
  28. print a.shape, b.shape
  29. print c.shape
  1. (2, 3, 4) (5, 6, 4, 3)
  2. (2, 5, 6)

原文: https://nbviewer.jupyter.org/github/lijin-THU/notes-python/blob/master/09-theano/09.17-tensor-operator-and-elementwise-operations.ipynb