tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
tensorFlow2.0的高阶操作! |
一、张量的合并和分割(merge, split)
1.1、tf.concat()拼接操作
In [1]: import tensorflow as tf
In [2]: a=tf.ones([4,35,8])
In [3]: b=tf.ones([2,35,8])
In [4]: c=tf.concat([a,b],axis=0)
In [5]: c.shape
Out[5]: TensorShape([6, 35, 8])
- 例子:
1.2、tf.stack()创建一个维度
1.3、维度不匹配情况
1.4、tf.unstack()对应tf.stack()
二、数理统计
2.1、tf.norm()张量的范数(向量范数)
- 张量的范数包括向量范数和矩阵范数,这里只讨论向量范数
2.2、tf.reduce_min/max/mean():求均值,最大值,最小值
2.3、tf.argmax/argmin():最大值的位置
2.4、tf.equal(a,b):逐个判断a,b中元素是否相等
- accuracy的例子!
2.5、tf.unique():去除重复的元素
三、张量排序
3.1、tf.sort()排序,tf.argsort()排序得到元素index
注意: tf.random.shuffle():对元素进行随机的打乱!
3.2、top-k之tf.math.top_k()最大的前k个元素
3.3、top-k accuracy
注意: 这就是top-k accuracy 的定义,可以看出top-1 accuracy是要求最严格的,因为我们要求概率最大的那个是预测对的。但是实际上top-1可能没有这么表现好。例如:我们在imagenet上面,有1000多个类别,每个类的物种是非常非常复杂的,我们做预测的时候有时候发现不太好,有时候只有70%的top-1 accuracy,或者80%的top-1 accuracy。
- 那么为了很好的检测一个算法的性能,我们还会考虑另一个指标,Top-5 accuracy,也就是说1000个类别中,如果前5个预测可能性最高之中预测对了一个,那么我们呢就认为预测对了。虽然没有top-1 那么精准,但是top-5也能从另一个方面反映模型是否比较好,是否优于目前的。
- 如何计算top-k accuracy
3.4、top-k accuracy实战例子!
- 完整例子:
- 代码演示:
import tensorflow as tf
import os
os.environ["TF_CPP_MIN_LOG_LEVEL"] = '2'
tf.random.set_seed(2467)
def accuracy(output, target, topk=(1,)):
maxk = max(topk) #这里为6
batch_size = target.shape[0] #tensor的行数
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_)
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.0 / batch_size) )
res.append(acc)
return res
#用正太分布生成10个样本,6类,然后进行一个softmax.
output = tf.random.normal([10, 6])
output = tf.math.softmax(output, axis=1)
target = tf.random.uniform([10], maxval=6, dtype=tf.int32) #0-5之间随机10个数。
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)) #top1~top6的accuracy
print('top-1-6 acc:', acc)
运行结果:
ssh://[email protected]:22/home/zhangkf/anaconda3/envs/tf2.0/bin/python -u /home/zhangkf/tf1/demo/TF2/demo1.py
prob: [[0.2531028 0.21715645 0.16043884 0.13088997 0.04334084 0.19507112]
[0.05892419 0.04548918 0.00926314 0.14529602 0.66777605 0.07325139]
[0.09742808 0.08304427 0.07460099 0.04067176 0.626185 0.07806987]
[0.20478567 0.12294924 0.12010485 0.1375123 0.3641873 0.05046057]
[0.11872064 0.31072396 0.12530337 0.15528883 0.21325871 0.07670453]
[0.01519807 0.09672115 0.1460476 0.00934331 0.5649092 0.16778068]
[0.04199062 0.18141054 0.06647632 0.6006175 0.03198383 0.07752118]
[0.0922622 0.2346089 0.13022321 0.16295874 0.05362029 0.3263266 ]
[0.07019574 0.08611771 0.10912605 0.10521299 0.2152082 0.4141393 ]
[0.01882888 0.2659769 0.19122465 0.24109262 0.14920163 0.13367529]]
pred: [0 4 4 4 1 4 3 5 5 1]
label: [0 2 3 4 2 4 2 3 5 5]
top-1-6 acc: [40.0, 40.0, 50.0, 70.0, 80.0, 100.0]
四、填充与复制
4.1、tf.pad()数据的填充
- image padding 卷积的时候,为了实现same卷积。
4.2、tf.tile()数据的复制
4.3、tf.tile() VS tf.broadcast_to()
五、张量的限幅
5.1、tf.clip_by_value()限幅
- 例子:通过限幅实现relu函数
5.2、tf.clip_by_norm()根据范数裁剪
- 等比例缩放,只改变模值大小,不改变方向!
5.3、tf.clip_by_global_norm()整体同比例缩放
注意: 梯度爆炸:就是梯度值太大了,每一次前进的步长太长了,导致不停的来回震荡!
梯度消失:就是梯度的值太小了,每一次前进基本没什么变化,导致loss的值长时间不动。
5.4、5.3中实战代码(很重要!)
- 代码如下,
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import datasets, layers, optimizers
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
print(tf.__version__)
(x, y), _ = datasets.mnist.load_data()
x = tf.convert_to_tensor(x, dtype=tf.float32) / 50. #我们限制0~5范围内,比较大这时候有可能出现gradient exploding
y = tf.convert_to_tensor(y)
y = tf.one_hot(y, depth=10)
print("x: ", x.shape, "y: ", y.shape)
train_db = tf.data.Dataset.from_tensor_slices((x,y)).batch(128).repeat(30)
iteration = iter(train_db)
x,y =next(iteration)
print("sample: ", x.shape, y.shape)
def main():
# 784 => 512
w1, b1 = tf.Variable(tf.random.truncated_normal([784, 512], stddev=0.1)), tf.Variable(tf.zeros([512]))
# 512 => 256
w2, b2 = tf.Variable(tf.random.truncated_normal([512, 256], stddev=0.1)), tf.Variable(tf.zeros([256]))
# 256 => 10
w3, b3 = tf.Variable(tf.random.truncated_normal([256, 10], stddev=0.1)), tf.Variable(tf.zeros([10]))
optimizer = optimizers.SGD(lr=0.01)
for step, (x,y) in enumerate(train_db):
# [batch_size, 28, 28]=> [batch_size, 784]
x = tf.reshape(x, (-1, 784))
with tf.GradientTape() as tape:
# layer1
h1 = [email protected] + b1
h1 = tf.nn.relu(h1)
# layer2
h2=tf.nn.relu([email protected] + b2)
# layer3
out = tf.nn.relu([email protected] + b3)
#computer loss
# [batch_size, 10] - [batch_size, 10]
loss = tf.square(out-y)
# [batch_size, 10] => [batch_size]
loss = tf.reduce_sum(loss, axis=1)
# [batch_size] => scalar
loss = tf.reduce_mean(loss)
#compute gradient
grads = tape.gradient(loss, [w1, b1, w2, b2, w3, b3])
print('==before global_norm==')
for g in grads:
print(tf.norm(g)) #梯度的模,没有考虑方向
grads, _ =tf.clip_by_global_norm(grads, 15) #梯度的值等比例缩放,都在15以内。
# print('==after global_norm==')
# for g in grads:
# print(tf.norm(g)) #梯度的模,没有考虑方向
# update w' = w - lr*grad
optimizer.apply_gradients(zip(grads, [w1, b1, w2, b2, w3, b3]))
if step % 100 == 0:
print(step, 'loss: ', float(loss))
if __name__ == '__main__':
main()
- 运行结:1:
- 运行结果2:
- 运行结果3:
六、高阶操作(op)
6.1、tf.where()对tensor操作返回一系列坐标
- 例子:利用tf.where() 和tf.gather_nd()结合。
6.2、tf.scatter_nd()根据坐标有目的的进行更新
- 例子:
6.3、tf.meshgrid()对tensor如果要画一个3D的图片,要生成一个3D的坐标轴
- 如何得到上面这种坐标tensor呢?非常简单看下面的。利用2层的for循环!
- 如何通过GPU加速来完成这样一个目的呢?
6.4、6.3中实战例子
- 中也有一个和 一样的
import tensorflow as tf
import matplotlib.pyplot as plt
def func(x):
"""
:param x: [b,2] 2的前面部分就是x坐标,后面就是y坐标。
:return:
"""
z=tf.math.sin(x[...,0]) + tf.math.sin(x[...,1]) #...表示取所有维度的0,前面所有点的x部分,后者所有点y部分。
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()
- 运行结果如下: