tensorflow中tensor运算函数记录

1
2
import tensorflow as tf
import numpy as np
1
2
3
4
5
6
# 这两种效果等价
np.random.seed(10)
a = np.random.randint(0,9,(2, 1, 4, 3))
b = np.random.randint(0,9,(2, 8, 3, 4))
print(tf.matmul(a, b).shape)
print(tf.matmul(tf.tile(a, [1, 8, 1, 1]), b).shape)
(2, 8, 4, 4)
(2, 8, 4, 4)
1
2
3
4
5
# 要广播的话,首先维度个数要一致
a = np.reshape(range(12), (2, 3, 2))
b = np.reshape(range(6), (2, 3, ))

print(tf.multiply(a, b[:, :, np.newaxis]))
tf.Tensor(
[[[ 0  0]
  [ 2  3]
  [ 8 10]]

 [[18 21]
  [32 36]
  [50 55]]], shape=(2, 3, 2), dtype=int32)

tf.pad

tf.pad(
tensor, paddings, mode=’CONSTANT’, constant_values=0, name=None
)
padding的rank和tensor保持一直,例如tensor=[[1,2,3]], padding=[[1,1], [2,2]],则表示在原始tensor的第一个维度上下各增加一行0,在第二个维度上左右各增加两列0

1
2
3
4
5
6
# 应用场景:机器翻译中,在decoder阶段,在target_input前填充一个句子开始符号
t=tf.constant([[1,2,3]])
print(t.shape)
t = tf.pad(t, paddings=[[0, 0], [1, 0]])
print(t.shape)
print(t)
(1, 3)
(1, 4)
tf.Tensor([[0 1 2 3]], shape=(1, 4), dtype=int32)

tf.stack

tf.stack(
values, axis=0, name=’stack’
)

1
2
3
4
5
x = tf.constant([1, 4])
y = tf.constant([2, 5])
z = tf.constant([3, 6])
print(tf.stack([x, y, z], axis=0)) # [[1, 4], [2, 5], [3, 6]] (Pack along first dim.)
print(tf.stack([x, y, z], axis=1)) # [[1, 2, 3], [4, 5, 6]]
tf.Tensor(
[[1 4]
 [2 5]
 [3 6]], shape=(3, 2), dtype=int32)
tf.Tensor(
[[1 2 3]
 [4 5 6]], shape=(2, 3), dtype=int32)

tf.slice

tf.slice(
tensor, begin, size, name=None
)

1
2
3
4
5
6
7
8
t = tf.constant([[[1, 1, 1], [2, 2, 2]],
[[3, 3, 3], [4, 4, 4]],
[[5, 5, 5], [6, 6, 6]]])
tf.slice(t, [1, 0, 0], [1, 1, 3]) # [[[3, 3, 3]]]
tf.slice(t, [1, 0, 0], [1, 2, 3]) # [[[3, 3, 3],
# [4, 4, 4]]]
tf.slice(t, [1, 0, 0], [2, 1, 3]) # [[[3, 3, 3]],
# [[5, 5, 5]]]
<tf.Tensor: id=28, shape=(2, 1, 3), dtype=int32, numpy=
array([[[3, 3, 3]],

       [[5, 5, 5]]])>

tf.tensordot

tf.tensordot(
a, b, axes, name=None
)
给定两个张量(维度大于等于 1 的数组),a 和 b,以及一个包含两个数组的数组, (a_axes, b_axes),把 a 和 b 的元素的乘积沿着 a_axes 和 b_axes 加和。 如果第三个参数是一个常数 N,那么就沿着 a 的最后 N 个 轴和 b 的前 N 个 轴加和。
a_axes和b_axes里的轴拉伸后形状要一样大

1
2
3
4
5
6
7
8
9
10
11
# 首先形状上
# 当axes为一个正整数N时,代表取a的后N个轴,b的前N个轴,
a = np.ones([5, 4, 2, 3])
b = np.ones([2, 3, 6])
print(tf.tensordot(a, b, 2).shape)
print('=====================')
# 当axes= (a_axes, b_axes), 形状就是去掉a_axes和b_axes里得轴
a = np.random.random([5, 4, 2, 3])
b = np.random.random([3, 2, 6])
print(np.tensordot(a, b, axes=((2, 3), (1, 0))).shape)
print(tf.tensordot(a, b, axes=((2, 3), (0,1))).shape)
(5, 4, 6)
=====================
(5, 4, 6)
(5, 4, 6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 深层运行机制
np.random.seed(10)
a = np.random.randint(0,9,(2, 2, 3))
b = np.random.randint(0,9,(3, 2, 6))
print(tf.tensordot(a, b, axes=2))
print(np.matmul(np.reshape(a, (2, -1)), np.reshape(b, (-1, 6))))

print('=====================================')
np.random.seed(10)
a = np.random.randint(0,9,(3, 2, 3, 5))
b = np.random.randint(0,9,(2, 2, 3))
res = tf.tensordot(a, b, axes=[(1, 2), (1,2)])
print(res.shape)
print(res[0, 0, 0])
print(np.multiply(a[0, :, :, 0].ravel(), b[0, :, :].ravel()).sum())
print('========================')
# 支持 transpose axis, 即对应选中的axis拉伸后做点积
res = tf.tensordot(a, b, axes=[(2, 1), (1,2)])
print(res[0, 0, 0])
print(np.multiply(np.transpose(a, [0, 2, 1,3])[0, :, :, 0].ravel(), b[0, :, :].ravel()).sum())
tf.Tensor(
[[ 58  67  91  78 103  48]
 [ 49  77  63 112  94 152]], shape=(2, 6), dtype=int32)
[[ 58  67  91  78 103  48]
 [ 49  77  63 112  94 152]]
=====================================
(3, 5, 2)
tf.Tensor(106, shape=(), dtype=int32)
106
========================
tf.Tensor(88, shape=(), dtype=int32)
88

tf.tile

tf.tile(
input, multiples, name=None
)

1
2
3
np.random.seed(10)
a = np.random.randint(0,9,(3, 1, 3, 5))
print(tf.tile(a, (1, 8, 1, 1)).shape)
(3, 8, 3, 5)