eneural_net

eNeural.net / Dart 是一个高效人工智能神经网络的 AI 库。该库是可移植的(原生、JS/Web、Flutter),并且计算能够利用 SIMD(单指令多数据)来提高性能。

用法

import 'package:eneural_net/eneural_net.dart';
import 'package:eneural_net/eneural_net_extensions.dart';

void main() {
  // Type of scale to use to compute the ANN:
  var scale = ScaleDouble.ZERO_TO_ONE;

  // The samples to learn in Float32x4 data type:
  var samples = SampleFloat32x4.toListFromString(
    [
      '0,0=0',
      '1,0=1',
      '0,1=1',
      '1,1=0',
    ],
    scale,
    true, // Already normalized in the scale.
  );

  var samplesSet = SamplesSet(samples, subject: 'xor');

  // The activation function to use in the ANN:
  var activationFunction = ActivationFunctionSigmoid();

  // The ANN using layers that can compute with Float32x4 (SIMD compatible type).
  var ann = ANN(
    scale,
    // Input layer: 2 neurons with linear activation function:
    LayerFloat32x4(2, true, ActivationFunctionLinear()),
    // 1 Hidden layer: 3 neurons with sigmoid activation function:
    [HiddenLayerConfig(3, true, activationFunction)],
    // Output layer: 1 neuron with sigmoid activation function:
    LayerFloat32x4(1, false, activationFunction),
  );

  print(ann);

  // Training algorithm:
  var backpropagation = Backpropagation(ann, samplesSet);

  print(backpropagation);

  print('\n---------------------------------------------------');

  var chronometer = Chronometer('Backpropagation').start();

  // Train the ANN using Backpropagation until global error 0.01,
  // with max epochs per training session of 1000000 and
  // a max retry of 10 when a training session can't reach
  // the target global error:
  var achievedTargetError = backpropagation.trainUntilGlobalError(
          targetGlobalError: 0.01, maxEpochs: 50000, maxRetries: 10);

  chronometer.stop(operations: backpropagation.totalTrainingActivations);

  print('---------------------------------------------------\n');

  // Compute the current global error of the ANN:
  var globalError = ann.computeSamplesGlobalError(samples);

  print('Samples Outputs:');
  for (var i = 0; i < samples.length; ++i) {
    var sample = samples[i];

    var input = sample.input;
    var expected = sample.output;

    // Activate the sample input:
    ann.activate(input);

    // The current output of the ANN (after activation):
    var output = ann.output;

    print('- $i> $input -> $output ($expected) > error: ${output - expected}');
  }

  print('\nglobalError: $globalError');
  print('achievedTargetError: $achievedTargetError\n');

  print(chronometer);
}

输出

ANN<double, Float32x4, SignalFloat32x4, Scale<double>>{ layers: 2+ -> [3+] -> 1 ; ScaleDouble{0.0 .. 1.0}  ; ActivationFunctionSigmoid }
Backpropagation<double, Float32x4, SignalFloat32x4, Scale<double>, SampleFloat32x4>{name: Backpropagation}

---------------------------------------------------
Backpropagation> [INFO] Started Backpropagation training session "xor". { samples: 4 ; targetGlobalError: 0.01 }
Backpropagation> [INFO] Selected initial ANN from poll of size 100, executing 600 epochs. Lowest error: 0.2451509315860858 (0.2479563313068569)
Backpropagation> [INFO] (OK) Reached target error in 2317 epochs (107 ms). Final error: 0.009992250436771877 <= 0.01
---------------------------------------------------

Samples Outputs:
- 0> [0, 0] -> [0.11514352262020111] ([0]) > error: [0.11514352262020111]
- 1> [1, 0] -> [0.9083549976348877] ([1]) > error: [-0.0916450023651123]
- 2> [0, 1] -> [0.9032943248748779] ([1]) > error: [-0.09670567512512207]
- 3> [1, 1] -> [0.09465821087360382] ([0]) > error: [0.09465821087360382]

