TensorFlow深度学习-第五章

第五章主要是介绍了TensorFlow2的几个高阶操作,包含:

  • 合并与分割

  • 数据统计

  • 张量比较

  • 填充与复制

  • 数据限幅

  • 张量的高级操作

  • 数据加载及预处理

image

合并与分割

合并

将多个张量在一个维度上合并成一个张量。合并有分为两种:拼接concatenate和堆叠stack

  1. 拼接tf.concat(x, axis)

    • 不会产生新的维度

    • 约束条件是:非合并的维度必须是一致的

    • axis指定拼接的轴;x条件是待合并的张量

import tensorflow

a = tf.random.normal([4,8,5])
b = tf.random.normal([6,8,5])
tf.concat([a,b], axis=0)   # 结果是[10,8,5]
  1. 堆叠tf.stack(x, axis)

    • 创建新的维度,新维度的位置是任意的

    • 可以同时堆叠多个张量

    • 进行堆叠的张量维度必须一致

    • axis的用法和tf.expand_dims中相同:

      • ​ 表示当前维度之前插入

      • ​表示当前维度之后插入

    image
import tensorflow

a = tf.random.normal([6,8])
b = tf.random.normal([6,8])
tf.stack([a,b], axis=0)   # 结果是[2,6,8]
tf.stack([a,b], axis=-1)  # 结果是[6,8,-1]

分割

合并的逆操作,将一个张量分成多个张量,通过tf.split(x,axis,num_or_size_splits)实现

  • x:待分割张量
  • axis:分割的维度索引号
  • num_or_size_splits:切割方案
    • num_or_size_splits为单个数值时,如10,表示切割 为 10 份
    • num_or_size_splitsList 时,每个元素表示每份的长度,如[2,4,2,2]表示 切割为 4 份,每份的长度分别为 2,4,2,2
x = tf.random.normal([10,35,8])
result = tf.split(x, axis=0, num_or_size_splits=10)   # 结果是[1,35,8]

result = tf.split(x,axis=0,num_or_size_splits=[4,2,2,2])  # 10=4+2+2+2,第一个维度上进行分割
result[0]  # 查看第一个张量

如果希望在某个维度上全部按照长度为1进行分割,使用tf.unstack,切割长度固定为1。

x = tf.random.normal([10,35,8])
result = tf.unstack(x,axis=0)
len(result)  # 结果为10;shape为[35,8]

数据统计

向量范数Vector norm

通过函数tf.norm(x, ord)

  • x:表示张量
  • norm:指定范数类型

常见的3种范数有:

  • L_1范数:所有元素绝对值之和
    ||x||_1=\sum_{i=1}|x_i|
  • L_2范数:所有元素的平方和,再开根号

||x||_2=\sqrt{\sum_i|x_i|^2}

  • 无穷范数:所有元素绝对值的最大值

max|x_i|

import numpy as np
import tensorflow tf

x=tf.ones([2,3])
tf.norm(x,ord=1)
tf.norm(x,ord=2)
tf.norm(x,ord=np.inf)   # 无穷

最大/最小、均值、和

函数 作用
tf.reduce_max 最大
tf.reduce_min 最小
tf.reduce.mean 均值
tf.reduce_sum

上述的函数都可以指定axis;如果不指定,tf.reduce_.*函数会求解出全局元素的最大、最小、均值、和。

out = tf.random.normal([4,10])
y = tf.constant([1,2,2,0])
y = tf.one_hot(y, depth=10)  # 热编码
loss = keras.losses.mse(loss)
loss = tf.reduce_mean(loss)  # 平均误差

最值的索引号

通过tf.argmax(x, axis)tf.argmin(x, axis)

out = tf.random.normal([2,10])
out = tf.nn.softmax(out, axis=1)  # 通过softmax转成概率
pred = tf.argmax(out, axis=1)

张量比较

tf.equal(a,b)tf.math.equal(a,b)比较两个张量是否相等,返回的是布尔型张量

