tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

tensorFlow2.0的高阶操作!

一、张量的合并和分割(merge, split)

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

1.1、tf.concat()拼接操作

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
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])
  • 例子:
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

1.2、tf.stack()创建一个维度

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

1.3、维度不匹配情况

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

1.4、tf.unstack()对应tf.stack()

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

二、数理统计

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

2.1、tf.norm()张量的范数(向量范数)

  • 张量的范数包括向量范数和矩阵范数,这里只讨论向量范数
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

2.2、tf.reduce_min/max/mean():求均值,最大值,最小值

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

2.3、tf.argmax/argmin():最大值的位置

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

2.4、tf.equal(a,b):逐个判断a,b中元素是否相等

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
  • accuracy的例子!
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

2.5、tf.unique():去除重复的元素

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

三、张量排序

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

3.1、tf.sort()排序,tf.argsort()排序得到元素index

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

注意: tf.random.shuffle():对元素进行随机的打乱!

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

3.2、top-k之tf.math.top_k()最大的前k个元素

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

3.3、top-k accuracy

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

注意: 这就是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
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

3.4、top-k accuracy实战例子!

  • 完整例子:
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
  • 代码演示:
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]

四、填充与复制

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

4.1、tf.pad()数据的填充

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
  • image padding 卷积的时候,为了实现same卷积。
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

4.2、tf.tile()数据的复制

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

4.3、tf.tile() VS tf.broadcast_to()

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

五、张量的限幅

5.1、tf.clip_by_value()限幅

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
  • 例子:通过限幅实现relu函数
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

5.2、tf.clip_by_norm()根据范数裁剪

  • 等比例缩放,只改变模值大小,不改变方向!
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

5.3、tf.clip_by_global_norm()整体同比例缩放

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

注意: 梯度爆炸:就是梯度值太大了,每一次前进的步长太长了,导致不停的来回震荡!
梯度消失:就是梯度的值太小了,每一次前进基本没什么变化,导致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:
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
  • 运行结果2:
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
  • 运行结果3:
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

六、高阶操作(op)

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

6.1、tf.where()对tensor操作返回一系列坐标

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
  • 例子:利用tf.where() 和tf.gather_nd()结合。
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

6.2、tf.scatter_nd()根据坐标有目的的进行更新

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
  • 例子:
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

6.3、tf.meshgrid()对tensor如果要画一个3D的图片,要生成一个3D的坐标轴

tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
  • 如何得到上面这种坐标tensor呢?非常简单看下面的。利用2层的for循环!
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
  • 如何通过GPU加速来完成这样一个目的呢?
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!

6.4、6.3中实战例子

  • tensorflowtensorflow 中也有一个和 numpynumpy 一样的 linspacelinspace
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
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()
  • 运行结果如下:
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!
tensorflow2.0笔记8:tensorFlow2.0的高阶操作!