目录
1.前言
最近一直在搞联邦学习,查了很多资料发现这个领域的科普文章多但真正一步一步讲到底的比较少。那我刚好把收集到的资料整理一下也顺便记录一下自己的学习历程。
在research的大环境里我还是一个小白,希望有机会和大佬多多交流~
2.TFF
最开始接触深度学习的时候搞得是TF,所以进联邦学习也是拿的TF的门票,用的是TFF-tenserflow federated。Pytorch的话估计以后也是要搞,不过以后的事以后再说(⑉・̆-・̆⑉)
2.1TF基础
既然提到tensorflow那就先回顾一下tf吧(记得上次打tensorflow已经是2020年的事了。TF的整体结构就是数据流表:
构件图(数据与操作的执行步骤被描绘成一个图)+执行图(使用会话以执行构建好的图操作)
- 图:是TF将计算表达为指令之间的依赖关系的一种表达方式
- 会话:跨一个或多个设备运行数据流的机制
- 张量:TF中的基本数据对象
- 节点:提供图中执行的操作
图中规定了变量(这样说好像不太对,参数赋值?)运算过程,但不执行。有两种方式定义图,一种是tensorflow调用默认图,另一种方式是自定义图。默认图比较简单会自动创建(所以无需理会,直接构建图内容即可)默认图可以用下面的代码调用并查看:
default_g = tf.get_default_graph()
自定义图需要使用到下面代码,创建后再进行构建图的内容(如参数赋值):
new_g = tf.Graph()
with new_g.as_default():
值得注意的是,一旦创建了自定义图开启会话时也需要标注(如下面斜体所示)。
会话包括两种开启方式,或者说两种使用方式。其中第二种方式使用了上下文管理器,不需要单独再次关闭会话,这两种区别在去资源的释放:
sess = tf.Session() A = sess.run(B) print(A) sess.close() | with tf.Session(graph=new_g) as sess: A = sess.run(B) print(A) |
张量本身长由placeholder配合None定义,在执行图时其形状需要修改。通常有两种修改方法,一种是静态修改一种是动态修改。其中静态修改使用 set_shape(),其作用于张量本身(也就是张量本身会被修改)
设置静态维度使用 set_shape() 查询静态维度使 tensorX.shape.as_list()
而动态修改则不同,它可以被理解成调用 tf.reshape() 方法,并不会直接作用于张量。所以需要有一个新的变量去接
动态的改变tensor的动态维度使用 tf.reshape() 查询tensor的动态维度使用 tf.shape()
而除了形状外,张量的类型也可以被改变:
n = tf.cast(tensor, dtype)
和 tf.reshape 相同,并不会直接作用于张量,而是需要一个变量去接。
2.2 TF进阶
上面谈到一点即图中规定了变量,这里就稍微在说一下变量。在tensorflow中模型参数一般用变量存储。这里会使用关键字 tf.variable()
tf.Variable(initial_value=None, trainable=True, collections=None, name=None)
但在图中这些变量并没有被初始化,需要在会话外再进行初始化
init=tf.gloabal_variables_initializer() #在外部
sess.run(init) #在会话中
这里多啰嗦一句,前面的关键字太多了搞的有点昏(至少我有点晕了)。
- placeholder用在构建于构建自变量和因变量(这个说法有点奇怪)其实也就是 x 和 y ,因为在传入参数(训练集)的时候时非常大,不可能一次性传入。所以要先placeholder占位置,之后再传入batch。
- 也是因为placeholder的存在,无法定义这个数组的形状,所以要用None表示这个tensor的一个维度是不确定的,可以是任意的,(其具体维度值要在图运行过程中确定)
- 在构建模型的时候使用reshape(或者set_shape)重新定义形状,这里经常使用-1来进行自动填充。
此外,可以为变量定义命名空间是整个代码段更加可读和友好(属于上下文管理器):
with tf.variable_scope("my_scope")
2.3 TF流程
上面基本把tf的组件过了一遍,这里就简单过一下tf的流程。
准备数据 =》构造模型(定义模型参数,使用变量)=》构造损失函数 =》 优化损失(定义optimizer)=》显示的初始化变量 =》开启会话 =》开始训练
2.4 TF其他
以上提到的为组件部分,下面列出为基础API
tf.app | |
tf.image | 图形处理 |
tf.gfile | 一组文件操作函数 |
tf.Summary | 用于生成可用的日志(TensorBoard) |
tf.python_io | 读写文件 |
tf.train | 提供训练器 |
tf.nn | 神经网络的底层函数 |
下面列出的为高级API
tf.keras | 用于快速构建模型 |
tf.layers | |
tf.contrib | |
tf.estimator |
其实基础API和高级API之间并没有隔着很厚的次元壁,一般情况下通过排列组合基础API也可以达到高级API的效果。
这篇文章主要聊了tf的一些基础知识,也顺便回顾一下搭建和训练的流程。计划下一篇博文聊一聊TFF的相关知识~
大家加油!俺先告辞了(ง ˙o˙)ว
2.5 TF其他的其他(7/27更新)
真是学无止境阿铁铁们!前几天看到一篇大佬的TFF代码当时有一个地方没怎么看懂,今天翻官方文档灵光乍现!原来还是自己TF的知识学的不扎实阿QAQ
在大佬的那篇代码里,虽然使用了tensorflow但并没有显示做变量初始化以及开启会话(也就是sess, inital那一套)当时有点疑惑,因为如果会话都没开启那计算图相当于没有被执行,更谈不到模型训练了。后来看官方文档的时候发现一直提到 Eager 模式,查了才知道原来tensorflow可以有两种模式去实现!一种就是“图+会话”的模式也就是上面提到的那种模式,而另一种就叫Eager模式,是一种更直观更友好(至少我觉得是 =。=)的方式。
借用一篇博文的话:
“众所周知,Tensorflow入门之所以困难,与其采用的Graph 和 Session 模式有关,这与原生的 Python 代码简单、直观的印象格格不入。同时,由于计算仅仅发生在Session里面,所以初始化参数和变量的时候没办法将结果打印出来,以至于调试起来也十分困难。”
“当然Google官方也意识到了这点,于是引入了Eager模式,在这个模式下tensorflow的常量和变量可以直接计算并打印出来,甚至还可以和numpy数组混合计算”
经过翻查,发现Eager其实是很简洁的而且也是在TFF官方文档中推荐使用的。在这种模式下:
1. 变量,常量,计算结果都可以直接打印出来而无需开启会话;
2. 同样的,在创建优化器阶段不再需要构建计算图谱。
但值得注意的是,两种模式不能混用,Eager需要声明来手动开启。下面这个链接中作者讲的很详细,这里就不予赘述。
https://www.cnblogs.com/sqm724/p/13610584.html
https://zhuanlan.zhihu.com/p/82548504
而与此同时,在Eager模式下也有新的(独有的)梯度求解方法,其使用方法类似于上下文管理器,而且可以用作多级求导:
https://www.cnblogs.com/sqm724/p/13610681.html
除此之外,这里放几个链接,是我在查资料的时候遇到的比较好的资源,感谢作者(们:
1. tensorflow中tensor的静态维度和动态维度:
https://www.cnblogs.com/mtcnn/p/9411708.html
2. Tensorflow中的Placeholder及用法:
https://zhuanlan.zhihu.com/p/81040163
3. TensorFlow的默认图与自定义图:
https://blog.csdn.net/dai_kai_kai/article/details/104788753
4. Keras: 基于 Python 的深度学习库:
5. TensorFlow低阶API:
https://www.cnblogs.com/lfri/p/10356655.html
6. Python的lambda函数用法(下一篇会用到):