MIT-6.S191 2020机器学习公开课Part1-Tensorflow用法梳理总结

- 说在前面

由于课程需要,最近开始学习MIT机器学习公开课,想一边学习一边总结,同时或许可以帮助到有需要的人hh,如果有不对的地方欢迎批评指正,一起进步!

- MIT.6.S191 2020课程简介

很牛的机器学习课程 !!! 都给我捧!!!
上来一段机器学习制作的奥巴马演讲视频给我看懵了,真的极致炫酷cool!在这里插入图片描述
课程链接:http://introtodeeplearning.com/
课程讲义和练习github链接:https://github.com/aamini/introtodeeplearning/tree/master/lab1
本博客参考博客:https://blog.csdn.net/dcrmg/article/details/79017146/

- TensorFlow是什么

TensorFlow可以看作处理多维数组的数据结构,提供了一种将向量和矩阵推广到更高维度的方法。tensor(张量)意味着N维数组,flow(流)意味着基于数据流图的计算,所以tensorflow字面理解为张量从流图的一端流动到另一端的计算过程。用于处理机器学习中图像、语音等高纬度数据,表示为一个高纬数组。

- TensorFlow属性

结合第5项中多维Tensor的定义,理解Tensor(张量)的维度(rank)和形状(shape)。(本部分源自参考)
. Tips: 维度(rank)要看张量的最左边有多少个左中括号,有n个,则这个张量就是n维张量。
源自参考博客
. Tips:张量的形状以 [D0, D1, … Dn-1] 的形式表示,D0 到Dn 是任意的正整数。如形状[3,4]表示第一维有3个元素,第二维有4个元素,[3,4]表示一个3行4列的矩阵。形状的第一个元素要看张量最外边的中括号中有几个元素,形状的第二个元素要看张量中最左边的第二个中括号中有几个被逗号隔开的元素…以此类推。
在这里插入图片描述

- Tensor数据类型 (参考)

在这里插入图片描述
在这里插入图片描述

- 定义多维Tensor

  • 0-d Tensor 在这里插入图片描述
    使用 tf.constant() 函数定义张量,第一个参数是必要的value,第二个是其类型(不必要)。tf.rank()获得括号中参数(张量)的维度,numpy()函数此处尝试运行后发现去掉也是一样的,留疑,后填坑。
    如下代码测试了一番,猜想numpy()函数用于输出Tensor的value?
    在这里插入图片描述

  • 1-d Tensor
    向量和列表(vector & list)可以用于创建一维张量。
    在这里插入图片描述
    输出为1+类型

  • 2-d+ Tensor
    下面考虑高纬张量,未来图像处理和计算机视觉实验中将会使用4-d Tensors。首先考虑二维:在这里插入图片描述
    此处assert断言语句,当其后条件为False时,执行,引起并输出AssertionError。例如本代码段中第一个assert行,当matrix不是一个Tensor类型时,将输出Assertion: matrix must be a tf Tensor object。下面考虑4维:
    在这里插入图片描述
    tolist() 函数将每一维度的形状放到一个list中。一个张量的形状(shape)提供了每个张量维中的元素个数。这种形状非常有用,将经常使用它。用 tf.zeros 函数初始化10256256*3的张量,可以理解为10 个图像,其中每个图像是256x256 RGB。
    也可以使用切片来访问高秩张量中的子张量:
    在这里插入图片描述
    在这里插入图片描述
    - matrix[1] , 与 matrix[1,:,:] 相同,获取第一维度中序号为1的部分。
    - matrix[:,2] , 与 matrix[:,2,:] 相同,获取第二维度中序号为2的部分
    - matrix[:,:,1] ,获取第三维度中序号为1的部分
    - matrix[a,b,c] 获取 (a,b,c) 位置的元素

-Tensor计算

在TensorFlow中,一种方便的考虑和可视化计算的方法是使用图形。我们可以用张量来定义这个图,张量包含数据,数学运算按一定的顺序作用于这些张量。

1. Tensor加法
在这里插入图片描述
在这里插入图片描述
由此创建了一个由运算组成的计算图,它执行了这些运算并返回了结果。TensorFlow重写了数学运算符。如果用c1.numpy() 就会输出76了。
2. Tensor 其他运算 在这里插入图片描述
在这里插入图片描述
没有输出形状(shape),因为此处运算的Tensor为一个单独的常量。

-TensorFlow中的神经网络