out = tf.random.normal([100,10])
out = tf.nn.softmax(out, axis=1) # 输出转换为概率
pred = tf.argmax(out, axis=1) # 选取预测值
y = tf.random.uniform([100],dtype=tf.int64,maxval=10)
out = tf.equal(pred,y)   # 返回的是bool值
out = tf.cast(out, dtype=tf.float32)
correct = tf.reduce_sum(out)  # 统计True的个数

填充与复制

填充tf.pad

需要补充的信号开始或者结束处填充足够的特定数值;通过tf.pad(x, axis)实现

a = tf.constant([1,2,3,4,5])
b = tf.constant([9,8,7])
b = tf.pad(b, [[6,0]])  # 填充
tf.stack([a,b], axis=0)

在NLP中,需要加载不同长度的句子,需要设定一个阈值来固定最大的句子长度

total_words = 10000
max_review_len = 80
embedding_len = 100  # 词向量长度
(x_train, y_train), (x_test, y_test) = keras.datasets.imdb.load_data(num_words=total_words)
x_train = keras.preprocessing.sequence.pad_sequences(x_train, maxlen=max_review_len,truncating='post',padding='post')
x_test = keras.preprocessing.sequence.pad_sequences(x_test,maxlen=max_review_len,truncating='post',padding='post')
print(x_train.shape,x_test.shape)

keras.preprocessing.sequence.pad_sequences迅速完成句子的填充与截断工作

复制tf.tile

tf.tile()函数实现长度为1的维度复制的功能;tf.tile() 函数可以在任意维度将数据重复复制多份

x = tf.random.normal([4,32,32,3])
tf.tile(x, [2,3,3,1])

数据限幅

  • tf.maximum()实现下限幅
  • tf.minimum()实现上限幅
  • tf.clip_by_vlaue实现双边限幅
x = tf.range(9)
tf.maximum(x, 2)  # 下
tf.minimum(x, 7)  # 上
tf.clip_by_vlaue(x, 2, 7)

高级操作

tf.gather

根据索引号收集数据tf.gather;对于不规则的索引也非常适合。索引从0开始

x = tf.random.uniform([4,35,8],maxval=100,dtype=tf.int32)
tf.gather(x, [0,1], axis=0)
tf.gather(x, [0,4,2,13,30], axis=1)

假设希望:抽查第 2 个班级的第 2 个同学的所有科目, 第 3 个班级的第 3 个同学的所有科目,第 4 个班级的第 4 个同学的所有科目。那么怎么实现呢?

方法1

分别取出3个,再进行堆叠stack操作

x = tf.random.uniform([4,35,8],maxval=100,dtype=tf.int32)
x[1,1]   # x[2,2]  x[3,3]
tf.stack([x[1,1], x[2,2], x[3,3]])  

tf.gather_nd

指定每次采样点的坐标来实现采样多个点的目的。上面问题的解决

tf.gather_nd(x, [[1,1], [2,2], [3,3]])

tf.boolean_mask

通过掩码的方式来获取数据采样;掩码的长度必须和对应维度的长度一致

x = tf.random.uniform([4,35,8],maxval=100,dtype=tf.int32)
# mask = [True, False, True, False]
tf.boolean_mask(x, mask = [True, False, True, False], axis=0)  # 第一个维度是班级

多维度掩码采样方式

希望采样第 1 个班级的第 1-2 号学生,第 2 个班级的第 2-3 号学生

x = tf.random.uniform([2,3,8],maxval=100,dtype=tf.int32)
tf.gather_nd(x,[[0,0],[0,1],[1,1],[1,2]]) # 多维坐标采集
tf.boolean_mask(x,[[True,True,False],[False,True,True]]) # 多维度掩码采样
image

