美文网首页
用C实现神经网络之KANN库简介

用C实现神经网络之KANN库简介

作者: 念_e87e | 来源:发表于2018-11-28 16:49 被阅读0次

下载链接:https://github.com/attractivechaos/kann

以什么是KANN:

       KANN是一个独立的轻量级库,用于构建和训练中小型人工神经网络,如多层感知器卷积神经网络递归神经网络(包括LSTMGRU)。它实现了基于图形的反向模式自动区分,并允许构建具有递归,共享权重和多个输入/输出/成本的拓扑复杂神经网络。与主流深度学习框架(如TensorFlow)相比,KANN不具备可扩展性,但它的灵活性接近,代码库小得多,仅依赖于标准C库。与其他轻量级框架(如tiny-dnn)相比,KANN仍然更小,更快,更通用,支持RNN,VAE和非标准神经网络,可能会使这些轻量级框架失效。

特征

    灵活。通过使用运算符构建计算图来进行模型构建。支持RNN,权重共享和多个输入/输出。

    高效。合理优化的矩阵产品和卷积。支持迷你批处理和有效的多线程。有时在主CPU模式下比主流框架更快。

    小巧便携。截至目前,KANN在四个源代码文件中的代码少于4000行,默认情况下没有非标准依赖项。与ANSI C编译器兼容。

限制

    仅限CPU。因此,KANN 不是用于训练巨大的神经网络。

    缺少一些常见的运算符和体系结构,如批量标准化。

    缺少用于训练RNN的详细API

API

神经网络中的网络层:

    kad_node_t *kad_feed(int n_d, ...):设置输入层节点,如:t = kad_feed(4, 1, 1, 28, 28);

    kad_node_t *kann_layer_dense(kad_node_t *in, int n1)

    kad_node_t *kann_layer_conv2d(kad_node_t *in, int n_flt, int k_rows, int k_cols, int stride_r, int stride_c, int pad_r, int pad_c):

   kad_node_t *kann_layer_gru(kad_node_t *in, int n1, int rnn_flag)

    kad_node_t *kann_layer_rnn(kad_node_t *in, int n1, int rnn_flag)

    kad_node_t *kann_layer_layernorm(kad_node_t *in)      //Batch Normalization

    kad_node_t *kann_layer_dropout(kad_node_t *t, float r)

    kad_node_t *kad_max2d(kad_node_t *x, int kernel_r, int kernel_c, int stride_r, int stride_c, int top_pad, int left_pad)

激活函数:

    kad_node_t *kad_square(kad_node_t *x);     /* f(x) = x^2 (element-wise square) */

    kad_node_t *kad_sigm(kad_node_t *x);      /* f(x) = 1/(1+exp(-x))              (element-wise sigmoid) */

    kad_node_t *kad_tanh(kad_node_t *x);      /* f(x) = (1-exp(-2x)) / (1+exp(-2x)) (element-wise tanh) */

    kad_node_t *kad_relu(kad_node_t *x);       /* f(x) = max{0,x}                    (element-wise rectifier, aka ReLU) */

    kad_node_t *kad_softmax(kad_node_t *x);    /* f_i(x_1,...,x_n) = exp(x_i) / \sum_j exp(x_j) (softmax: tf.nn.softmax(x,dim=-1)) */

    kad_node_t *kad_1minus(kad_node_t *x);     /* f(x) = 1 - x */

    kad_node_t *kad_exp(kad_node_t *x);        /* f(x) = exp(x) */

    kad_node_t *kad_log(kad_node_t *x);        /* f(x) = log(x) */

    kad_node_t *kad_sin(kad_node_t *x);       /* f(x) = sin(x) */

构建网络:

    kann_t *kann_new(kad_node_t *cost, int n_rest, ...)

训练网络:

    int kann_train_fnn1(kann_t *ann, float lr, int mini_size, int max_epoch, int max_drop_streak, float frac_val, int n, float **_x, float **_y)

        对于RNN多输入的网络, kann_train_fnn1并不适合,而且kann中也没有提供类似API

