python中tensor与variable_NLP实战篇之tf2中tensor、variable、gradient、ops
本文是基于tensorflow2.2.0版本,介绍了tf中变量、张量的概念,tf中梯度的计算方式和tensor相关的操作。
实战系列篇章中主要会分享,解决实际问题时的过程、遇到的问题或者使用的工具等等。如问题分解、bug排查、模型部署等等。相关代码实现开源在:https://github.com/wellinxu/nlp_store ,更多内容关注知乎专栏(或微信公众号):NLP杂货铺。
变量
张量张量的创建
形状
索引
其他张量非矩阵张量
稀疏张量
梯度计算GradientTape的参数与方法
Gradient tapes
模型中的梯度
operations数组操作
检查操作
裁剪操作
流程控制操作
函数操作
数学操作
其他操作
参考
变量
TensorFlow2中可以使用tf.Variable来创建变量,变量与张量(tensor)很接近,拥有tensor的很多属性,以及操作(加减乘除等)。但张量是不可改变的,而变量是可以重新赋值的。变量的创建以及再赋值方法如下:
import tensorflow as tf
my_tensor = tf.constant([1.0, 2.0])
my_variable = tf.Variable(my_tensor) # 数值型
bool_variable = tf.Variable([False, False, False, True]) # bool型
complex_variable = tf.Variable([5 + 4j, 6 + 1j]) # 复数型
print(my_variable) #
print(bool_variable) #
print(complex_variable) #
# 再赋值
my_variable.assign([2.0, 3.0])
print(my_variable) #
张量
tensor(张量)是具有统一类型的多位数组,跟Python中数字、字符串类似,张量是不可改变的,只能创建一个新张量而不能更新张量的值(变量则可以更新)。
张量的创建
tensor可以直接从各种类型的数组(list或numpy)来创建,也能转成numpy数据。
# 创建
my_tensor1 = tf.constant([1.2, 4.5])
my_numpy = my_tensor1.numpy()
my_tensor2 = tf.convert_to_tensor(my_numpy)
print(my_tensor1) # tf.Tensor([1.2 4.5], shape=(2,), dtype=float32)
print(my_numpy) # [1.2 4.5]
print(my_tensor2) # tf.Tensor([1.2 4.5], shape=(2,), dtype=float32)
形状
tensor形状相关的有这么几个概念:形状:shape,tesor中每个维度的长度
秩,rank,tensor维度的个数,标量的秩是0,向量是1,矩阵是2
维度,axis/dimension
大小,size,tensor中所有元素的个数
下面代码中展示了一个4维tensor的几个概念:
rank_4_tensor = tf.zeros([3, 2, 4, 5])
print("Type of every element:", rank_4_tensor.dtype) # Type of every element:
print("Number of dimensions:", rank_4_tensor.ndim) # Number of dimensions: 4
print("Shape of tensor:", rank_4_tensor.shape) # Shape of tensor: (3, 2, 4, 5)
print("Elements along axis 0 of tensor:", rank_4_tensor.shape[0]) # Elements along axis 0 of tensor: 3
print("Elements along the last axis of tensor:", rank_4_tensor.shape[-1]) # Elements along the last axis of tensor: 5
print("Total number of elements (3*2*4*5): ", tf.size(rank_4_tensor).numpy()) # Total number of elements (3*2*4*5): 120
tf中可以使用reshape或者transpose操作来改变形状,reshape操作非常快捷并且消耗资源很小,下面代码演示了这两种操作的简单使用:
# 改变形状
new_shape_tensor = tf.reshape(rank_4_tensor, (3, 2, -1))
print(new_shape_tensor.shape) # (3, 2, 20)
new_shape_tensor = tf.transpose(rank_4_tensor, [0, 1, 3, 2])
print(new_shape_tensor.shape) # (3, 2, 5, 4)
索引
TensorFlow遵循标准的python索引规则,类似于在python中索引列表或字符串,以及numpy索引的基本规则。索引开始于 0
负索引从末尾开始倒数
冒号:用于切片start:stop:step
# 索引
rank_2_tensor = tf.constant([[1, 2], [3, 4], [5, 6]])
print("Second row:", rank_2_tensor[1, :].numpy()) # Second row: [3 4]
print("Second column:", rank_2_tensor[:, 1].numpy()) # Second column: [2 4 6]
print("Last row:", rank_2_tensor[-1, :].numpy()) # Last row: [5 6]
print("First item in last column:", rank_2_tensor[0, -1].numpy()) # First item in last column: 2
print("Skip the first row:")
print(rank_2_tensor[1:, :].numpy(), "\n") # [[3 4] [5 6]]
其他张量
tf中除了提供了标准的张量之外,还提供了一些其他张量,比如非矩阵张量和系数矩阵张量。下面就简单介绍了这两种张量的定义方式。
非矩阵张量
# 非矩阵张量
ragged_list = [
[0, 1, 2, 3],
[4, 5],
[6, 7, 8],
[9]
]
ragged_tensor = tf.ragged.constant(ragged_list)
print(ragged_tensor) #
print(ragged_tensor.shape) # (4, None)
稀疏张量
# 稀疏张量
sparse_tensor = tf.sparse.SparseTensor(indices=[[0, 0], [1, 2]],values=[1, 2],dense_shape=[3, 4])
print(sparse_tensor)
# SparseTensor(indices=tf.Tensor( [[0 0] [1 2]], shape = (2, 2), dtype = int64), values = tf.Tensor([1 2], shape=(2,),dtype=int32), dense_shape = tf.Tensor([3 4],shape=(2,),dtype=int64))
# 转为稠密矩阵
print(tf.sparse.to_dense(sparse_tensor))
# tf.Tensor([[1 0 0 0] [0 0 2 0] [0 0 0 0]], shape = (3, 4), dtype = int32)
梯度计算
为了能够进行自动微分计算,tf需要记录在前向过程中都有哪些操作,然后在后向过程中,tf以相反的顺序遍历操作列表来计算梯度。
GradientTape的参数与方法persistent:控制tape的gradient()方法是否可以多次被调用,默认是False
watch_accessed_variables:控制tape是否自动记录可训练的变量,默认是True
watch():手动添加被tape记录的变量(tensor)
watched_variables():按照构造顺序返回tape中被记录的变量
gradient():计算被tape记录的操作的梯度
Gradient tapes
tf中提供了tf.GradientTape接口来进行自动微分计算,如下面代码所示,先将前向计算的操作过程记录在tape上,然后就可以用tape进行梯度计算。
w = tf.Variable(tf.random.normal((3, 2)), name='w')
b = tf.Variable(tf.zeros(2, dtype=tf.float32), name='b')
x = [[1., 2., 3.]]
# 记录前向计算过程,保留在tape上
with tf.GradientTape() as tape:
y = tf.matmul(x, w) + b
loss = tf.reduce_mean(y ** 2)
# 计算梯度
[dl_dw, dl_db] = tape.gradient(loss, [w, b])
print(w.shape) # (3, 2)
print(dl_dw.shape) # (3, 2)
模型中的梯度
在很多时候,我们需要计算模型中可训练变量的梯度。因为tf.Module的子类都会将所有变量放在Module.trainable_variables中,所以我们可以比较方便的计算模型中变量的梯度。
# 模型中的梯度计算
layer = tf.keras.layers.Dense(2, activation='relu')
x = tf.constant([[1., 2., 3.]])
with tf.GradientTape() as tape:
y = layer(x)
loss = tf.reduce_mean(y ** 2)
# 计算层(模型)中的所有变量的梯度
grad = tape.gradient(loss, layer.trainable_variables)
for var, g in zip(layer.trainable_variables, grad):
# dense/kernel:0, shape: (3, 2)
# dense/bias:0, shape: (2,)
print(f'{var.name}, shape:{g.shape}')
operations
本小节简单列举了tf中可以对tensor进行的一些操作,知道某些操作的存在,可以较快地实现某些模型、结构,当然具体使用过程中,还需要仔细研究各api的使用方式、适用范围。
数组操作boolean_mask:根据布尔型mask返回一个新的tensor
concat:根据某个维度,横向拼接多个tensor
edit_distance:计算序列间的编辑距离
expand_dims:在指定的维度上增加一维
fill:使用一个标量填充来创建一个tensor
gather:根据索引获取tensor值
identity:复制一个跟输入形状、内容一样的tensor
meshgrid:将1xN维tensor广播成NxN维tensor
one_hot:将索引变成one-hot值
ones:生成全1tensor
ones_like:生成一个跟输入形状一样的全1tensor
pad:pad一个tensor
rank:获取tensor的秩
repeat:重复输入的tensor
reshape:改变tensor形状
sequence_mask:生成一个mask tensor
shape:获取tensor的形状
size:获取tensor的大小
slice:从tensor中获取一个切片
split:切分tensor
squeeze:去除大小为1的维度
stack:根据某个维度,纵向拼接多个tensor
tile:通过平铺一个给定的tensor来创建一个新tensor
transpose:对tensor进行转置
unique:从向量(1维tensor)中找出唯一值
where:判断tensor中哪些元素符合条件
zeros:生成全0的tensor
zeros_like:生成跟输入形状一样的全0tensor
检查操作assert_equal:判断两个tensor的元素是否相等
assert_greater:判断第一个tensor的元素是否大于第二个
assert_less:判断第一个tensor的元素是否小于第二个
assert_rank:判断tensor的秩
裁剪操作clip_by_norm:根据范数裁剪tensor的值
clip_by_global_norm:根据范数裁剪多个tensor的值
clip_by_value:根据最大最小值限制裁剪tensor的值
流程控制操作Assert:验证给定的条件是否正确
case:创建一个case操作
cond:类似三元运算
group:创建一个集合多个操作的操作
switch_case:创建一个switch case操作
tuple:创建tensor元组
while_loop:while循环
函数操作foldl:在tensor第0维上进行函数操作,类似reduce
foldr:flodl的逆序,即从最后一个元素到第一个元素
scan:扫描tensor第0维上的数据进行函数操作
map_fn:在tensor第0维上进行函数操作,类似map
数学操作acos:acos三角函数计算
acosh:acosh三角函数计算
add:加法计算
asin:asin三角函数计算
asinh:asinh三角函数计算
atan:atan三角函数计算
atanh:atanh三角函数计算
cos:cos三角函数计算
cosh:cosh三角函数计算
floor:去尾法近似计算
greater:大于运算
greater_equal:大于等于运算
less:小于运算
less_equal:小于等于运算
linspace:根据开始、结束、间隔生成值
logical_and:逻辑与运算
logical_not:逻辑非运算
logical_or:逻辑或运算
maximum:计算最大值
minimum:计算最小值
negative:计算负tensor值
realdiv:除法计算
sin:sin三角函数计算
sinh:sinh三角函数计算
square:平方计算
tan:tan三角函数计算
tanh:tanh三角函数计算
truncatediv:除法计算
truncatemod:取余计算
eig:矩阵特征分解计算
eigvals:矩阵特征值计算
eye:构造单位矩阵
norm:计算tensor的范数
abs:绝对值计算
add_n:加法计算,多个tensor
argmax:获取最大值索引
argmin:获取最小值索引
cast:数据类型转换
complex:构建复数
cumsum:累计和计算
divide:除法计算
equal:等于运算
exp:指数计算
matmul:点积运算
multiply:乘积计算
not_equal:不等于运算
pow:幂运算
range:创建数字序列
reduce_all:进行逻辑与的reduce操作
reduce_any:进行逻辑或的reduce操作
reduce_logsumexp:进行 指数后求和在对数化 的操作
reduce_max:计算某个维度的最大值
reduce_mean:计算某个维度的平均值
reduce_min:计算某个维度的最小值
reduce_prod:计算某个维度的连乘
reduce_sum:计算某个维度的和
round:四舍五入近似计算
scalar_mul:标量与tensor相乘
sigmoid:sigmoid计算
sign:sign计算
sqrt:开方计算
tensordot:根据指定维度和外积做张量搜索
truediv:除法计算
argsort:获取排序后的索引值
sort:排序操作
einsum:爱因斯坦求和约定,强大的张量处理方式
其他操作print:日志打印
py_function:将Python函数包装成tf操作
numpy_function:将numpy函数包装成tf操作
as_string:转为string
timestamp:以秒为单位的时间
参考
python中tensor与variable_NLP实战篇之tf2中tensor、variable、gradient、ops相关推荐
- dotNET:怎样处理程序中的异常(实战篇)?
在上篇 <dotNET:怎样处理程序中的异常(理论篇)> 中讲了一些程序中出现异常怎样处理的理论知识,本文将以代码的方式来进行实践. 环境 dotNET Core:3.1 工具:Rider ...
- selenium之 chromedriver与chrome版本映射表_NLP实战篇之tf2训练与评估
本文是基于tensorflow2.2.0版本,介绍了模型的训练与评估.主要介绍了tf.keras的内置训练过程,包括compile.fit,其中compile中包含优化器.loss与metrics的使 ...
- android在主程序中调用图片,009android初级篇之APP中使用系统相机相册等集成应用...
009android初级篇之APP中使用系统相机相册等集成应用 android应用中使用相机功能,大致有两种方式实现: 直接调用系统内部的相机程序,显示的也是系统预设的界面(简单,只有简单的拍照功能) ...
- 基类成员的public访问权限在派生类中变为_第17篇:C++继承中虚表的内存布局
我们已经表明,非虚类的对象实例不包含虚指针,编译器在编译阶段也没有为非虚类没有构建虚表.而本篇我们会从简单的单继承链分析虚类中虚表构造过程和内存布局.这一切假定你有如下基础 对gdb调试器使用有一个比 ...
- mysql的char在java中表示为_Java学习篇之-Mysql中varchar门类总结_mysql
java学习篇之---mysql中varchar类型总结 Mysql中varchar类型总结 今天新做一个项目,需要自己进行数据库设计,发现自己对varchar的用法还不是很熟悉,所以查阅资料总结若下 ...
- python爬虫简易到进阶实战篇——(1)
python简易实战(1)--猫眼top100 第一篇文章介绍python基本环境搭建,简单实战,希望我们一同进步. 首先,对于初学者,python相比于c.java语言较容易入手,而写爬虫更是简单了 ...
- Python描述数据结构之链表实战篇
文章目录 前言 1. LeetCode21: 合并两个有序链表 2. LeetCode237: 删除链表中的节点 3. 剑指 Offer 18: 删除链表的节点 4. LeetCode234: 回文链 ...
- AngularJS in Action读书笔记5(实战篇)——在directive中引入D3饼状图显示
前言: "宁肯像种子一样等待 也不愿像疲惫的陀螺 旋转得那样勉强" 这是前几天在查资料无意间看到的一位园友的签名,看完后又读了两遍,觉得很有味道.后来一寻根究底才知这是出资大诗 ...
- Python描述数据结构之图实战篇
文章 前言 1. LeetCode684:冗余连接 2. LeetCode841:钥匙和房间 3. LeetCode1387:将整数按权重排序 4. LeetCode997:找到小镇的法官 前言 ...
最新文章
- Ajax实现无刷新树
- 安卓手机格式化怎么弄_安卓手机无法启动如何进行格式化
- 路由器的转发能力PPS
- 用Javascript获取页面元素的位置
- 编译原理【实验1——扫描器的设计与实现】
- 问题 D: 二叉树求高度
- AQS(AbstractQuenedSynchronizer)详解
- python3 面向对象编程 下载_Python3(7) Python 面向对象编程
- 你的简历已经被机器人筛选了
- Java并发编程笔记—摘抄—基础知识
- 51NOD 1244 莫比乌斯函数之和
- 10. Zend_Loader
- SMOTE过采样算法
- Hdu 4093 ( Xavier is Learning to Count ) BZOJ2498 FFT+容斥原理
- 计算机组成原理/计算机硬件基础第五章:存储器
- Material Theme UI 插件的下载安装与使用,免费版Material Theme UI 插件
- 人脸识别嵌入式Linux芯片瑞芯微RV1109参数介绍
- 未来科技 从零到一「真格星球 · 前沿科技创业营」探访加速科技
- MATLAB基础—算数运算符
- 智能穿戴开发需要什么技术_可穿戴技术–可穿戴应用开发技术