200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > mysql遍历查询子集 写出你自己的TensorFlow – 数据库 – 前端 mysql 多个定时任务数据汇总

mysql遍历查询子集 写出你自己的TensorFlow – 数据库 – 前端 mysql 多个定时任务数据汇总

时间:2021-12-09 22:28:06

相关推荐

mysql遍历查询子集 写出你自己的TensorFlow – 数据库 – 前端 mysql 多个定时任务数据汇总

1. 分支与特征后端

2. 仅支持标量的分支

这个工程是偶与 Minh Le 一起完成的。

为什么?

如果你修习的是计算机科学(CS)的人的话,你可能听说过这个短语「不要自己动手____」几千次了。它包含了加密,标准库,解析器等等。偶想到现在为止,它也应该包含机器学习库(ML library)了。

不管现实是怎么样的,这个震撼的课程都值得大家去学习。人们现在把 TensorFlow 和类似的库当作理所当然了。他们把它看作黑盒子并让他运行起来,但是并没有多少人知道在这背后的运行原理。这只是一个非凸(Non-convex)的优化问题!请停止对代码无意义的胡搞——仅仅只是为了让代码看上去像是正确的。

TensorFlow

在 TensorFlow 的代码里,有一个重要的组件,允许你将操作串在一起,形成一个称为「图形运算符」(此处英文错误?正确英文应为 Graph Operator)的东西。这个操作图是一个有向图 G=(V,E)G=(V,E), 在某些节点处 u1,u2,…,un,v∈Vu1,u2,…,un,v∈V,和 e1,e2,…,en∈E,ei=(ui,v)e1,e2,…,en∈E,ei=(ui,v)。大家知道,存在某种操作图从 u1,…,unu1,…,un 映射到 vv.

举个例子,如果大家有 x + y = z,那么 (x,z),(y,z)∈E(x,z),(y,z)∈E.

这对于评估算术表达式非常有用,大家能够在操作图的汇点下找到结果。汇点是类似 v∈V,∄e=(v,u)v∈V,∄e=(v,u) 这样的顶点。从另一方面来说,这些顶点从自身到其他顶点并没有定向边界。同样的,输入源是 v∈V,∄e=(u,v)v∈V,∄e=(u,v).

对于大家来说,大家总是把值放在输入源上,而值也将传播到汇点上。

反向模式分化

如果你觉得偶的解释不正确,可以参考下这些幻灯片的说明。

差异化是 Tensorflow 中许多模型的核心需求,因为大家需要它梯度下降的运行。每一个从高中毕业的人都应该知道差异化的意思。如果是基于基础函数组成的复杂函数,则只需要求出函数的导数,然后做链式法则。

在 5 分钟内倒转模式

所以现在请记住大家运行操作符时用的有向无环结构(DAG=Directed Acyclic Graph=有向无环图),还有上一个例子用到的链式法则。做出评估,大家能看到像这样的

x -> h -> g -> f

作为一个图表,在 f 它能够给予大家答案。然而,大家也可以反过来:

dx <- dh <- dg <- df

这样它看起来就像链式法则了!大家需要把导数相乘到最终结果的路径上。

这里是一个操作符的例子:

所以这将衰减为一个图的遍历问题。有谁感觉到这是个拓扑排序和深度优先搜索/宽度优先搜索?

是的,所以为了在双方面都支持拓扑排序,大家需要包含一套父组一套子组,而汇点是另一个方向的来源。反之亦然。

执行

在学校开学前,Minh Le 和偶开始设计这个工程。大家决定使用后端的特征库进行线性代数的运算。他们有一个叫做 MatrixXd 的矩阵类。大家在这儿使用那个东西。

