合并与分割
Merge and split
tf.concat
- [class1-4, students, scores]
- [class5-6, students, scores]
a = tf.ones([4,35,8])
b = tf.ones([2,35,8])
c = tf.concat([a,b], axis=0)
c.shape
a = tf.ones([4,32,8])
b = tf.ones([4,32,8])
tf.concat([a,b], axis=1).shape
tf.stack
- [classes, students, scores]
- [classes, students, scores]
- out:[schools, classes, students, scores]
a = tf.ones([4,35,8])
b = tf.ones([4,35,8])
tf.concat([a,b], axis=-1).shape
# [4,35,16]
tf.stack([a,b], axis=0).shape
# [2,4,35,8]
tf.stack([a,b], axis=3).shape
# [4,35,8,2]
tf.unstack
a = tf.ones([4,35,8])
b = tf.ones([4,35,8])
c = tf.stack([a,b])
c.shape
# [2,4,35,8]
aa,bb = tf.unstack(c, axis=0)
aa.shape,bb.shape
res = tf.unstack(c,axis=3)
res[0].shape,res[7].shape
# [2, 4, 35]
tf.split
c = ones([2, 4, 35, 8])
res = tf.unstack(c, axis=3)
len(res)
# 8
res = tf.split(c, axis=3, num_or_size_splits=2)
len(res)
res[0].shape # [2, 4, 35, 4]
res = tf.split(c, axis=3,num_or_size_splits=[2,2,4])
res[0].shape, res[2].shape
# [2, 4, 35, 2] [2, 4, 35, 4]
数据统计
tf.norm
- Vector Norm
- ∣ ∣ x ∣ ∣ 2 = [ ∑ k x k 2 ] 1 / 2 ||x||_2=[\sum_{k}{{x_k}^2}]^{1/2} ∣∣x∣∣2=[∑kxk2]1/2
a = tf.ones([2,2])
tf.norm(a)
tf.sqrt(tf.reduce_sum(tf.quare(a)))
a = tf.ones([4,28,28,3])
tf.norm(a)
tf.sqrt(tf.reduce_sum(tf.square(a)))
- ∣ ∣ x ∣ ∣ 1 = ∑ k ∣ x k ∣ ||x||_1 = \sum_k{|x_k|} ∣∣x∣∣1=∑k∣xk∣
b = tf.ones([2,2])
tf.norm(b)
tf.norm(b, ord=2, axis=1)
tf.norm(b, ord=1)
tf.norm(b. ord=1, axis=0)
tf.norm(b, ord=1, axis=1)
- ∣ ∣ x ∣ ∣ ∞ = m a x k ∣ x k ∣ ||x||_\infty=max_k{|x_k|} ∣∣x∣∣∞=maxk∣xk∣
- reduce_min/max/mean
a = tf.random.normal([4,10])
tf.reduce_min(a),tf.reduce_max(a),tf.reduce_mean(a)
tf.reduce_min(a,axis=1),tf.reduce_max(a, axis=1),tf.reduce_mean(a,axis=1)
- argmax/argmin
a.shape
# [4,10]
tf.argmax(a).shape
tf.argmax(a)# default axis = 0
- tf.equal
a = tf.constant([1,2,3,2,5])
b = tf.range(5)
tf.equal(a,b)
res = tf.equal(a,b)
tf.reduce_sum(tf.cast(res, dtype=tf.int32))
tf.unique
a = tf.range(5)
tf.unique(a)
a = tf.constant([4,2,2,4,3])
tf.unique(a)
uni, idx = tf.unique(a)
tf.gather(uni, idx)
张量排序
Sort/argsort
a = tf.random.shuffle(tf.range(5))
tf.sort(a,direction="DESCENDING")
tf.argsort(a,direction="DESCENDING")
idx - tf.argsort(a,direction='DESCENDING')
tf.gather(a, idx)
a = tf.random.uniform([3,3,maxval=10, dtype=tf.int32])
tf.sort(a)#default axis = -1
tf.sort(a, direction="DESCENDING")
idx=tf.argsort(a)
Topk
res = tf.math.top_k(a,2)# k=2
res.indices
res.values
- Top-k accuracy
batch_size = 2
k = 3
prob=tf.constant([[0.1,0.2,0.7][0.2,0.7,0.1])
trget=tf.constant([2,0])
k_b=tf.math.top_k(prob,k).indices
k_b=tf.transpose(k_b,[1,0])
trget = tf.broadcast_to(trget, [3,2])
correct = tf.equal(pred, trget)
correct = tf.reduce_sum(correct)
acc = float(correct / batch_size)
下面是一个完整的例子
import tensorflow as tf
import os
os.environ["TF_CPP_MIN_LOG_LEVEL"] = '2'
os.environ['CUDA_VISIBLE_DEVICES'] = '3'
tf.random.set_seed(2467)
def accuracy(output, target, topk=(1,)):
maxk = max(topk);
batch_size = target.shape[0]
pred = tf.math.top_k(output, maxk).indices
pred = tf.transpose(pred, perm=[1,0])
target_ = tf.broadcast_to(target, pred.shape)
correct = tf.equal(pred, target_)
res = []
for k in topk:
correct_k = tf.cast(tf.reshape(correct[:k], [-1]), dtype=tf.float32)
correct_k = tf.reduce_sum(correct_k)
acc = float(correct_k * 100 / batch_size)
res.append(acc)
return res
output = tf.random.normal([10,6])
output = tf.math.softmax(output, axis=1)
target = tf.random.uniform([10], maxval=6, dtype=tf.int32)
print('prob: ', output.numpy())
pred = tf.argmax(output, axis=1)
print('pred: ', pred.numpy())
print('label: ', target.numpy())
acc = accuracy(output, target, topk=(1, 2, 3, 4, 5, 6))
print('top-1-6 acc: ', acc)
填充与复制
Pad
- [[dim0_l, dim0_r][dim1_l, dim1_r]…[dimn_l,dimn_r]]
a = tf.reshape(tf.range(9), [3, 3])
tf.pad(a,[[0, 0], [0, 0]])
# [3, 3]
tf.pad(a, [[1, 0], [0, 0]])
# [4, 3]
tf.pad(a, [[1, 1], [0, 0]])
# [5, 3]
tf.pad(a, [[1, 1], [1, 0]])
# [5,4]
tf.pad(a, [[1, 1], [1, 1]])
# [5,5]
a = tf.random.normal([4,28,28,3])
b = tf.pad(a, [[0,0],[2,2],[2,2],[0,0]])
b.shape
# [4,32,32,3]
tile
- repeat data along dim n times
- [a,b,c],2
- → \rightarrow →[a,b,c,a,b,c]
a = a = tf.reshape(tf.range(9), [3, 3])
tf.tile(a, [1, 2])
# (3,6)
tf.tile(a, [2, 1])
# (6,3)
tf.tile(a, [2, 2])
tile vs broadcast_to
aa = tf.expand_dims(a, axis = 0)
# (1, 3, 3)
tf.tile(a, [2,1,1])
# (2,3,3)
tf.broadcast_to(aa, [2,3,3])
# (2,3,3)
- in memory : broadcast_to is better
张量限幅
clip_by_value
a = tf.range(10)
tf.maximum(a, 2)
tf,minimum(a, 8)
tf.clip_by_value(a, 2, 8)
relu
- m a x ( x , 0 ) max(x,0) max(x,0)
a = a - 5
tf.nn.relu(a)
tf.maximum(a,0)
clip_by_norm
a = tf.random.normal([2, 2], mean = 10)
tf.norm(a)
aa = tf.clip_by_norm(a, 15)
tf.norm(aa)
Gradient clipping
- Gradioent Exploding or vanishing
- set lr = 1
- new_grads, total_norm = tf.clip_by_global_norm(grads, 25)
高阶操作
where
输入一个bool型tensor A,返回一个tensor,给出A中值为True的所有坐标
# return [num, dim_num]
a = tf.random.normal([3, 3])
mask = a > 0
tf.boolean_mask(a, mask)
indices = tf.where(mask)
tf.gather_nd(a, indices)
- where(cond, A, B)
mask
A = tf.ones([3, 3])
B = tf.zeros([3, 3])
tf.where(mask, A, B)
scatter_nd
indices = tf.constant([[4], [3], [1], [7]])
updates = tf.constant([9, 10, 11, 12])
shape = tf.constant([8])
tf.scatter_nd(indices, updates, shape)
indices = tf.constant([[0], [2]])
updates = tf.constant([[[5, 5, 5, 5], [6, 6, 6, 6], [7, 7, 7, 7], [8, 8, 8, 8]],[[5, 5, 5, 5], [6, 6, 6, 6], [7, 7, 7, 7], [8, 8, 8, 8]]])
updates.shape
# [2, 4, 4]
shape = tf.constant([4, 4, 4])
tf.scatter_nd(indices, updates, shape)
meshgrid
- Numpy
points = []
for y in np.linspace(-2, 2, 5)
for x in np.linspace(-2, 2, 5)
points.append([x, y])
return np.array(points)
- GPU
这里x,y轴默认是几何意义上的xy轴,即x为横坐标,y为列坐标
y = tf.linspace(-2., 2, 5)
x = tf.linspace(-2., 2, 5)
points_x, points_y = tf.meshgrid(x, y)
points_x.shape
# [5, 5]
points = tf.stack([points_x, points_y], axis=2)
# [5, 5, 2]