《TensorFlow2深度学习》学习笔记(一)

本系列笔记记录了学习TensorFlow2的过程,主要依据git

https://github.com/dragen1860/Deep-Learning-with-TensorFlow-bookgithub

进行学习算法

首先须要明确TensorFlow 是一个面向于深度学习算法的科学计算库,内部数据保存在张量(Tensor)对象上,全部的运算操做(Operation, OP)也都是基于张量对象进行。数组

数据类型网络

Tensorflow中的基本数据类型有三种,包括数值型、字符串型和布尔型。框架

数值型】又包括:(在 TensorFlow 中间,为了表达方便,通常把标量、向量、矩阵也统称为张量,不做区分,须要根据张量的维度数和形状自行判断。 )dom

1.Scalar(标量)函数

维度数(Dimension,也叫秩)为 0,shape 为[] 工具

a = tf.constant(1.2) # 建立标量 学习

2.Vector(向量)

维度数为 1,长度不定,shape 为[𝑛] 

x = tf.constant([1,2.,3.3]) 

3.Matrix(矩阵)

维度数为 2,每一个维度上的长度不定,shape 为[𝑛,𝑚] (n 行 m 列)

b = tf.constant([[1,2],[3,4]]) 

4.Tensor(张量)

维度数dim > 2的数组统称为张量。

c = tf.constant([[[1,2],[3,4]],[[5,6],[7,8]]]) (三维张量定义)

字符串】类型:

a = tf.constant('Hello, Deep Learning.') 

在 tf.strings 模块中,提供了常见的字符串型的工具函数,如拼接 join(),长度 length(),切分 split()等等,如:tf.strings.lower(a) 

布尔】类型:

 a = tf.constant(True)

数值精度

经常使用的精度类型有 tf.int16, tf.int32, tf.int64, tf.float16, tf.float32, tf.float64,其中 tf.float64 即为 tf.double

对于大部分深度学习算法,通常使用 tf.int32, tf.float32 可知足运算精度要求,部分对精度要求较高的算法,如强化学习,能够选择使用 tf.int64, tf.float64 精度保存张量。

