Tensorflow2.x版本常用函数

TensorFlow2.x中的常用函数

合并与分割

tf.concat()在特定的维度上进行合并

tf.concat(tensor, axis)
其中 tensors 保存了所有需要合并的张量 List,axis 指定需要合并的维度。

a = tf.random.normal([4,35,8]) 
b = tf.random.normal([6,35,4])
tf.concat([a,b], axis = 0)

Output:
<tf.Tensor: id=13, shape=(10, 35, 8), dtype=float32, numpy = array([[[ 1.95299834e-01, 6.87859178e-01, -5.80048323e-01, ...,1.29430830e+00, 2.56610274e-01, -1.27798581e+00],[ 4.29753691e-01, 9.11329567e-01, -4.47975427e-01, ...,
tf.stack()

tf.stack(tensors, axis)
是一个堆叠类型的合并,在新的维度上进行合并
其中 tensors 保存了所有需要合并的张量 List,axis >= 0时,在axis之前插入维度;axis<0时,在axis的后方插入维度。

a = tf.random.normal([35,8])
b = tf.random.normal([35,8])
tf.stack([a,b],axis=0) 
tf.stack([a,b], axis = -1)

Output:
<tf.Tensor: id=55, shape=(2, 35, 8), dtype=float32, numpy=...>
<tf.Tensor: id=55, shape=(35, 8, 2), dtype=float32, numpy=...>
tf.split()

合并操作的逆过程就是分割,将一个张量分拆为多个张量。
通过 tf.split(x, axis, num_or_size_splits)可以完成张量的分割操作,其中
❑ x:待分割张量
❑ axis:分割的维度索引号 ❑ num_or_size_splits:切割方案。当num_or_size_splits 为单个数值时,如 10,表示切割为 10 份;当 num_or_size_splits 为 List 时,每个元素表示每份的长度,如[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)
len(result)
Output: 10

# 自定义长度的切割
result = tf.split(x,axis=0,num_or_size_splits=[4,2,2,2])
len(result)
Output: 4

数据计算

向量范数(Vector norm)是表征向量“长度”的一种度量方法,在神经网络中,常用来
表示张量的权值大小,梯度大小等。常用的向量范数有:
❑ L1 范数,定义为向量𝒙的所有元素绝对值之和
‖𝒙‖1 = ∑|𝑥𝑖| 𝑖

❑ L2 范数,定义为向量𝒙的所有元素的平方和,再开根号
‖𝒙‖2 = √∑|𝑥𝑖|2 𝑖

❑ ∞ −范数,定义为向量𝒙的所有元素绝对值的最大值:
‖𝒙‖∞ = 𝑚𝑎𝑥𝑖(|𝑥𝑖|)
对于矩阵、张量,同样可以利用向量范数的计算公式,等价于将矩阵、张量拉平成向量后计算。

tf.norm()
In [13]: x = tf.ones([2,2])
tf.norm(x,ord=1) # 计算 L1 范数
Out[13]: <tf.Tensor: id=183, shape=(), dtype=float32, numpy=4.0>
In [14]: tf.norm(x,ord=2) # 计算 L2 范数
Out[14]: <tf.Tensor: id=189, shape=(), dtype=float32, numpy=2.0>
In [15]: import numpy as np
tf.norm(x,ord=np.inf) # 计算∞范数
Out[15]: <tf.Tensor: id=194, shape=(), dtype=float32, numpy=1.0>

数值复制、填充与限制

对于图片数据的高和宽、序列信号的长度,维度长度可能各不相同。为了方便网络的并行计算,需要将不同长度的数据扩张为相同长度,之前我们介绍了通过复制的方式可以增加数据的长度,但是重复复制数据会破坏原有的数据结构,并不适合于此处。通常的做法是,在需要补充长度的信号开始或结束处填充足够数量的特定数值,如 0,使得填充后的长度满足系统要求。那么这种操作就叫做填充(Padding)。
填充操作可以通过 tf.pad(x, paddings)函数实现,paddings 是包含了多个
[𝐿𝑒𝑓𝑡 𝑃𝑎𝑑𝑑𝑖𝑛𝑔, 𝑅𝑖𝑔ℎ𝑡 𝑃𝑎𝑑𝑑𝑖𝑛𝑔]的嵌套方案 List,如[[0,0],[2,1],[1,2]]表示第一个维度不填充,第二个维度左边(起始处)填充两个单元,右边(结束处)填充一个单元,第三个维度左边填充一个单元,右边填充两个单元。考虑上述 2 个句子的例子,需要在第二个句子的第一个维度的右边填充 2 个单元,则 paddings 方案为[[0,2]]:

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

Output:<tf.Tensor: id=3, shape=(6,), dtype=int32, numpy=array([7, 8, 1, 6, 
0, 0])>

#填充后句子张量形状一致,再将这 2 句子 Stack 在一起:
tf.stack([a,b],axis=0) # 合并

Output:<tf.Tensor: id=5, shape=(2, 6), dtype=int32, numpy=
array([[1, 2, 3, 4, 5, 6], [7, 8, 1, 6, 0, 0]])>
tf.tile()

通过 tf.tile 函数可以在任意维度将数据重复复制多份,如 shape 为[4,32,32,3]的数据,复制方案 multiples=[2,3,3,1],即通道数据不复制,高宽方向分别复制 2 份,图片数再复制1 份:

x = tf.random.normal([4,32,32,3])
tf.tile(x,[2,3,3,1]) # 数据复制

<tf.Tensor: id=25, shape=(8, 96, 96, 3), dtype=float32, numpy=...>
tf.maximum() tf.minimum()

在 TensorFlow 中,可以通过 tf.maximum(x, a)实现数据的下限幅:𝑥 ∈ [𝑎, +∞);可以通过 tf.minimum(x, a)实现数据的上限幅:𝑥 ∈ (−∞,𝑎]:

x = tf.range(9)
tf.maximum(x,2) # 下限幅 2

<tf.Tensor: id=48, shape=(9,), dtype=int32, numpy=array([2, 2, 2, 3, 4, 5, 6, 7, 8])>

tf.minimum(x,7) # 上限幅 7

<tf.Tensor: id=41, shape=(9,), dtype=int32, numpy=array([0, 1, 2, 3, 4, 5, 6, 7, 7])>
tf.clip_by_value()

tf.clip_by_value(tensor, 下限,上限)

x = tf.range(9)
tf.clip_by_value(x,2,7) # 限幅为 2~7

<tf.Tensor: id=66, shape=(9,), dtype=int32, numpy=array([2, 2, 2, 3, 4, 5, 6, 7, 7])>

其他高级操作

tf.gather()

tf.gather(tensor, num, axis)
num为想要收集数据的索引号
axis是按照哪个维度来进行检索

x = tf.random.uniform([4,35,8],maxval=100,dtype=tf.int32)
tf.gather(x,[0,1],axis=0) # 在班级维度收集第 1-2 号班级成绩册

<tf.Tensor: id=83, shape=(2, 35, 8), dtype=int32, numpy=array([[[43, 10, 93, 85, 75, 87, 28, 19],[52, 17, 44, 88, 82, 54, 16, 65],[98, 26, 1, 47, 59, 3, 59, 70],…

tf.gather_nd()用法与tf.gather()类似,用于根据多维的坐标来检索数据

tf.boolean_mask()

tf.boolean_mask(x,mask=[True, False,False,True],axis=0)
mask是掩码,该方法根据掩码来进行维度的检索

tf.boolean_mask(x,mask=[True, False,False,True],axis=0)  x = [4, 35, 8]
Out[49]:<tf.Tensor: id=288, shape=(2, 35, 8), dtype=int32, numpy=array([[[43, 10, 93, 85, 75, 87, 28, 19],…
tf.where()

通过 tf.where(cond, a, b)操作可以根据 cond 条件的真假从 a 或 b 中读取数据,条件判定规则如下:
𝑜𝑖 = {𝑎𝑖 𝑐𝑜𝑛𝑑𝑖为𝑇𝑟𝑢𝑒 𝑏𝑖 𝑐𝑜𝑛𝑑𝑖为𝐹𝑎𝑙𝑠𝑒
其中 i 为张量的索引,返回张量大小与 a,b 张量一致,当对应位置中𝑐𝑜𝑛𝑑𝑖为 True,𝑜𝑖位置从𝑎𝑖中复制数据;当对应位置中𝑐𝑜𝑛𝑑𝑖为 False,𝑜𝑖位置从𝑏𝑖中复制数据。考虑从 2 个全 1、 全 0 的 3x3 大小的张量 a,b 中提取数据,其中cond 为 True 的位置从 a 中对应位置提取,cond 为 False 的位置从 b 对应位置提取:

In [53]:
a = tf.ones([3,3]) # 构造 a 为全 1
b = tf.zeros([3,3]) # 构造 b 为全 0
# 构造采样条件
cond = tf.constant([[True,False,False],[False,True,False],[True,True,False]])
tf.where(cond,a,b) # 根据条件从 a,b 中采样
Out[53]:<tf.Tensor: id=384, shape=(3, 3), dtype=float32, numpy=
array([[1., 0., 0.],
       [0., 1., 0.],
       [1., 1., 0.]], dtype=float32)>

通过对于cond的where操作会得到true元素所在的位置

In [55]:tf.where(cond) # 获取 cond 中为 True 的元素索引

Out[55]:<tf.Tensor: id=387, shape=(4, 2), dtype=int64, numpy=
array([[0, 0],
       [1, 1],
       [2, 0],
       [2, 1]], dtype=int64)>
tf.meshgrid()

通过 tf.meshgrid 可以方便地生成二维网格采样点坐标,方便可视化等应用场合。考虑2 个自变量 x,y 的 Sinc 函数表达式为:
𝑧 =𝑠𝑖𝑛(𝑥2 + 𝑦2) 𝑥2 + 𝑦2
如果需要绘制函数在𝑥 ∈ [−8,8],𝑦 ∈ [−8,8]区间的 Sinc 函数的 3D 曲面,如图 所示,则首先需要生成 x,y 的网格点坐标{(𝑥, 𝑦)},这样才能通过 Sinc 函数的表达式计算函数在每个(𝑥, 𝑦)位置的输出值 z。可以通过如下方式生成 1 万个坐标采样点:
在这里插入图片描述

points = []
for x in range(-8,8,100): # 循环生成 x 坐标
	for y in range(-8,8,100): # 循环生成 y 坐标
		z = sinc(x,y) # 计算 sinc 函数值
		points.append([x,y,z]) # 保存采样点

很明显这种方式串行计算效率极低,那么有没有简洁高效地方式生成网格坐标呢?答案是肯定的,tf.meshgrid 函数即可实现。
通过在 x 轴上进行采样 100 个数据点,y 轴上采样 100 个数据点,然后通过
tf.meshgrid(x, y)即可返回这 10000 个数据点的张量数据,shape 为[100,100,2]。为了方便计算,tf.meshgrid 会返回在 axis=2 维度切割后的 2 个张量 a,b,其中张量 a 包含了所有点的 x坐标,b 包含了所有点的 y 坐标,shape 都为[100,100]:

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

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

Sinc 函数在 TensorFlow 中实现如下:

z = tf.sqrt(x**2+y**2) 
z = tf.sin(z)/z # sinc 函数实现

通过 matplotlib 即可绘制出函数在𝑥 ∈ [−8,8], 𝑦 ∈ [−8,8]区间的 3D 曲面

fig = plt.figure()
ax = Axes3D(fig)

根据网格点绘制 sinc 函数 3D 曲面

ax.contour3D(x.numpy(), y.numpy(), z.numpy(), 50)
plt.show()

注:.numpy()方法只用在使用tf.enable_eager_execution()(命令式编程开启)后才有的方法, 否则会有==AttributeError: ‘Tensor’ object has no attribute ‘numpy’==报错

好的,针对您的问题,我可以给您提供一个基于 TensorFlow 2.x 的食物图像识别模型的简单实现思路和步骤。 首先,我们需要准备一组带有标注的食品图像数据集,可以使用现有的公开数据集,例如 Food-101 数据集,该数据集包括 101 类不同类型的食品图像,并且已经经过标注。 接下来,我们可以使用 TensorFlow 2.x 中的 Keras 库来构建食物图像识别模型,具体的步骤如下: 1. 加载数据集并进行预处理。我们可以使用 TensorFlow 中的 ImageDataGenerator 类来进行数据增强和预处理操作,例如对图像进行旋转、缩放、翻转等操作,以增加数据集的多样性和鲁棒性。 2. 定义模型结构。我们可以使用 Keras 中提供的各种卷积神经网络(CNN)模型,例如 VGG、ResNet、Inception 等,也可以自己设计模型结构。根据数据集的大小和复杂度,我们可以选择使用较浅的网络结构,以避免过拟合,或者使用较深的网络结构,以提高模型的准确率。 3. 编译模型。在编译模型时,我们需要指定损失函数、优化器和评估指标。对于分类任务,我们可以选择使用交叉熵损失函数常用的优化器有 Adam、SGD、RMSprop 等,评估指标可以选择准确率、精确率、召回率等。 4. 训练模型。在训练模型时,我们可以根据数据集的大小和计算资源的限制,选择适当的批量大小和训练轮数。可以使用 Keras 中的 fit() 方法来进行模型训练,同时可以指定验证集和回调函数,以监控模型的训练过程和性能。 5. 测试模型。在测试模型时,我们可以使用测试集来评估模型的准确率和其他指标。可以使用 Keras 中的 evaluate() 方法来进行模型测试,并输出测试结果。 以上就是一个基于 TensorFlow 2.x 的食物图像识别模型的简单实现思路和步骤。当然,实际应用中还需要根据具体的场景和需求进行进一步的优化和调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值