tf.where

  • 通过tf.where(cond, a, b)操作可以根据cond条件的真假从ab 中读取数据
  • a=b=Nonea,b 参数不指定时,``tf.where会返回cond张量中所有True`的元素的索引坐标
a = tf.ones([3,3]) # 构造 a 为全 1
b = tf.zeros([3,3]) # 构造 b 为全 0
tf.constant([[True,False,False],[False,True,False],[True,True,False]])
tf.where(cond,a,b) # 根据条件从 a,b 中采样

tf.where(cond) # 获取 cond 中为 True 的元素索引

demo

获取张量中的正数及其索引

x = tf.random.normal([3,3]) # 构造 a
mask=x>0 # 比较操作,等同于 tf.equal()

# 方式1
tf.boolean_mask(x,mask)   # 通过掩码的方式获取数据

# 方式2
indices=tf.where(mask) # 提取所有大于 0 的元素索引
tf.gather_nd(x,indices) # 拿到索引后,提取正数的元素值

scatter_nd

通过tf.scatter_nd(indices, updates,shape)实现刷新张量的部分数据。只能在全0张量的白板上进行刷新,可能需要结合其他操作来实现现有张量的数据刷新功能。

  • shape:白板的形状
  • indices:需要刷新数据的索引
  • updates:需要插入进去的新数据
image
indices = tf.constant([[4], [3], [1], [7]])   # 索引位置
updates = tf.constant([4.4, 3.3, 1.1, 7.7])  # 新数据
tf.scatter_nd(indices, updates, [8])  # 长度为8的白板上刷新数据

tf.meshgrid

通过tf.meshgrid方便地生成二维网格采样点坐标,方便可视化

x = tf.linspace(-8.,8,100) # 设置 x 坐标的间隔 
y = tf.linspace(-8.,8,100) # 设置 y 坐标的间隔
x,y = tf.meshgrid(x,y) # 生成网格点,并拆分后返回 
x.shape,y.shape # 打印拆分后的所有点的 x,y 坐标张量 shape

[out]: (TensorShape([100, 100]), TensorShape([100, 100]))

数据加载操作

常用数据

  • Boston Housing 波士顿房价趋势数据集,用于回归模型训练与测试
  • CIFAR10/100 真实图片数据集,用于图片分类任务
  • MNIST/Fashion_MNIST 手写数字图片数据集,用于图片分类任务
  • IMDB 情感分类任务数据集

数据处理过程

在TF中,keras.datasets模块提供经典数据的自动下载、管理、加载等功能

  1. 数据集合对象

tf.data.Dataset

  1. 数据加载

datasets.xxx.load_data()

其中,CIFAR10、MNIST数据集返回的是两个元组,一个保存训练的数据,一个保存的是测试的数据。

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import datasets # 导入经典数据集加载模块 # 加载 MNIST 数据集
(x, y), (x_test, y_test) = datasets.mnist.load_data()  # 自动加载
  1. 数据转成Dataset对象

数据加载进入内存后,需要转换成 Dataset 对象,以利用TensorFlow 提供的各种便捷功能

train_db = tf.data.Dataset.from_tensor_slices((x, y))
  1. 随机散打

通过函数Dataset.shuffle(buffer_size)来实现,buffer_size指定缓冲池的大小,一般设置成一个较大的数字

  1. 批训练

一般在网络的计算过程中会同时计算多个样本,这种方式叫做批训练

  • 样本数量:batch size
train_db = train_db.batch(128)  # 将Dataset设置成批训练方式
  1. 预处理

Dataset对象通过提供map(func)工具函数来实现预处理

# 预处理函数实现在 preprocess 函数中,传入函数引用即可
train_db = train_db.map(preprocess)

def preprocess(x, y): # 自定义的预处理函数
    # 调用此函数时会自动传入 x,y 对象,shape 为[b, 28, 28], [b] # 标准化到 0~1
    x = tf.cast(x, dtype=tf.float32) / 255.
    x = tf.reshape(x, [-1, 28*28])
    y = tf.cast(y, dtype=tf.int32)
    y = tf.one_hot(y, depth=10)
    # 返回的 x,y 将替换传入的 x,y 参数,从而实现数据的预处理功能 
    return x,y
  1. 循环训练
  • step:完成一个batch的数据训练
  • 通过多个step来完成整个训练集的一次迭代
for epoch in range(20): # 训练 Epoch 数
    for step, (x,y) in enumerate(train_db): # 迭代 Step 数
           # training...
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容