CS231n 学习笔记(十五)

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

课时19:深度学习框架

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

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

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

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

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

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

CS231n 学习笔记(十五)_第35张图片
Keras在后端为你处理那些建立的计算图(它也支持Theano作为后端)
CS231n 学习笔记(十五)_第36张图片
CS231n 学习笔记(十五)_第37张图片
CS231n 学习笔记(十五)_第38张图片
CS231n 学习笔记(十五)_第39张图片
CS231n 学习笔记(十五)_第40张图片
Theano快速介绍
CS231n 学习笔记(十五)_第41张图片
CS231n 学习笔记(十五)_第42张图片
CS231n 学习笔记(十五)_第43张图片
CS231n 学习笔记(十五)_第44张图片
在这里插入图片描述
CS231n 学习笔记(十五)_第45张图片
PyTorch细节介绍
CS231n 学习笔记(十五)_第46张图片
和tf对应关系
CS231n 学习笔记(十五)_第47张图片
CS231n 学习笔记(十五)_第48张图片
注意此处不需要再导入numpy了
CS231n 学习笔记(十五)_第49张图片
CS231n 学习笔记(十五)_第50张图片
CS231n 学习笔记(十五)_第51张图片
在这里插入图片描述
tensor在GPU上运行,而numpy不是
CS231n 学习笔记(十五)_第52张图片
可以把PyTorch张量看成Numpy加上GPU
CS231n 学习笔记(十五)_第53张图片
x是一个变量
CS231n 学习笔记(十五)_第54张图片
CS231n 学习笔记(十五)_第55张图片
每一次对变量的构造器的调用,都封装了一个PyTorch张量。并设置了二值的标记 ,告诉构造器我们需不需要计算在该变量上的梯度CS231n 学习笔记(十五)_第56张图片CS231n 学习笔记(十五)_第57张图片
在这里插入图片描述
PyTorch每次向前传播时都要构造一个新的图(程序会更简洁)
CS231n 学习笔记(十五)_第58张图片
使用张量进行前向和反向操作,然后把这些操作固定在计算图中
CS231n 学习笔记(十五)_第59张图片
这样可以定义我们自己的运算
CS231n 学习笔记(十五)_第60张图片
CS231n 学习笔记(十五)_第61张图片
在这里插入图片描述
在这里插入图片描述
优化操作:
CS231n 学习笔记(十五)_第62张图片
CS231n 学习笔记(十五)_第63张图片
CS231n 学习笔记(十五)_第64张图片
CS231n 学习笔记(十五)_第65张图片
CS231n 学习笔记(十五)_第66张图片
CS231n 学习笔记(十五)_第67张图片
CS231n 学习笔记(十五)_第68张图片
CS231n 学习笔记(十五)_第69张图片
CS231n 学习笔记(十五)_第70张图片
CS231n 学习笔记(十五)_第71张图片
CS231n 学习笔记(十五)_第72张图片
CS231n 学习笔记(十五)_第73张图片
可以在静态图上优化,但在动态图上不是很容易
CS231n 学习笔记(十五)_第74张图片
CS231n 学习笔记(十五)_第75张图片
CS231n 学习笔记(十五)_第76张图片
不依赖数据输入大小
CS231n 学习笔记(十五)_第77张图片
TensorFlow几乎用计算图重构了所有编程语言,不能真正使用python中的一些命令CS231n 学习笔记(十五)_第78张图片
CS231n 学习笔记(十五)_第79张图片
Caffe简要介绍
CS231n 学习笔记(十五)_第80张图片
CS231n 学习笔记(十五)_第81张图片
CS231n 学习笔记(十五)_第82张图片
CS231n 学习笔记(十五)_第83张图片
CS231n 学习笔记(十五)_第84张图片
CS231n 学习笔记(十五)_第85张图片
CS231n 学习笔记(十五)_第86张图片
CS231n 学习笔记(十五)_第87张图片
CS231n 学习笔记(十五)_第88张图片

你可能感兴趣的:(斯坦福,CS231n,学习笔记,CS231n,学习笔记)