globalError: 0.009992250436771877
achievedTargetError: true

Backpropagation{elapsedTime: 111 ms, hertz: 83495.49549549549 Hz, ops: 9268, startTime: 2021-05-26 06:25:34.825383, stopTime: 2021-05-26 06:25:34.936802}

SIMD(单指令多数据)

当使用 Float32x4Int32x4 进行计算时,Dart 支持 SIMD。
激活函数是使用 Float32x4 实现的,与普通实现相比,
性能提高了 1.5 倍到 2 倍。

SIMD 的基本原理是同时对 4 个数字执行数学运算。

Float32x4 是一个包含 4 个 double(32 位单精度浮点数)的通道。
乘法示例

  var fs1 = Float32x4( 1.1 , 2.2 , 3.3  , 4.4  );
  var fs2 = Float32x4( 10  , 100 , 1000 , 1000 );
  
  var fs3 = fs1 * fs2 ;
  
  print(fs3);
  // Output:
  // [11.000000, 220.000000, 3300.000000, 4400.000000]

请参阅“dart:typed_data 库”和“在 Dart 中使用 SIMD”。

信号

Signal 类代表数字集合(包括其相关操作),
这些数字将流经 ANN,代表实际信号,
即人工智能神经网络应计算的信号。

主要实现是 SignalFloat32x4,它代表一个
基于 Float32x4ANN Signal。所有操作都优先使用 SIMD。

Signal 的框架允许实现任何类型的数据
来表示 [eNeural.net] ANN 的数字和操作。SignalInt32x4
是一个实验性实现,用于练习基于整数的 ANN

激活函数

ActivationFunctionANN 神经元激活函数的基类

  • ActivationFunctionSigmoid:

    经典的 Sigmoid 函数(对于 x 返回一个介于 0.01.0 之间的值)

    activation(double x) {
      return 1 / (1 + exp(-x)) ;
    }
    
  • ActivationFunctionSigmoidFast:

    Sigmoid 函数的快速近似版本,不基于 exp(x)

    activation(double x) {
      x *= 3 ;
      return 0.5 + ((x) / (2.5 + x.abs()) / 2) ;
    }
    

    函数作者:Graciliano M. Passos:[gmpassos@GitHub][github]。

  • ActivationFunctionSigmoidBoundedFast:

    Sigmoid 函数的快速近似版本,不基于 exp(x)
    并将 [x] 限制在较低和较高的范围内。

    activation(double x) {
      if (x < lowerLimit) {
        return 0.0 ;
      } else if (x > upperLimit) {
        return 1.0 ;
      }
      x = x / scale ;
      return 0.5 + (x / (1 + (x * x))) ;
    }
    

    函数作者:Graciliano M. Passos:[gmpassos@GitHub][github]。

exp(x)

exp 是自然指数函数,
e 的 x 次方。

这是重要的 ANN 函数,因为它被流行的
Sigmoid 函数使用,并且通常高精度版本速度较慢,
而近似版本可用于大多数 ANN 模型和训练
算法。

快速数学

包含一个内部的快速数学库,可用于计算
exp(指数函数)效率不高的平台。

您可以导入此库并使用它来创建专门的
ActivationFunction 实现,或在任何项目中进行使用。

import 'package:eneural_net/eneural_net_fast_math.dart' as fast_math ;

void main() {
  // Fast Exponential function:
  var o = fast_math.exp(2);

  // Fast Exponential function with high precision:
  var highPrecision = <double>[0.0 , 0.0];
  var oHighPrecision = fast_math.expHighPrecision(2, 0.0, highPrecision);
  
  // Fast Exponential function with SIMD acceleration:
  var o32x4 = fast_math.expFloat32x4( Float32x4(2,3,4,5) );
}

该实现基于 Dart 包 Complex

fast_math.expFloat32x4 函数由 Graciliano M. Passos ([gmpassos@GitHub][github]) 创建。

GitHub

https://github.com/eneural-net/eneural_net_dart