模型保存及加载:

    kann_t *kann_load_fp(FILE *fp)

    void kann_save(const char *fn, kann_t *ann)

线程加速:

    void kann_mt(kann_t *ann, int n_threads, int max_batch_size)

内存释放:

    void kann_data_free(kann_data_t *d)

    void kann_delete(kann_t *a)

数据结构

输入数据结构为【1,1,28,28】

The shape of n-d arrays

    For 2D convolution, cuDNN and Theano take images in shape of (batch-size,in-channel,height,width) and convolution weights in shape of (out-channel,in-channel,kernel-height,kernel-width). KANN follows the cuDNN and Theano convention. Caffe and TensorFlow are different. They take images in shape of (batch-size,height,weight,in-channel) and weights in (kernel-height,kernel-width,in-channel,out-channel).

存储到链表中为:

typedef struct kad_node_t {  
    uint8_t n_d;                                          /* number of dimensions; no larger than KAD_MAX_DIM */ //尺寸数;不大于KADY-Max  
    uint8_t flag;                                                      /* type of the node; see KAD_F_* for valid flags */ //节点的类型  
    uint16_t op;                                                      /* operator; kad_op_list[op] is the actual function */  
    int32_t n_child;                                                  /* number of operands/child nodes */  
    int32_t tmp;                                                      /* temporary field; MUST BE zero before calling kad_compile() */  
    int32_t ptr_size;                                                  /* size of ptr below */  
    int32_t d[KAD_MAX_DIM];                                 /* dimensions */  
    int32_t ext_label;                                              /* labels for external uses (not modified by the kad_* APIs) */  
    uint32_t ext_flag;                                              /* flags for external uses (not modified by the kad_* APIs) */  
    float *x;                                                              /* value; allocated for internal nodes */  
    float *g;                                                             /* gradient; allocated for internal nodes */  
    void *ptr;                                                          /* for special operators that need additional parameters (e.g. conv2d) */  
    void *gtmp;                                                    /* temporary data generated at the forward pass but used at the backward pass */  
    struct kad_node_t **child;                              /* operands/child nodes */  
    struct kad_node_t *pre;                                  /* usually NULL; only used for RNN */
} kad_node_t, *kad_node_p; 

图示结构图:

    

测试性能

相关文章

  • 用C实现神经网络之KANN库简介

    下载链接:https://github.com/attractivechaos/kann 以什么是KANN: K...

  • RNN循环神经网络

    用RNN(循环神经网络)实现连续数据的预测(以股票预测为例) 回顾卷积神经网络 卷积就是特征提取器,就是C(卷积)...

  • c++ 实现队列

    相关资料: 用C++实现一个队列 数据结构代码实现之队列的链表实现(C/C++)

  • Mosquitto 客户端使用介绍

    简介 ​ Mosquitto是用C语言实现了MQTT(Message Queueing TelemetryTr...

  • iOS 使用 RSA/ECB/OAEPWithSHA-256A

    先说结果 iOS这边采用openssl+C语言方式实现了加密即引入openssl库,用C语言header实现方法交...

  • 用C/C++实现BP神经网络

    缘起 最近跟着老师在学习神经网络,为了更加深刻地理解这个黑盒,我打算自己用C/C++将其实现一遍。今天忙活了好一会...

  • Linux下HElib库安装记录

    1.HElib库简介 HElib是一个实现全同态加密的软件库,开发语言是C++,是根据Brakerski,Gent...

  • css实现基础图表

    简介 1 .纯css实现icon图表,不需要引入阿里妈妈那个库了 https://www.zhangxinxu.c...

  • Runtime API

    Runtime库主要做下面几件事: 封装:在这个库中,对象可以用C语言中的结构体表示,而方法可以用C函数来实现,另...

  • iOS Runtime 常用方法整理

    Objective-C runtime是一个实现Objective-C语言的C库。对象可以用C语言中的结构体表示,...

网友评论

      本文标题:用C实现神经网络之KANN库简介

      本文链接:https://www.haomeiwen.com/subject/tgetxqtx.html