kann, 一种用于人工神经网络的轻量级

分享于 

10分钟阅读

GitHub

  繁體 雙語
A C Library for Artificial Neural Networks
  • 源代码名称:kann
  • 源代码网址:http://www.github.com/attractivechaos/kann
  • kann源代码文档
  • kann源代码下载
  • Git URL:
    git://www.github.com/attractivechaos/kann.git
    Git Clone代码到本地:
    git clone http://www.github.com/attractivechaos/kann
    Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/attractivechaos/kann
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
    

    启动

    # acquire source code and compilegit clone https://github.com/attractivechaos/kanncd kann; make# learn unsigned addition (30000 samples; numbers within 10000)seq 30000 | awk -v m=10000 '{a=int(m*rand());b=int(m*rand());print a,b,a+b}' 
     |./examples/rnn-bit -m7 -o add.kan -# apply the model (output 1138429, the sum of the two numbers)echo 400958 737471 |./examples/rnn-bit -Ai add.kan -

    简介

    合肥 KANN is multi constructing网络 smallconvolutional神经网络和递归神经网络等小型人工神经网络,是一个独立的和轻量级的图书馆。 方法基于 graph automatic automatic,并与主流的深度学习框架( 如 TensorFlow ) 相比,具有更小的代码库,具有更小的共享权值和更多的inputs/outputs/costs.,它的代码库比较小,只依赖于标准的C 库。 in tiny,KANN和non的轻量级框架相比,KANN更小,速度更快,支持 RNN,VAE和非标准的神经网络,可能会导致这些轻量级框架。

    如果你想在 C/C++ 中实验小型到中等神经网络,部署no-so-large模型而不用担心依赖 hell,或者学习深度学习库的内部internals可能很有用。

    特性

    • 利用运算图建立计算图的柔性模型。 支持 RNNs,权重共享和多个输入/输出。

    • 高效。合理的矩阵产品和卷积。 支持小型批处理和有效多线程。 有时比主流框架的cpu模式更快。

    • 小型和便携式。至少在四个源代码文件中有 4000行代码,缺省情况下没有标准依赖项。 兼容 ANSI C 编译器。

    限制

    • 仅 CPU。因此,KANN为训练庞大的神经网络而不是。

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

    • 用于培训RNNs的详细 api。

    安装

    库由四个文件组成: kautodiff.{h,c}kann.{h,c}。鼓励你在源代码树中包含这些文件。 不需要安装要编译示例:

    make

    这将在示例目录中生成几个可执行文件。

    文档

    头文件中的注释简要解释了 api。 更多文档可以在 doc 目录中找到。 使用库的示例在示例目录中。

    基本api教程

    使用神经网络通常涉及三个步骤: 模型构建。训练和预测。 我们可以使用层api来构建一个简单的模型:

    kann_t *ann;kad_node_t *t;
    t = kann_layer_input(784); // for MNISTt = kad_relu(kann_layer_dense(t, 64)); // a 64-neuron hidden layer with ReLU activationt = kann_layer_cost(t, 10, KANN_C_CEM); // softmax output + multi-class cross-entropy costann = kann_new(t, 0); // compile the network and collate variables

    对于具有一个输入和一个输出的简单前馈模型,可以使用以下方法对它的进行训练:

    int n; // number of training samplesfloat **x; // model input, of size n * 784float **y; // model output, of size n * 10// fill in x and y here and then call:kann_train_fnn1(ann, 0.001f, 64, 25, 10, 0.1f, n, x, y);

    我们可以将模型保存到一个带有 kann_save()的文件中,或者使用它来对MNIST图像进行分类:

    float *x; // of size 784constfloat *y; // this will point to an array of size 10// fill in x here and then call:y = kann_apply1(ann, x);

    使用复杂模型需要使用低级 api。 详细信息请参见 01 user.md

    一个完整的例子

    本示例学习如何计算整数中的" 1"位数( 例如。 popcount ):

    // to compile and run: gcc -O2 this-prog.c kann.c kautodiff.c -lm &&./a.out#include<stdlib.h>#include<stdio.h>#include"kann.h"intmain(void)
    {
     int i, k, max_bit = 20, n_samples = 30000, mask = (1<<max_bit)-1, n_err, max_k;
     float **x, **y, max, *x1;
     kad_node_t *t;
     kann_t *ann;
     // construct an MLP with one hidden layers t = kann_layer_input(max_bit);
     t = kad_relu(kann_layer_dense(t, 64));
     t = kann_layer_cost(t, max_bit + 1, KANN_C_CEM); // output uses 1-hot encoding ann = kann_new(t, 0);
     // generate training data x = (float**)calloc(n_samples, sizeof(float*));
     y = (float**)calloc(n_samples, sizeof(float*));
     for (i = 0; i <n_samples; ++i) {
     int c, a = kad_rand(0) & (mask>>1);
     x[i] = (float*)calloc(max_bit, sizeof(float));
     y[i] = (float*)calloc(max_bit + 1, sizeof(float));
     for (k = c = 0; k <max_bit; ++k)
     x[i][k] = (float)(a>>k&1), c += (a>>k&1);
     y[i][c] = 1.0f; // c is ranged from 0 to max_bit inclusive }
     // trainkann_train_fnn1(ann, 0.001f, 64, 50, 10, 0.1f, n_samples, x, y);
     // predict x1 = (float*)calloc(max_bit, sizeof(float));
     for (i = n_err = 0; i <n_samples; ++i) {
     int c, a = kad_rand(0) & (mask>>1); // generating a new numberconstfloat *y1;
     for (k = c = 0; k <max_bit; ++k)
     x1[k] = (float)(a>>k&1), c += (a>>k&1);
     y1 = kann_apply1(ann, x1);
     for (k = 0, max_k = -1, max = -1.0f; k <= max_bit; ++k) // find the maxif (max <y1[k]) max = y1[k], max_k = k;
     if (max_k!= c) ++n_err;
     }
     fprintf(stderr, "Test error rate: %.2f%%n", 100.0 * n_err/n_samples);
     kann_delete(ann); // TODO: also to free x, y and x1return0;
    }

    基准测试

    • 基准只评估相对较小的网络,但实际上,在gpu上是巨大的网络,它真正展示了主流深入学习框架的true 能力。 请不要把太多的东西读到表格里。

    • "Linux 2.7 E5-2697 CPU 上有 48个内核,位于 GHz。 MKL,NumPy-1.12.0 和 Theano-0.8.2 与Conda一起安装;Keras-1.2.2 安装了。 这台机器上的正式 TensorFlow-1.0.0 轮不适用于这台机器上的% OS 6. 这台机器安装了特斯拉 K40c GPU。 我们使用 CUDA-7.0 和 cuDNN-4.0 在GPU上进行训练。

    • "i7-3667U"内核CPU上的4内核 2 GHz。 MKL和Theano和也带了 Conda。 Keras-1.2.2 和 Tensorflow-1.0.0 安装了 pip。 在这两台机器上,在March年3月,tiny从github获得了小的dnn。

    • mnist of实现了一个具有 64个隐藏神经元的单层。 mnist的两个卷积层采用 32 3 -by-3内核和ReLU激活,然后是 2 -by-2最大池和一个 128-neuron 密集层。 mul100-rnn使用两个大小为 160的GRUs。 输入和输出都是每个 30000个训练样本的形状( 14,2 ) -- 28 GRU操作的2-D 二进制阵列。

    任务框架机设备实际 CPU 命令行
    mnistKANN+SSELinux1 个 CPU31.3s31.2s-m20 -v0
    苹果机1 个 CPU27.1s27.1s
    KANN+BLASLinux1 个 CPU18.8s18.8s
    Theano+KerasLinux1 个 CPU33.7s33.2skeras/。py -m20 -v0
    4 CPU32.0s121.3s
    苹果机1 个 CPU37.2s35.2s
    2 CPU32.9s62.0s
    TensorFlow苹果机1 个 CPU33.4s33.4stensorflow/。py -m20
    2 CPU29.2s50.6stensorflow/。py -m20 -t2
    dnnLinux1 个 CPU2m19s2m18s小型 dnn/-m20
    Tiny-dnn+AVXLinux1 个 CPU1m34s1m33s
    苹果机1 个 CPU2m17s2m16s
    mnist-cnnKANN+SSELinux1 个 CPU57m57s57m53smnist-cnn -v0 -m15
    4 CPU19m09s68m17smnist -v0 -t4 -m15
    Theano+KerasLinux1 个 CPU37m12s37m09skeras/。py -Cm15 -v0
    4 CPU24m24s97m22s
    1 GPU2m57skeras/。py -Cm15 -v0
    Tiny-dnn+AVXLinux1 个 CPU300m40s300m23s小型 dnn/-Cm15
    mul100-rnnKANN+SSELinux1 个 CPU40m05s40m02srnn位 -l2 -n160 -m25 -Nd0
    4 CPU12m13s44m40srnn位 -l2 -n160 -t4 -m25 -Nd0
    KANN+BLASLinux1 个 CPU22m58s22m56srnn位 -l2 -n160 -m25 -Nd0
    4 CPU8m18s31m26srnn位 -l2 -n160 -t4 -m25 -Nd0
    Theano+KerasLinux1 个 CPU27m30s27m27srnn-bit.py -l2 -n160 -m25
    4 CPU19m52s77m45s
    • 在单线程模式下,Theano大约比KANN快 50%,这可能是由于有效的矩阵乘法( 即。 sgemm ) 在MKL中实现。 如以前的微基准测试所示,/openblas的速度可能是KANN的实现的两倍。

    • 可以从 BLAS 库( 按宏 HAVE_CBLAS 启用) 中选择使用 sgemm 例程。 openblas-0.2 19链接,spx与Mul100-rnn上Theano的单个线程性能匹配。 不会减少卷积到矩阵乘法,所以 mnist cnn不会从OpenBLAS中受益。 我们观察到,当我们使用小型的size时,OpenBLAS比本机实现慢得多。 原因未知。

    • intra多线程多线程模型比Theano+Keras多。 然而,在它的当前形式中,这个模型可能不能很好地与 gpu。


    相关文章