如何手写一个深度学习框架、对比tensorflow分析

本文仅对一个开源手写框架做介绍,并简要分析。

最近为了更深入得了解深度学习框架,发现网上已经有人实现了手写框架,参照其文章,尝试进行了实现。

这里记录一下实现过程和心得。并通过对比一些tensorflow框架下的特性,阐述一些自己理解。

原文的连接在此: https://borgwang.github.io/dl/2019/08/18/tinynn.html

(国内网可能无法访问)

知乎连接在此: https://zhuanlan.zhihu.com/p/78713744?utm_source=wechat_timeline

原文介绍

原文里的笔者将设计和实现一个、轻量级的(约 200 行)、易于扩展的深度学习框架 tinynn,这个框架是基于 Python 和 Numpy 实现的。
原文首先从深度学习的流程开始分析,对神经网络中的关键组件抽象,确定基本框架;然后再对框架里各个组件进行代码实现

原文最后基于这个框架实现了一个 MNIST 分类的示例,并与 Tensorflow 做了简单的对比验证。

但该步骤,因为本人网络问题,导致MNIST数据集未下载出来,未进行验证。

设计步骤

步骤如下:

分析深度学习流程 --》 关键组件抽象  --》进行代码实现

深度学习流程分析

模型从被设计,到训练的整个周期,可以被简单理解为:网络的构建 + 损失函数的选取 + 训练。

其中的,网络的构建必定会涉及网络层(layer)的选取、前向传播、反向传播、优化器等的选取。

设置好特定的损失函数后,通过计算出每次传递的误差,传递给优化器,通过反向传播,对每层的参数进调整。

训练的时候,执行训练过程往复,达到特定的训练结要求后,就停止训练。

详细介绍见原文。

整体框架如下图所示:

preview
对于整个框架具体的实现细节,原文阐述的很详细,我这里就不赘述了。

想要自行实现的话,可以参照原作者的github连接: https://github.com/borgwang/tinynn-autograd

但有时候,github访问不了的话,也可以参见gitee连接获取源码:https://gitee.com/aismarter/tinynn-autograd

 

依照相关操作,即可实现全过程。下面说一些,对标tensorflow,对这个简单小框架的体会。

对比tensorflow框架

 下图,按照系统的层次结构展示了 TensorFlow 的不同层的功能和组件,也是这些构成了TensorFlow 框架下整个生态系统的核心。

当然,tensorfow开发维护者众多,原文里手写的框架,仅只相对于tensorflow的计算图层和数值计算层的实现。

之后,原文就分别实现,手写框架种的layer、loss、optimizer等模块。

实际上,就tinnyNN这个而言就只是实现了数值计算和构建网络的功能。连优化器,损失函数等都很少。当然,后边,原作者也再不断添加。

对标tensorflow,其也仅仅只是实现了数值计算层和计算图层。

在构建数值计算层上,手写框架,使用nump作为数值计算层的组件,也直接使用 numpy.ndarray 类作为 tensor 类的实现tensor 张量。而tensorflow下,我们一般较常见则使用cuDNN相关来实现计算。

在构建计算图层上,手写框架,通过自己编写的Dense类,Optimizer类等构成core组件,来实现计算图的构造、优化、执行以及前向传播和后向传播等功能。而tensorflow也是有相应的core组件,Core组件下的代码结构详情,可以上github查看。

以下是手写框架下,core组件下目录结构以及layer的相关代码。

tinynn
├── core
│   ├── __init__.py
│   ├── evaluator.py
│   ├── initializer.py
│   ├── layers.py
│   ├── losses.py
│   ├── model.py
│   ├── nn.py
│   └── optimizer.py
# layers.py
class Dense(Layer):
    def __init__(self, num_in, num_out,
                 w_init=XavierUniformInit(),
                 b_init=ZerosInit()):
        super().__init__("Linear")

        self.params = {
            "w": w_init([num_in, num_out]),
            "b": b_init([1, num_out])}

        self.inputs = None

    def forward(self, inputs):
        self.inputs = inputs
        return inputs @ self.params["w"] + self.params["b"]

    def backward(self, grad):
        self.grads["w"] = self.inputs.T @ grad
        self.grads["b"] = np.sum(grad, axis=0)
        return grad @ self.params["w"].T

以下是tensorflow的core组件的目录结构。。(源码可登上github自行查阅)

可见,tensorflow对框架的计算图进行了多次封装,用以实现图构造、优化、执行等功能。但手写的框架就比较直接。

毕竟tensorflow的core是由c++实现,并大约有26万行代码。

另外关于tensorflow内核剖析,可以查看以下相关文章:

https://blog.csdn.net/Labiod/article/details/105789942

其它说明

再次附上原文的知乎连接:https://zhuanlan.zhihu.com/p/78713744?utm_source=wechat_timeline

可以从其中了解一个框架实现的最开始的细节。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值