引子
作为一家电商公司,年底都是我们最闲的时候,前两周心血来潮想看看是否有直播写代码的。
看完后十分推荐,现在很多同学学习深度学习,一般都是从tensorflow和pytorch入手。但作为一个码农,不能了解其内部细节,总是很难受,而这些框架目前的源码有略显复杂。如果能低成本的DIY一些轮子,再对比源码来看,则事半功倍。
joelgrus在直播时用了200行不到的代码,撸了一个非常简单的DNN,跑了个XOR的例子用于演示。麻雀虽小五脏俱全,一定程度上能帮助我们加深对DL的理解。本文将简单介绍下直播的内容,更具体的细节大家去看视频。
实施方案
有一句不是那么严谨的话说的很好:pytorch一开始就是gpu版本的numpy + autograd
可以说,tensor是第一公民,pytorch在0.4把Variable和tensor合并,更突出了这个一味。
因此,对于即将要做的玩具DNN,我们先不考虑GPU,那么可以直接用numpy的ndarray来代表tensor,剩下的需要设计网络的代码的结构。
"""A tensor is just a n-dimensional array"""
from numpy import ndarray as Tensor
拆解下来,我们需要实现下面几个类:Tensors
Loss Function
Layers
Neurals Nets
Optimizers
Data
Training
XOR Example
环境准备
作者使用VS Code + mypy的工作环境。我试了下VS Code,挺好用的,以前在没有用Mac之前,一直比较喜欢VS系列,用VS Code看源码比PyCharm方便一些,推荐下给大家。
mypy可以让python做静态类型检查,代码写起来有点想scala了,个人也比较喜欢强类型语言,所以采取了下面的风格,需要python 3.5+
class Loss:
def loss(self, pred:Tensor, y:Tensor) -> float:
raise NotImplementedError
def grad(self, pred:Tensor, y:Tensor) -> Tensor:
raise NotImplementedError
class MSE(Loss):
def __init__(self):
super().__init__()
def loss(self, pred:Tensor, y:Tensor) -> float:
return np.sum((pred - y) ** 2)
def grad(self, pred:Tensor, y:Tensor) -> Tensor:
return 2 * (pred - y)
一些tipsnumpy的matrix的@操作和matmul类似,add操作在处理两个matrix dimension不一致时,其broadcast有默认的rule,和tensorflow类似,不熟悉的建议参考文档看下。
layer是整个玩具项目的核心,代码稍微多一点,由于没有用autograd,需要自己实现backward,
一些grad的check都么有做,为了简单。
其他
joelgrus在youtube上还有不少视频,可以学习到更多的DL代码相关的细节。
参考