TensorFlow使用了一个名为Keras的高级API,它为构建和训练深度学习模型提供了一个强大的、直观的框架。首先考虑一个简单的感知器的例子,它是由一个稠密层定义的:
在这里插入图片描述
其中W为权重矩阵,b是偏差(bias),x为输入,z=Wx+b作用在sigmoid函数上输出为y。可以进一步使公式可视化:
在这里插入图片描述
1. 使用Layer定义神经网络
张量可以流经称为层(layer)的抽象类型——神经网络的构建块。层实现常见的神经网络操作,并用于更新权重、计算损耗(losses)和定义层间连接。我们将首先定义一个层来实现上面定义的简单感知器。
在这里插入图片描述
定义一个类代表简单层(Layer),其必须继承tf.keras.layers.Layer。

  • 初始化函数(__init __):参数为输出节点个数,并调用父类的初始化函数(Python3中可以使用super()代替super(class,self) )。
  • build函数:定义权重矩阵(W)和偏差矩阵(b)。通过父类的self.add_weight()函数来初始化(应该是随机指派?)。本例使用矩阵方便理解,参数input_shape为输入数据的形状,因需将输入x和权重矩阵相乘,input_shape的最后一个元素即为权重矩阵第一维度的形状(结合矩阵相乘时两矩阵行列向量个数关系理解),同时n_output_nodes为权重矩阵和偏差矩阵的列数。
  • call函数:计算。
    接着随机假设一些数字进行测试:
    在这里插入图片描述
    当在代码中使用了随机数,但是希望代码在不同时间或者不同的机器上运行能够得到相同的随机数,以至于能够得到相同的结果,那么就需要到设置随机函数的seed 参数,通过调用tf.random.set_ seed(1)来设置随机数的种子。

2. 使用Keras序列模型和单个致密层定义神经网络
方便的是,TensorFlow 已经定义了许多神经网络中常用的层,例如密集层。现在,我们将使用 Keras 的序列模型和单个致密层来定义我们的网络,而不是使用单层来定义我们的简单神经网络。有了顺序 API,你可以很容易地通过像积木一样堆叠在一起的层来创建神经网络。
如图,从上到下依次为从输入到输出过程中的每一层,输出层有2个节点,倒数第二层有n2个节点,第一层有n1个节点。
在这里插入图片描述
在这里插入图片描述
首先需要定义model,再向其中加入layer,设置函数为sigmoid,可戳如下链接查看Dense使用方法,如何初始化W和b(应该也是随机?)。https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense?version=stable
在这里插入图片描述
直接使用model(x_input)即可将输入带入到序列模型中求得结果。

3. 直接子类化模型定义神经网络
除了使用顺序 API 定义模型,我们还可以通过直接子类化模型类来定义神经网络,该模型类将层组合在一起以实现模型训练和推理。模型类捕获我们称之为 “模型” 或 “网络” 的东西。使用子类,我们可以为我们的模型创建一个类,然后使用 call 函数定义网络的前向传递。子类化提供了定义自定义层、自定义训练循环、自定义激活函数和自定义模型的灵活性。现在让我们使用子类而不是顺序模型来定义与上面相同的神经网络。
在这里插入图片描述
定义子类化模型,同样使用Dense定义一个单层模型,call函数中可看出通过dense_layer(inputs)即可输入参数求得结果,可以看出可直接通过传参形式向Dense定义的层传值。
就像序列API一样,传入参数测试:
在这里插入图片描述
重要的是,子类化为定义自定义模型提供了很大的灵活性。例如,我们可以在调用函数中使用布尔参数来指定不同的网络行为,例如在训练和推断过程中不同的行为。假设在某些情况下,我们希望网络简单地输出输入,不受任何干扰。我们定义一个布尔参数 isidentity 来控制这种行为:
在这里插入图片描述
在call函数中引入参数identity,意在表明可以通过认为传递参数改变执行条件,以达到在不同条件下执行不同的任务。此处当identity=True时,直接返回输入内容。
在这里插入图片描述
既然我们已经学习了如何使用序列API和子类API在TensorFlow中定义层和神经网络,我们准备将注意力转向如何使用反向传播实际实现网络训练。

TensorFlow自动微分

自动微分是TensorFlow中最重要的部分,也是反向传播训练的基础。我们将使用TensorFlow GradientTape中tf.GradientTape来追踪后面计算梯度的操作。
当通过网络进行正向传递时,所有正向传递操作都被记录到“磁带”上;然后,为了计算梯度,倒带播放。默认情况下,磁带在倒放后被丢弃;这意味着一个特定的 tf.GradientTape 只能计算一个梯度,随后的调用会抛出一个运行时错误。但是,我们可以通过创建一个持久的梯度来在相同的计算过程中计算多个梯度。
首先,我们将看看如何使用GradientTape计算梯度并访问它们进行计算。定义简单函数y=x^2,计算梯度:
在这里插入图片描述
在训练神经网络时,我们使用微分和随机梯度下降(SGD)来优化损失函数。现在我们已经了解了如何使用GradientTape来计算和访问导数,我们来看一个使用自动微分和SGD查找L =(x-xf)^2的最小值的示例。这里xf是一个我们想要优化的期望值的变量; L表示我们正在努力使损失最小化。尽管我们可以通过解析(xmin = xf)清楚地解决此问题,但考虑到如何使用GradientTape可以计算出此问题,这为将来使用梯度下降来优化整个神经网络损失的实验室提供了很好的条件。
在这里插入图片描述
在这里插入图片描述
GradientTape 为自动区分提供了一个非常灵活的框架。为了通过神经网络反向传播误差,我们跟踪磁带上的前向传递,使用这些信息来确定梯度,然后使用 SGD 使用这些梯度进行优化。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_44645726

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值