经过访问张量的 dtype 成员属性能够判断张量的保存精度: a = tf.constant(np.pi, dtype=tf.float16) ,print(a.dtype

转换精度 :a = tf.cast(a,tf.float32) 

布尔型与整形之间相互转换也是合法的,是比较常见的操做,通常默认 0 表示 False,1 表示 True,在 TensorFlow 中,将非 0 数字都视为 True

待优化张量 

为了区分须要计算梯度信息的张量与不须要计算梯度信息的张量,TensorFlow 增长了 一种专门的数据类型来支持梯度信息的记录:tf.Variable。tf.Variable 类型在普通的张量类 型基础上添加了 name,trainable 等属性来支持计算图的构建。因为梯度运算会消耗大量的 计算资源,并且会自动更新相关参数,对于不须要的优化的张量,如神经网络的输入 X, 不须要经过 tf.Variable 封装;相反,对于须要计算梯度并优化的张量,如神经网络层的W 和𝒃,须要经过 tf.Variable 包裹以便 TensorFlow 跟踪相关梯度信息。 经过 tf.Variable()函数能够将普通张量转换为待优化张量。

a = tf.constant([-1, 0, 1, 2])
aa = tf.Variable(a)
aa.name, aa.trainable

'''''''''''''''''''''''''''''''
Out[20]:
('Variable:0', True)

'''''''''''''''''''''''''''''''

建立 Variable 对象是默认启用优化标志,能够设置 trainable=False 来设置张量不须要优化。 

除了经过普通张量方式建立 Variable,也能够直接建立: a = tf.Variable([[1,2],[3,4]]) 

待优化张量可看作普通张量的特殊类型,普通张量也能够经过 GradientTape.watch()方法临 时加入跟踪梯度信息的列表。 

建立张量

 1.从 Numpy, List 对象建立 

经过 tf.convert_to_tensor 能够建立新 Tensor,并将保存在 Python List 对象或者 Numpy Array 对象中的数据导入到新 Tensor 中: tf.convert_to_tensor([1,2.])  |  tf.convert_to_tensor(np.array([[1,2.],[3,4]])) 

须要注意的是,Numpy 中浮点数数组默认使用 64-Bit 精度保存数据,转换到 Tensor 类型时 精度为 tf.float64,能够在须要的时候转换为 tf.float32 类型。 

tf.constant()和 tf.convert_to_tensor()都可以自动的把 Numpy 数组或者 Python List 数据类型转化为 Tensor 类型

2. 建立全 0,全 1 张量 

考虑线性变换 𝒚 = 𝑊𝒙 +𝒃,将权值矩阵 W 初始化为全 1 矩阵,偏置 b 初始化为全 0 向量,此时线性变 化层输出𝒚 = 𝒙,是一种比较好的层初始化状态。经过 tf.zeros()和 tf.ones()便可建立任意形 状全 0 或全 1 的张量。例如,建立为 0 和为 1 的标量张量:
 tf.zeros([2,2])   |    tf.ones([3,2]) 

经过 tf.zeros_like, tf.ones_like 能够方便地新建与某个张量 shape 一致,内容全 0 或全 1 的张量  :  tf.zeros_like(a) 

tf.*_like 是一个便捷函数,能够经过 tf.zeros(a.shape)等方式实现

3.建立自定义数值张量 

tf.fill([2,2], 99) 

4.建立已知分布的张量 

正态分布(Normal Distribution,或 Gaussian Distribution)和均匀分布(Uniform Distribution)是最多见的分布之一,建立采样自这 2 种分布的张量很是有用,好比在卷积神经网络中,卷积核张量 W 初始化为正态分布有利于网络的训练;在对抗生成网络中,隐藏变量 z 通常采样自均匀分布。 

经过 tf.random.normal(shape, mean=0.0, stddev=1.0)能够建立形状为 shape,均值为 mean,标准差为 stddev 的正态分布𝒩(𝑚𝑒𝑎𝑛,𝑠𝑡𝑑𝑑𝑒𝑣2)。

经过 tf.random.uniform(shape, minval=0, maxval=None, dtype=tf.float32)能够建立采样自 [𝑚𝑖𝑛𝑣𝑎𝑙,𝑚𝑎𝑥𝑣𝑎𝑙]区间的均匀分布的张量。

5. 建立序列 

 tf.range(start, limit, delta=1)能够建立[𝑠𝑡𝑎𝑟𝑡,𝑙𝑖𝑚𝑖𝑡),步长为 delta 的序列,不包含 limit 自己:tf.range(1,10,delta=2) 

张量的典型应用 

1.标量

在 TensorFlow 中,标量最容易理解,它就是一个简单的数字,维度数为 0,shape 为 []。标量的典型用途之一是偏差值的表示、各类测量指标的表示,好比准确度(Accuracy, acc),精度(Precision)和召回率(Recall)等。

out = tf.random.uniform([4,10]) #随机模拟网络输出

 

y = tf.constant([2,3,2,0]) # 随机构造样本真实标签

y = tf.one_hot(y, depth=10) # one-hot 编码

loss = tf.keras.losses.mse(y, out) # 计算每一个样本的 MSE

loss = tf.reduce_mean(loss) # 平均 MSE

print(loss)

2.向量 

向量是一种很是常见的数据载体,如在全链接层和卷积神经网络层中,偏置张量𝒃就 使用向量来表示。如图 所示,每一个全链接层的输出节点都添加了一个偏置值,把全部 输出节点的偏置表示成向量形式:𝒃 = [𝑏1,𝑏2]𝑇。 

 

# z=wx,模拟得到激活函数的输入 z

z = tf.random.normal([4,2])

b = tf.zeros([2]) # 模拟偏置向量

z = z + b # 累加偏置(到这里 shape 为[4,2]的𝒛和 shape 为[2]的𝒃张量能够直接相加,这是为何呢?让咱们在 Broadcasting 一节为你们揭秘)

 

经过高层接口类 Dense()方式建立的网络层,张量 W 和𝒃存储在类的内部,由类自动创 建并管理。能够经过全链接层的 bias 成员变量查看偏置变量𝒃

fc = tf.keras.layers.Dense(3)# 建立一层 Wx+b,输出节点为 3   (原书表述为:fc = layers.Dense(3) # 建立一层 Wx+b,输出节点为 3,此处前提是:)

fc.build(input_shape=(2,4))# 经过 build 函数建立 W,b 张量,输入节点为 4 

fc.bias # 查看偏置

3.矩阵

矩阵也是很是常见的张量类型,好比全链接层的批量输入𝑋 = [𝑏,𝑑𝑖𝑛],其中𝑏表示输入样本的个数,即 batch size,𝑑𝑖𝑛表示输入特征的长度。好比特征长度为 4,一共包含 2 个样本的输入能够表示为矩阵: x = tf.random.normal([2,4])

能够经过全链接层的 kernel 成员名查看其权值矩阵 W: 

fc = layers.Dense(3) # 定义全链接层的输出节点为 3

fc.build(input_shape=(2,4)) # 定义全链接层的输入节点为 4

fc.kernel

4.三维张量 

三维的张量一个典型应用是表示序列信号,它的格式是 𝑋 = [𝑏,𝑠𝑒𝑞𝑢𝑒𝑛𝑐𝑒 𝑙𝑒𝑛,𝑓𝑒𝑎𝑡𝑢𝑟𝑒 𝑙𝑒𝑛] 其中𝑏表示序列信号的数量,sequence len 表示序列信号在时间维度上的采样点数,feature len 表示每一个点的特征长度。 

为了可以方便字符串被神经网络处理,通常将单词经过嵌入层(Embedding Layer)编码为固定长度的向量,好比“a”编码为某个长度 3 的向量,那么 2 个 等长(单词数为 5)的句子序列能够表示为 shape 为[2,5,3]的 3 维张量,其中 2 表示句子个数,5 表示单词数量,3 表示单词向量的长度。

5.四维张量 

咱们这里只讨论 3/4 维张量,大于 4 维的张量通常应用的比较少,如在元学习(meta learning)中会采用 5 维的张量表示方法,理解方法与 3/4 维张量相似。

4 维张量在卷积神经网络中应用的很是普遍,它用于保存特征图(Feature maps)数据, 格式通常定义为

[𝑏,ℎ,w,𝑐]

其中𝑏表示输入的数量,h/w分布表示特征图的高宽,𝑐表示特征图的通道数,部分深度学习框架也会使用[𝑏,𝑐,ℎ, ]格式的特征图张量,例如 PyTorch。图片数据是特征图的一种, 对于含有 RGB 3 个通道的彩色图片,每张图片包含了 h 行 w 列像素点,每一个点须要 3 个数 值表示 RGB 通道的颜色强度,所以一张图片能够表示为[h,w,3]。