a = tf.ones([4,35,8])
b = tf.ones([2,35,8]) # 拼接,axis=0,就是针对第一个元素
c=tf.concat([a,b],axis=0) # 需要两个维度相同
TensorShape([6, 35, 8])
a = tf.ones([4,32,8]);b=tf.ones([4,3,8])
tf.concat([a,b],axis=1).shape
TensorShape([4, 35, 8])
print(a.shape,b.shape)
tf.concat([a,b],axis=-1).shape # 合并不会增加一个新的维度
(4, 32, 8) (4, 32, 8)
TensorShape([4, 32, 16])
tf.stack([a,b],axis=0).shape # stack可以增加一个新的维度
TensorShape([2, 4, 32, 8])
tf.stack([a,b],axis=3).shape # 可以指定前后,需要拼接的两个维度相同
TensorShape([4, 32, 8, 2])
print(a.shape,b.shape)
c = tf.stack([a,b])
print(c.shape)
aa,bb = tf.unstack(c,axis=0) # 拆分
aa.shape,bb.shape
(4, 32, 8) (4, 32, 8)
(2, 4, 32, 8)
(TensorShape([4, 32, 8]), TensorShape([4, 32, 8]))
res = tf.unstack(c,axis=3) # 拆分为8个
res[0].shape,res[1].shape,len(res)
(TensorShape([2, 4, 32]), TensorShape([2, 4, 32])),8
# 分组,灵活性更强
res = tf.split(c,axis=3,num_or_size_splits=2)
len(res) # 2
res[0].shape
TensorShape([2, 4, 32, 4])
res = tf.split(c,axis=3,num_or_size_splits=[2,2,4])
for each in res:
print(each.shape))
(2, 4, 32, 2)
(2, 4, 32, 2)
(2, 4, 32, 4)
# 向量的范数
a=tf.ones([2,2])
tf.norm(a) # 二阶范数,tf.sqrt(tf.reduce_sum(tf.square(a))) 全元素平和开跟
<tf.Tensor: shape=(), dtype=float32, numpy=2.0>
tf.norm(a,ord=2,axis=1) # 指定维度求范数
<tf.Tensor: shape=(2,), dtype=float32, numpy=array([1.4142135, 1.4142135], dtype=float32)>
tf.norm(a,ord=1) # 一阶求和
<tf.Tensor: shape=(), dtype=float32, numpy=4.0>
a = tf.random.normal([4,10]) # 最大最小值,均值
tf.reduce_min(a),tf.reduce_max(a),tf.reduce_mean(a) # 都有 axis 这个属性,前面的reduce 就是提示会降维
(<tf.Tensor: shape=(), dtype=float32, numpy=-1.8088812>,
<tf.Tensor: shape=(), dtype=float32, numpy=2.0708714>,
<tf.Tensor: shape=(), dtype=float32, numpy=0.061080307>)
# 默认axis=0,针对 0 维,10组
tf.argmax(a).shape,tf.argmax(a)
(TensorShape([10]),
<tf.Tensor: shape=(10,), dtype=int64, numpy=array([2, 2, 2, 3, 0, 2, 2, 1, 3, 3])>)
# 比较操作
a = tf.constant([1,2,3,2,5])
b = tf.range(5)
tf.equal(a,b)
<tf.Tensor: shape=(5,), dtype=bool, numpy=array([False, False, False, False, False])>
res = tf.equal(a,b) # bool转类型,然后求和
tf.reduce_sum(tf.cast(res,dtype = tf.int32))
<tf.Tensor: shape=(), dtype=int32, numpy=0>
# 唯一值
a = tf.constant([4,2,2,1,4])
tf.unique(a)
Unique(y=<tf.Tensor: shape=(3,), dtype=int32, numpy=array([4, 2, 1], dtype=int32)>, idx=<tf.Tensor: shape=(5,), dtype=int32, numpy=array([0, 1, 1, 2, 0], dtype=int32)>)
b =tf.unique(a)
b.idx,b.index,b.y
(<tf.Tensor: shape=(5,), dtype=int32, numpy=array([0, 1, 1, 2, 0], dtype=int32)>,
<function Unique.index(value, start=0, stop=9223372036854775807, /)>,
<tf.Tensor: shape=(3,), dtype=int32, numpy=array([4, 2, 1], dtype=int32)>)
tf.gather(b.y,b.idx) # 复原
<tf.Tensor: shape=(5,), dtype=int32, numpy=array([4, 2, 2, 1, 4], dtype=int32)>
prob = tf.constant([[0.1,0.2,0.7],[0.2,0.7,0.1]]) # 表示可能性
target = tf.constant([2,0]) # 实际值
k_b = tf.math.top_k(prob,3).indices # 前三个
k_b
<tf.Tensor: shape=(2, 3), dtype=int32, numpy=
array([[2, 1, 0],
[1, 0, 2]], dtype=int32)>
def accuracy(output, target, topk=(1,)):
# 一个用来测精度的函数,指定考虑前几个概率
# output [b,N], target[b]
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)
# [10, b]
correct = tf.equal(pred, target_)
# print(correct)
res = []
for k in topk: # 比较前几行,转换为0,1 在计算个正确率
correct_k = tf.cast(tf.reshape(correct[:k], [-1]), dtype=tf.float32)
correct_k = tf.reduce_sum(correct_k)
acc = float(correct_k* (100.0 / batch_size) )
res.append(acc)
return res
output = tf.random.normal([10, 6]) # 10个样本,6类
output = tf.math.softmax(output, axis=1) # 让输出值总和为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())
# 意思就是考虑前几个概率大的值,有一个对了就对了,当全考虑时,概率就是100了
acc = accuracy(output, target, topk=(1,2,3,4,5,6)) #
print('top-1-6 acc:', acc)
prob: [[0.08726542 0.02225256 0.4912736 0.06410525 0.08286054 0.25224262]
[0.13055882 0.07061573 0.26486665 0.20455424 0.20469896 0.1247056 ]
[0.43044326 0.10636217 0.16449806 0.05707863 0.19358431 0.04803355]
[0.16948995 0.01624216 0.5305888 0.0307715 0.06940161 0.18350598]
[0.3525269 0.1322329 0.02679942 0.303122 0.1113945 0.07392432]
[0.06559116 0.09399377 0.26416907 0.16099243 0.1656936 0.24955998]
[0.25813058 0.07047742 0.20491946 0.06957188 0.27260825 0.12429236]
[0.28551948 0.16485259 0.10330899 0.09955222 0.30379328 0.0429734 ]
[0.08291844 0.11529168 0.35974807 0.14822288 0.14078341 0.15303555]
[0.11123328 0.15178108 0.2656589 0.15466414 0.12525429 0.19140829]]
pred: [2 2 0 2 0 2 4 4 2 2]
label: [4 5 3 0 5 3 1 0 5 2]
top-1-6 acc: [10.0, 30.0, 40.0, 60.0, 100.0, 100.0]
a =tf.reshape(tf.range(9),[3,3])
a
<tf.Tensor: shape=(3, 3), dtype=int32, numpy=
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]], dtype=int32)>
# a 是二维的,axis=0就是行[1,0] 就是前面加一行,后面不加
# axis = [0,0] 列的前后都不加
array([[0, 0, 0],
tf.pad(a,[[1,0],[0,0]])
<tf.Tensor: shape=(5, 3), dtype=int32, numpy=
array([[0, 0, 0],
[0, 1, 2],
[3, 4, 5],
[6, 7, 8]], dtype=int32)>
tf.pad(a,[[1,1],[1,1]]) # 懂了吗
<tf.Tensor: shape=(5, 5), dtype=int32, numpy=
array([[0, 0, 0, 0, 0],
[0, 0, 1, 2, 0],
[0, 3, 4, 5, 0],
[0, 6, 7, 8, 0],
[0, 0, 0, 0, 0]], dtype=int32)>
a = tf.random.normal([4,28,28,3])
b = tf.pad(a,[[0,0],[2,2],[2,2],[0,0]]) # 用于图片的填充,NLP中单词数量的padding
b.shape
TensorShape([4, 32, 32, 3])
tf.tile(a,[1,2]) # 第一个维度复制一次,第二个维度复制两次
<tf.Tensor: shape=(3, 6), dtype=int32, numpy=
array([[0, 1, 2, 0, 1, 2],
[3, 4, 5, 3, 4, 5],
[6, 7, 8, 6, 7, 8]], dtype=int32)>
tf.tile(a,[2,1])
<tf.Tensor: shape=(6, 3), dtype=int32, numpy=
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 1, 2],
[3, 4, 5],
[6, 7, 8]], dtype=int32)>
tf.tile(a,[2,2])
<tf.Tensor: shape=(6, 6), dtype=int32, numpy=
array([[0, 1, 2, 0, 1, 2],
[3, 4, 5, 3, 4, 5],
[6, 7, 8, 6, 7, 8],
[0, 1, 2, 0, 1, 2],
[3, 4, 5, 3, 4, 5],
[6, 7, 8, 6, 7, 8]], dtype=int32)>
[50]
aa = tf.expand_dims(a,axis=0)
aa
<tf.Tensor: shape=(1, 3, 3), dtype=int32, numpy= # 扩维填充
array([[[0, 1, 2],
[3, 4, 5],
[6, 7, 8]]], dtype=int32)>
[51]
tf.tile(aa,[2,1,1])
<tf.Tensor: shape=(2, 3, 3), dtype=int32, numpy=
array([[[0, 1, 2],
[3, 4, 5],
[6, 7, 8]],
[[0, 1, 2],
[3, 4, 5],
[6, 7, 8]]], dtype=int32)>
[52]
tf.broadcast_to(aa,[2,3,3])
<tf.Tensor: shape=(2, 3, 3), dtype=int32, numpy= # 效果同上,但性能上面那个更好,不会占据内存
array([[[0, 1, 2],
[3, 4, 5],
[6, 7, 8]],
[[0, 1, 2],
[3, 4, 5],
[6, 7, 8]]], dtype=int32)> # 但针对一些操作符 +- 之类的可以自动进行广播,还是很方便的
就是值的裁剪,relu函数就是这
a = tf.range(10)
a
<tf.Tensor: shape=(10,), dtype=int32, numpy=array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int32)>
tf.maximum(a,2) # 就是限幅。。。。。。。多维也是一样,这个是逐元素操作
<tf.Tensor: shape=(10,), dtype=int32, numpy=array([2, 2, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int32)>
tf.minimum(a,8)
<tf.Tensor: shape=(10,), dtype=int32, numpy=array([0, 1, 2, 3, 4, 5, 6, 7, 8, 8], dtype=int32)>
tf.clip_by_value(a,2,8) # 两边一起
<tf.Tensor: shape=(10,), dtype=int32, numpy=array([2, 2, 2, 3, 4, 5, 6, 7, 8, 8], dtype=int32)>
tf.nn.relu(a) == tf.maximum(a,0)
<tf.Tensor: shape=(10,), dtype=bool, numpy=
array([ True, True, True, True, True, True, True, True, True,
True])>
# 范数限幅
a = tf.random.normal([2,2],mean=10)
a
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[ 9.134853 , 9.628895 ],
[10.4377 , 10.5661335]], dtype=float32)>
tf.norm(a)
<tf.Tensor: shape=(), dtype=float32, numpy=19.918583> # 当前范数
aa = tf.clip_by_norm(a,15) # 指定限幅后的范数
aa
<tf.Tensor: shape=(2, 2), dtype=float32, numpy= # 计算的过程就是除以原范数,在乘以指定的
array([[6.8791437, 7.2511897], # 作用就是保证向量的方向不变,改变膜的大小
[7.8602734, 7.956992 ]], dtype=float32)>
tf.norm(aa)
<tf.Tensor: shape=(), dtype=float32, numpy=15.0>
# 应对梯度下降中的梯度爆炸和梯度消失(下降步幅过大,过小)
grads,total_norm = tf.clip_by_global_norm(grads,25) # 对网络的整体参数进行等比例缩放(保证所有向量方向不改变)
# 返回缩放后的结果和缩放前向量的范数,参数25是缩放后整体的范数。
# 比如梯度(导数)几百,损失很多的nan,就需要加上这个来缩放梯度。
a = tf.random.normal([3,3])
a
<tf.Tensor: shape=(3, 3), dtype=float32, numpy=
array([[-0.07731798, -0.78015125, 0.29295778],
[-0.32711634, 0.5294314 , -0.44531348],
[ 0.65166456, -0.9208928 , 0.4694049 ]], dtype=float32)>
mask = a>0
mask
<tf.Tensor: shape=(3, 3), dtype=bool, numpy=
array([[False, False, True],
[False, True, False],
[ True, False, True]])>
tf.boolean_mask(a,mask)
<tf.Tensor: shape=(4,), dtype=float32, numpy=array([0.29295778, 0.5294314 , 0.65166456, 0.4694049 ], dtype=float32)>
indices = tf.where(mask) # 这个就是返回布尔数组中为True的位置,注意shape
indices
<tf.Tensor: shape=(4, 2), dtype=int64, numpy=
array([[0, 2],
[1, 1],
[2, 0],
[2, 2]])>
tf.gather_nd(a,indices) # 借助where得到的索引,使用这个就可以提取出True的元素
<tf.Tensor: shape=(4,), dtype=float32, numpy=array([0.29295778, 0.5294314 , 0.65166456, 0.4694049 ], dtype=float32)>
mask
<tf.Tensor: shape=(3, 3), dtype=bool, numpy=
array([[False, False, True],
[False, True, False],
[ True, False, True]])>
A = tf.ones([3,3])
B = tf.zeros([3,3])
tf.where(mask,A,B) # 就相当于一个条件吧,Ture部分用A,False部分就用B
<tf.Tensor: shape=(3, 3), dtype=float32, numpy=
array([[0., 0., 1.],
[0., 1., 0.],
[1., 0., 1.]], dtype=float32)>
indices = tf.constant([[4],[3],[1],[2]])
updates = tf.constant([9,10,11,12])
shape = tf.constant([8]) # 或者多维的
tf.scatter_nd(indices,updates,shape) # 就是在形状为shape的地板上,根据indices更新数据,其余用0填充
<tf.Tensor: shape=(8,), dtype=int32, numpy=array([ 0, 11, 12, 10, 9, 0, 0, 0], dtype=int32)>\
# 网格
y = tf.linspace(-2,2,5)
x = tf.linspace(-2,2,5)
points_x,points_y = tf.meshgrid(x,y)
points_x.shape
TensorShape([5, 5])
(<tf.Tensor: shape=(5, 5), dtype=float64, numpy= # x,y 组合成所有点的坐标
array([[-2., -1., 0., 1., 2.],
[-2., -1., 0., 1., 2.],
[-2., -1., 0., 1., 2.],
[-2., -1., 0., 1., 2.],
[-2., -1., 0., 1., 2.]])>,
<tf.Tensor: shape=(5, 5), dtype=float64, numpy=
array([[-2., -2., -2., -2., -2.],
[-1., -1., -1., -1., -1.],
[ 0., 0., 0., 0., 0.],
[ 1., 1., 1., 1., 1.],
[ 2., 2., 2., 2., 2.]])>)
points = tf.stack([points_x,points_y],axis=2) # 要得到坐标,堆叠一下组合
points
<tf.Tensor: shape=(5, 5, 2), dtype=float64, numpy=
array([[[-2., -2.],
[-1., -2.],
[ 0., -2.],
[ 1., -2.],
[ 2., -2.]],
[[-2., -1.],
[-1., -1.],
[ 0., -1.],
[ 1., -1.],
[ 2., -1.]], 。。。。
# 用途就是绘图吧,,,等高线之类的
import tensorflow as tf
import matplotlib.pyplot as plt
# z = sin(x) + sin(y)
def func(x):
z = tf.math.sin(x[...,0]) + tf.math.sin(x[...,1])
return z
x = tf.linspace(0., 2*3.14, 500)
y = tf.linspace(0., 2*3.14, 500)
# [50, 50]
point_x, point_y = tf.meshgrid(x, y)
# [50, 50, 2]
points = tf.stack([point_x, point_y], axis=2)
# points = tf.reshape(points, [-1, 2])
print('points:', points.shape)
z = func(points)
print('z:', z.shape)
plt.figure('plot 2d func value')
plt.imshow(z, origin='lower', interpolation='none') # 不知道叫啥
plt.colorbar()
plt.figure('plot 2d func contour')
plt.contour(point_x, point_y, z) # 等高线
plt.colorbar()
plt.show()
函数 | 用法 | 备注 |
---|---|---|
tf.concat(a,b,axis) | 拼接(不会增加新的维度) | (4,35,8),(2,35,8)-axis=0-> (6,35,8) |
tf.stack([a,b],axis) | 堆叠(可以前后增加新的维度axis=0/-1) | (4,35,8),(4,35,8)-axis=0-> (2,8,35,8) |
tf.unstack(c,axis) | 拆分为多个 | (2, 4, 32, 8) -axis=3-> 8个(2,4,32) |
tf.split(c,axis=3,num_or_size_splits=[2,2,4]) | 分组灵活性更强 | |
tf.norm(a,ord,axis) | 范数 | |
tf.reduce_min\max\mean(a, axis) | 最大最小值,均值 | |
tf.argmax\argmin(a,axis) } | 最值的索引 | |
tf.equal(a,b) | 比较,返回布尔值 | tf.reduce_sum(tf.cast(res,dtype = tf.int32))转换为整形在求和 |
b = tf.unique(a) | 唯一值 | b.idx, b.index, b.y,tf.agther(b,y, b.idx) 复原 |
tf.math.top_k(p,3) | 考虑前3个值 | .indices 得到索引 |
tf.pad(a,[[0,0],[2,2],[2,2],[0,0]]) | 在维度前后添加值为0的行/列 | [4,28,28,3]-》[4, 32, 32, 3] |
tf.tile(a,[1,2]) | 第一个维度不变,第二个维度复制堆叠 | |
tf.expand_dims(a,axis=0) | 扩维 | (3,3) -> (1,3,3),在进行title([2,1,1])就是广播了 |
tf.maximum(a,2)\minimum(a,8)clip_by_value(a,2,8) | 下限幅,上限幅,双边 | |
tf.clip_by_norm(a,15) | 范数限幅,限幅后范数为15 | 保证向量方向不变 |
grads,total_norm = tf.clip_by_global_norm(grads,25) | 整体参数限幅 | 应对梯度消失爆炸 |
tf.boolean_mask(a,mask) | 返回mask为真对应a 的值 | |
indices = tf.where(mask) | 返回bool数组中为真的位置 | tf.gather_nd(a,indices)作用同上 |
tf.scatter_nd(indices,updates,shape) | 在形状为shape的地板上,根据indices更新数据,其余用0填充 | |
x,y = tf.meshgrid(x,y) | 网格 | points = tf.stack([points_x,points_y],axis=2)得到坐标 |