CS231n 学习笔记(十五)

时间:2019/4/6
内容:常用框架

课时19:深度学习框架

review:
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
大部分深度学习框架的目标是在前向传播时的代码编写看起来和numpy相似,但又能在GPU上运行,并且能自动计算梯度
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
TensorFlow细节介绍
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
我们定义了X,Y,w1,w2并且创建了这些变量的tf.placeholder对象,所以这些变量会成为图中的输入结点,让运行并输入数据时,将数据放到计算图中的输入槽中。注意这与内存分配没有关系,我们只是为计算图建立了输入槽
CS231n 学习笔记(十五)
然后我们利用这些输入槽或者说符号变量执行各种TensorFlow操作,来构建我们想要运行在这些变量上的计算。注意没目前系统里还没有任何数据,我们只是建立计算图数据结构
CS231n 学习笔记(十五)
计算损失值在w1,w2方向上的梯度
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
大多数时候TensorFlow只是从Numpy数组接收数据
CS231n 学习笔记(十五)
通过字典参数进行传递
CS231n 学习笔记(十五)
以上是训练过程。

但这里有个问题:当我们每次执行计算图进行向前传播时,我们实际上在对权重进行输入,我们将权重保存成Numpy的形式,直接将它输入到计算图中,当计算图执行完毕,我们会得到这些梯度值(这些梯度值的个数与权重值的个数一致),每次运行图的时候,我们将从Numpy数组中复制权重到TensorFlow才能得到梯度,然后从TensorFlow中复制梯度到Numpy数组。如果只是在CPU上运行不会出现太大问题,但由于CPU和GPU之间有传输瓶颈,要在CPU和GPU之间进行数据复制非常耗费资源。

修正方式:将权重w1和w2定义为变量,而不是在每次前向传播时都将它们作为需要输入网络的占位符,变量可以存在计算图中,并且在不同时间运行相同计算图的时候,它都可以保持在计算图中,且由TensorFlow负责初始化这些值(注意并不是真正的初始化它们,只是告诉TensorFlow我们希望怎样进行初始化)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
在修正之前,我们实际上是在计算图之外对权重进行的更新操作。我们计算梯度,然后以Numpy array的形式更新权重参数,然后在下一次迭代时利用这些更新过的权重参数。但现在我们希望在计算图操作中,更新参数的操作也成为计算图中的一个操作。因此利用这个赋值函数,其能够在计算图中改变参数值,然后这些变化的值会在计算图的多次迭代之后仍然保存
CS231n 学习笔记(十五)
执行整个网络的时候,需要首先进行一个全局参数的初始化操作,告诉TensorFlow来设置计算图中的这些参数
CS231n 学习笔记(十五)
目前的代码得出的loss是不变的,因为没有明确告诉TensorFlow来执行更新操作,也就是添加new_w1和new_w2作为输出

这些nuew_w1和new_w2都是非常大的tensor,当告诉TensorFlow我们需要这些输出时,每次迭代中就会在CPU和GPU之间执行这些操作,我们不希望这样。
这里有一个技巧:我们在图中添加一个仿制节点伴随这些仿制数据的独立性,我们就可以说仿制节点的更新拥有了new_w1和new_w2的数据依赖性。当执行计算图时,我们同时计算loss和这个仿制节点,这个仿制节点不返回任何值,我们放入节点这个数据依赖保证了当我们执行更新操作之后,我们使用了更新的权重参数值
CS231n 学习笔记(十五)
依赖的意思是更新依赖于这些赋值操作。这些赋值操作在计算图里面,存储于GPU显存中,所以我们在GPU中执行这些更新操作,而不需要把更新数值从图中拷贝出来

有一种便捷操作来处理以上过程,优化器
CS231n 学习笔记(十五)
tf.GlobalVariablesInitiator用来初始化w1和w2,它使得tf.randomnormal进行运行,并生成具体的值来初始化这些变量

在前面的例子中,我们使用自己的张量来精确计算损失,但TensorFLow也给了很多方便的函数,例如
计算L2损失
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
在tf.layers.dense这一行中,它设置了w1和b1,也就是偏差

CS231n 学习笔记(十五)
Keras在后端为你处理那些建立的计算图(它也支持Theano作为后端)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
Theano快速介绍
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
PyTorch细节介绍
CS231n 学习笔记(十五)
和tf对应关系
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
注意此处不需要再导入numpy了
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
tensor在GPU上运行,而numpy不是
CS231n 学习笔记(十五)
可以把PyTorch张量看成Numpy加上GPU
CS231n 学习笔记(十五)
x是一个变量
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
每一次对变量的构造器的调用,都封装了一个PyTorch张量。并设置了二值的标记 ,告诉构造器我们需不需要计算在该变量上的梯度CS231n 学习笔记(十五)CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
PyTorch每次向前传播时都要构造一个新的图(程序会更简洁)
CS231n 学习笔记(十五)
使用张量进行前向和反向操作,然后把这些操作固定在计算图中
CS231n 学习笔记(十五)
这样可以定义我们自己的运算
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
优化操作:
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
可以在静态图上优化,但在动态图上不是很容易
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
不依赖数据输入大小
CS231n 学习笔记(十五)
TensorFlow几乎用计算图重构了所有编程语言,不能真正使用python中的一些命令CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
Caffe简要介绍
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)
CS231n 学习笔记(十五)