class var {// Forward declarationstruct impl;public:// For initialization of new vars by ptr var(std::shared_ptr<impl>);var(double);var(const MatrixXd&);var(op_type, const std::vector<var>&);…// Access/Modify the current node value MatrixXd getValue() const;void setValue(const MatrixXd&);op_type getOp() const;void setOp(op_type);// Access internals (no modify) std::vector<var>& getChildren() const;std::vector<var> getParents() const;…private:// PImpl idiom requires forward declaration of the class: std::shared_ptr<impl> pimpl;};struct var::impl{public:impl(const MatrixXd&);impl(op_type, const std::vector<var>&);MatrixXd val;op_type op;std::vector<var> children;std::vector<std::weak_ptr<impl>> parents;};

在这儿,大家曾使用过一个叫「pImpl」的习语,意识是「执行的指针」。它对很多东西都很好,比如接口的解耦实现,以及当大家在堆栈上有一个本地接口时,允许大家实例化堆上的东西。一些「pImpl」的副作用是微弱的减慢运行时间,但是编译时间缩短了很多。这允许大家通过多个函数调用/返回来保持数据结构的持久性。像这样的树形数据结构应该是持久的。

大家有一些枚举来告诉大家目前正在进行哪些操作:

enum class op_type {plus,minus,multiply,divide,exponent,log,polynomial,dot,…none // no operators. leaf.};

执行此树的评估的实际类称为 expression:

class expression {public:expression(var);…// Recursively evaluates the tree. double propagate();…// Computes the derivative for the entire graph. // Performs a top-down evaluation of the tree. void backpropagate(std::unordered_map<var, double>& leaves);…private:var root;};

在回溯里,大家有一些做成类似这样的代码:

backpropagate(node, dprev):

derivative = differentiate(node)*dprev

for child in node.children:

backpropagate(child, derivative)

这几乎是在做一个深度优先搜索;你看到了吧?

为什么是 C++?

在实际过程中,C++可能不是合适的语言来做这些事儿。大家可以在像「Oaml」这样的函数式语言中花费更少的时间来开发。现在偶明白为什么「Scala」被用于机器学习中,主要就是因为「Spark」

然而,这很明显有利于 C++。

Eigen(库名)

举例来说,大家可以直接使用一个叫「Eigen」的 TensorFlow 的线性代数库。这是一个不假思索就被人用烂了的线性代数库。有一种类似于大家的表达式树的味道,大家构建表达式,它只会在大家真正需要的时候进行评估。然而,对于「Eigen」来说,他们在编译的时间内就决定使用什么模版,这意味着运行的时间减少了。偶对写出「Eigen」的人抱有很大的敬意,因为查看模版的错误几乎让偶眼瞎!

他们的代码看起来类似这样的:

Matrix A(…), B(…);auto lazy_multiply = A.dot(B);typeid(lazy_multiply).name(); // the class name is something like Dot_Matrix_Matrix.Matrix(lazy_multiply); // functional-style casting forces evaluation of this matrix.

这个特征库非常的强大,这就是为什么它是 TensortFlow 使用这些代码作为主要后端之一的原因。这意味着除了这个慢吞吞的评估技术之外还有其他的优化。

运算符重载

在 Java 中开发这个库很不错——因为没有 shared_ptrs, unique_ptrs, weak_ptrs;大家得到了一个真实的,有用的图形计算器(GC=Graphing Calculator)。这大大节省了开发时间,更不必说更快的执行速度。然而,Java 不允许操作符重载,因此它们不能这样:

// These 3 lines code up an entire neural network!var sigm1 = 1 / (1 + exp(-1 * dot(X, w1)));var sigm2 = 1 / (1 + exp(-1 * dot(sigm1, w2)));var loss = sum(-1 * (y * log(sigm2) + (1-y) * log(1-sigm2)));

顺便说一下,上面是实际的代码。是不是非常的漂亮?偶想说的是对于 TensorFlow 里面,这比使用 Python 封装来的更优美!这只是让你知道,它们也是矩阵而已。

在 Java 中,有一连串的 add(), divide() 等等是非常难看的。更重要的是,这将让用户更多的关注在「PEMDAS」上,而 C++的操作符则有非常好的表现。

特性,而不是一连串的故障

在这个库中,有一些东西是可以指定的,它没有明确的应用程序编程接口(API=Application Programming Interface),或者有但偶知道。举例子,实际上,如果大家只想训练一个特定的权重子集,大家只可以回溯到大家感兴趣的特定来源。这对于卷积神经网络的转移学习非常有用,因为很多时候,像 VGG19 这样的大网络被斩断,会附加了一些额外的层,根据新的域名样本来训练权重。

基准

在 Python 的 TensorFlow 库中,对虹膜数据集上的 10000 个「Epochs」进行训练以进行分类,并使用相同的超参数,大家有:

1.TensorFlow 的神经网络: 23812.5 ms

2.「Scikit」的神经网络:22412.2 ms

3.「Autodiff」的神经网络,迭代,优化:25397.2 ms

4.「Autodiff」的神经网络,迭代,无优化:29052.4 ms

5.「Autodiff」的神经网络,带有递归,无优化:28121.5 ms

令人惊讶的是,Scikit 是所有这些中最快的。这可能是因为大家没有做庞大的矩阵乘法。也可能是 TensorFlow 需要额外的编译步骤,如变量初始化等等。或者,也许大家不得不在 python 中运行循环,而不是在 C 中(Python 循环真的非常糟糕!)偶对自己也不是很自信。偶完全意识到,这绝不是一种全面的基准测试,因为在特定的情况下,它只适用于单个数据点。然而,库的表现并不能代表行为状态,因为大家不需要回滚大家自己的 TensorFlow。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。