public static IActivationFunction GetActivationFunction(ActivationFunction activationFunction) { IActivationFunction result; switch (activationFunction) { case ActivationFunction.ELU: result = new ELU(); break; case ActivationFunction.ReLU: result = new ReLU(); break; case ActivationFunction.Sigmoid: result = new Sigmoid(); break; case ActivationFunction.None: result = null; break; case ActivationFunction.Swish: result = new Swish(); break; default: result = new ReLU(); break; } return(result); }
public void Load(byte[] data) { var memStream = new MemoryStream(); var binForm = new BinaryFormatter(); memStream.Write(data, 0, data.Length); memStream.Seek(0, SeekOrigin.Begin); var obj = (SaveNetworkModel)binForm.Deserialize(memStream); var layers = new List <ILayer>(); Layers = null; foreach (var layer in obj.Layers) { var function = new BipolarSigmoid(); var relu = new ELU(); if (layer.Type == LayerType.Convolution) { layers.Add(new ConvolutionalLayer(layer.ActivationType, layer.OutputLength, layer.KernelSize)); } if (layer.Type == LayerType.MaxPoolingLayer) { layers.Add(new MaxPoolingLayer(layer.KernelSize)); } if (layer.Type == LayerType.FullyConnected) { layers.Add(new FullyConnectedLayer(layer.OutputLength, layer.ActivationType)); } } InitLayers(obj.InputWidth, obj.InputHeight, layers.ToArray()); for (var l = 0; l < Layers.Length; l++) { if (Layers[l].Type == LayerType.Convolution) { var layer = (ConvolutionalLayer)Layers[l]; for (var n = 0; n < layer.NeuronsCount; n++) { layer.Neurons[n].Weights = obj.Layers[l].ConvNeurons[n].Weights; } } if (Layers[l].Type == LayerType.FullyConnected) { var layer = (FullyConnectedLayer)Layers[l]; for (var n = 0; n < layer.NeuronsCount; n++) { layer.Neurons[n].Weights = obj.Layers[l].FullyConnectedNeurons[n].Weights; } } } }
public Layer(int nCount, int index, ActivationSettings activationSettings) { NCount = nCount; Index = index; ActivationType = activationSettings.Type(); // Activation Setup switch (activationSettings.Type()) { case EActivationType.Invalid: Activation = null; throw new ArgumentException("Activation Type Invalid."); case EActivationType.Arctan: Activation = new Arctan(); break; case EActivationType.BinaryStep: Activation = new BinaryStep(); break; case EActivationType.BipolarSigmoid: Activation = new BipolarSigmoid(); break; case EActivationType.ELU: Activation = new ELU((ELUSettings)activationSettings); break; case EActivationType.HardSigmoid: Activation = new HardSigmoid(); break; case EActivationType.HardTanh: Activation = new HardTanh(); break; case EActivationType.Identity: Activation = new Identity(); break; case EActivationType.Logit: Activation = new Logit(); break; case EActivationType.LReLU: Activation = new LReLU((LReLUSettings)activationSettings); break; case EActivationType.Mish: Activation = new Mish(); break; case EActivationType.ReLU: Activation = new ReLU(); break; case EActivationType.SeLU: Activation = new SeLU(); break; case EActivationType.Sigmoid: Activation = new Sigmoid(); break; case EActivationType.Softmax: Activation = new Softmax(); break; case EActivationType.Softplus: Activation = new Softplus(); break; case EActivationType.Softsign: Activation = new Softsign(); break; case EActivationType.Tanh: Activation = new Tanh(); break; default: throw new ArgumentException("Activation Type Invalid."); } }
public static void Run(bool verbose) { Stopwatch sw = new Stopwatch(); NdArray inputArrayCpu = new NdArray(BenchDataMaker.GetRealArray(INPUT_SIZE)); NdArray inputArrayGpu = new NdArray(BenchDataMaker.GetRealArray(INPUT_SIZE)); Ensure.Argument(inputArrayGpu).NotNull(); Ensure.Argument(inputArrayCpu).NotNull(); //Linear Linear linear = new Linear(verbose, INPUT_SIZE, OUTPUT_SIZE); if (verbose) { RILogManager.Default?.EnterMethod(linear.Name); } sw.Restart(); NdArray[] gradArrayCpu = linear.Forward(verbose, inputArrayCpu); sw.Stop(); if (verbose) { RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); } Ensure.Argument(gradArrayCpu).NotNull(); gradArrayCpu[0].Grad = gradArrayCpu[0].Data; // Use Data as Grad sw.Restart(); linear.Backward(verbose, gradArrayCpu); sw.Stop(); if (verbose) { RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); } if (linear.SetGpuEnable(true)) { sw.Restart(); NdArray[] gradArrayGpu = linear.Forward(verbose, inputArrayGpu); sw.Stop(); if (verbose) { RILogManager.Default?.SendDebug("Forward [Gpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); } gradArrayGpu[0].Grad = gradArrayGpu[0].Data; sw.Restart(); linear.Backward(verbose, gradArrayGpu); sw.Stop(); if (verbose) { RILogManager.Default?.SendDebug("Backward[Gpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); } } if (verbose) { RILogManager.Default?.ExitMethod(linear.Name); } //Tanh Tanh tanh = new Tanh(); if (verbose) { RILogManager.Default?.EnterMethod(tanh.Name); } sw.Restart(); gradArrayCpu = tanh.Forward(verbose, inputArrayCpu); sw.Stop(); if (verbose) { RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); } gradArrayCpu[0].Grad = gradArrayCpu[0].Data; sw.Restart(); tanh.Backward(verbose, gradArrayCpu); sw.Stop(); if (verbose) { RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); } if (tanh.SetGpuEnable(true)) { HandleGPU(verbose, sw, tanh, inputArrayGpu); } if (verbose) { RILogManager.Default?.ExitMethod(tanh.Name); } //Sigmoid Sigmoid sigmoid = new Sigmoid(); if (verbose) { RILogManager.Default?.EnterMethod(sigmoid.Name); } sw.Restart(); gradArrayCpu = sigmoid.Forward(verbose, inputArrayCpu); sw.Stop(); if (verbose) { RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); } gradArrayCpu[0].Grad = gradArrayCpu[0].Data; sw.Restart(); sigmoid.Backward(verbose, gradArrayCpu); sw.Stop(); if (verbose) { RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); } if (sigmoid.SetGpuEnable(true)) { HandleGPU(verbose, sw, sigmoid, inputArrayGpu); } if (verbose) { RILogManager.Default?.ExitMethod(tanh.Name); } //Softmax Softmax sm = new Softmax(); RILogManager.Default?.EnterMethod(sm.Name); sw.Restart(); gradArrayCpu = sm.Forward(verbose, inputArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); gradArrayCpu[0].Grad = gradArrayCpu[0].Data; sw.Restart(); sm.Backward(verbose, gradArrayCpu); sw.Stop(); if (verbose) { RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); } if (verbose) { RILogManager.Default?.ExitMethod(sm.Name); } //Softplus Softplus sp = new Softplus(); if (verbose) { RILogManager.Default?.EnterMethod(sp.Name); } sw.Restart(); gradArrayCpu = sp.Forward(verbose, inputArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); gradArrayCpu[0].Grad = gradArrayCpu[0].Data; sw.Restart(); sp.Backward(verbose, gradArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); RILogManager.Default?.ExitMethod(sp.Name); //ReLU ReLU relu = new ReLU(); RILogManager.Default?.EnterMethod(relu.Name); sw.Restart(); gradArrayCpu = relu.Forward(verbose, inputArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); gradArrayCpu[0].Grad = gradArrayCpu[0].Data; sw.Restart(); relu.Backward(verbose, gradArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); if (relu.SetGpuEnable(true)) { HandleGPU(verbose, sw, relu, inputArrayGpu); } RILogManager.Default?.ExitMethod(relu.Name); //LeakyReLU LeakyReLU leakyRelu = new LeakyReLU(); RILogManager.Default?.EnterMethod(leakyRelu.Name); sw.Restart(); gradArrayCpu = leakyRelu.Forward(verbose, inputArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); gradArrayCpu[0].Grad = gradArrayCpu[0].Data; sw.Restart(); leakyRelu.Backward(verbose, gradArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); if (leakyRelu.SetGpuEnable(true)) { HandleGPU(verbose, sw, leakyRelu, inputArrayGpu); } RILogManager.Default?.ExitMethod(leakyRelu.Name); //ReLuTanh ReLuTanh rth = new ReLuTanh(); RILogManager.Default?.EnterMethod(rth.Name); sw.Restart(); gradArrayCpu = rth.Forward(verbose, inputArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); gradArrayCpu[0].Grad = gradArrayCpu[0].Data; sw.Restart(); rth.Backward(verbose, gradArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); if (rth.SetGpuEnable(true)) { HandleGPU(verbose, sw, rth, inputArrayGpu); } RILogManager.Default?.ExitMethod(rth.Name); ////Swish //Swish swi = new Swish(); //RILogManager.Default?.SendDebug(swi.Name); //sw.Restart(); //gradArrayCpu = swi.Forward(inputArrayCpu); //sw.Stop(); //RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); //gradArrayCpu[0].Grad = gradArrayCpu[0].Data; //sw.Restart(); //swi.Backward(gradArrayCpu); //sw.Stop(); //RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); NdArray inputImageArrayGpu = new NdArray(BenchDataMaker.GetRealArray(3 * 256 * 256 * 5), new[] { 3, 256, 256 }, 5); NdArray inputImageArrayCpu = new NdArray(BenchDataMaker.GetRealArray(3 * 256 * 256 * 5), new[] { 3, 256, 256 }, 5); //MaxPooling MaxPooling maxPooling = new MaxPooling(3); RILogManager.Default?.EnterMethod(maxPooling.Name); sw.Restart(); NdArray[] gradImageArrayCpu = maxPooling.Forward(verbose, inputImageArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); gradImageArrayCpu[0].Grad = gradImageArrayCpu[0].Data; sw.Restart(); maxPooling.Backward(verbose, gradImageArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); if (maxPooling.SetGpuEnable(true)) { sw.Restart(); maxPooling.Forward(verbose, inputImageArrayGpu); sw.Stop(); RILogManager.Default?.SendDebug("Forward [Gpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); // There is no implementation for memory transfer only RILogManager.Default?.SendDebug("Backward[Gpu] : None"); } RILogManager.Default?.ExitMethod(maxPooling.Name); //AvgPooling AveragePooling avgPooling = new AveragePooling(3); RILogManager.Default?.EnterMethod(avgPooling.Name); sw.Restart(); gradImageArrayCpu = avgPooling.Forward(verbose, inputImageArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); gradImageArrayCpu[0].Grad = gradImageArrayCpu[0].Data; sw.Restart(); avgPooling.Backward(verbose, gradImageArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); RILogManager.Default?.ExitMethod(avgPooling.Name); //Conv2D Convolution2D conv2d = new Convolution2D(verbose, 3, 3, 3); RILogManager.Default?.EnterMethod(conv2d.Name); sw.Restart(); gradImageArrayCpu = conv2d.Forward(verbose, inputImageArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); gradImageArrayCpu[0].Grad = gradImageArrayCpu[0].Data; sw.Restart(); conv2d.Backward(verbose, gradImageArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); if (conv2d.SetGpuEnable(true)) { HandleGPU(verbose, sw, conv2d, inputArrayGpu); } RILogManager.Default?.ExitMethod(conv2d.Name); //Deconv2D Deconvolution2D deconv2d = new Deconvolution2D(verbose, 3, 3, 3); RILogManager.Default?.EnterMethod(deconv2d.Name); sw.Restart(); gradImageArrayCpu = deconv2d.Forward(verbose, inputImageArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); gradImageArrayCpu[0].Grad = gradImageArrayCpu[0].Data; sw.Restart(); deconv2d.Backward(verbose, gradImageArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); if (deconv2d.SetGpuEnable(true)) { HandleGPU(verbose, sw, deconv2d, inputArrayGpu); } RILogManager.Default?.ExitMethod(deconv2d.Name); //Dropout Dropout dropout = new Dropout(); RILogManager.Default?.EnterMethod(dropout.Name); sw.Restart(); gradArrayCpu = dropout.Forward(verbose, inputArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); gradArrayCpu[0].Grad = gradArrayCpu[0].Data; sw.Restart(); dropout.Backward(verbose, gradArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); if (dropout.SetGpuEnable(true)) { sw.Restart(); NdArray[] gradArrayGpu = dropout.Forward(verbose, inputArrayGpu); sw.Stop(); RILogManager.Default?.SendDebug("Forward [Gpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); gradArrayGpu[0].Grad = gradArrayGpu[0].Data; sw.Restart(); dropout.Backward(verbose, gradArrayGpu); sw.Stop(); RILogManager.Default?.SendDebug("Backward[Gpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); } RILogManager.Default?.ExitMethod(dropout.Name); //ArcSinH ArcSinH a = new ArcSinH(); RILogManager.Default?.EnterMethod(a.Name); sw.Restart(); gradArrayCpu = a.Forward(verbose, inputArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); gradArrayCpu[0].Grad = gradArrayCpu[0].Data; sw.Restart(); a.Backward(verbose, gradArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); if (a.SetGpuEnable(true)) { HandleGPU(verbose, sw, a, inputArrayGpu); } RILogManager.Default?.ExitMethod(a.Name); //ELU ELU e = new ELU(); RILogManager.Default?.EnterMethod(e.Name); sw.Restart(); gradArrayCpu = e.Forward(verbose, inputArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); gradArrayCpu[0].Grad = gradArrayCpu[0].Data; sw.Restart(); e.Backward(verbose, gradArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); RILogManager.Default?.ExitMethod(e.Name); //LeakyReluShifted LeakyReLUShifted lrs = new LeakyReLUShifted(); RILogManager.Default?.EnterMethod(lrs.Name); sw.Restart(); gradArrayCpu = lrs.Forward(verbose, inputArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); gradArrayCpu[0].Grad = gradArrayCpu[0].Data; sw.Restart(); lrs.Backward(verbose, gradArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); if (lrs.SetGpuEnable(true)) { HandleGPU(verbose, sw, lrs, inputArrayGpu); } RILogManager.Default?.ExitMethod(lrs.Name); //Logistic LogisticFunction lf = new LogisticFunction(); RILogManager.Default?.EnterMethod(lf.Name); sw.Restart(); gradArrayCpu = lf.Forward(verbose, inputArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); gradArrayCpu[0].Grad = gradArrayCpu[0].Data; sw.Restart(); lf.Backward(verbose, gradArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); if (lf.SetGpuEnable(true)) { HandleGPU(verbose, sw, lf, inputArrayGpu); } RILogManager.Default?.ExitMethod(lf.Name); //MaxMinusOne MaxMinusOne mmo = new MaxMinusOne(); RILogManager.Default?.EnterMethod(mmo.Name); sw.Restart(); gradArrayCpu = mmo.Forward(verbose, inputArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); gradArrayCpu[0].Grad = gradArrayCpu[0].Data; sw.Restart(); mmo.Backward(verbose, gradArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); if (mmo.SetGpuEnable(true)) { HandleGPU(verbose, sw, mmo, inputArrayGpu); } RILogManager.Default?.ExitMethod(mmo.Name); //ScaledELU ScaledELU se = new ScaledELU(); RILogManager.Default?.EnterMethod(se.Name); sw.Restart(); gradArrayCpu = se.Forward(verbose, inputArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); gradArrayCpu[0].Grad = gradArrayCpu[0].Data; sw.Restart(); se.Backward(verbose, gradArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); if (se.SetGpuEnable(true)) { HandleGPU(verbose, sw, se, inputArrayGpu); } RILogManager.Default?.ExitMethod(se.Name); //Sine Sine s = new Sine(); RILogManager.Default?.EnterMethod(s.Name); sw.Restart(); gradArrayCpu = s.Forward(verbose, inputArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Forward [Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); gradArrayCpu[0].Grad = gradArrayCpu[0].Data; sw.Restart(); s.Backward(verbose, gradArrayCpu); sw.Stop(); RILogManager.Default?.SendDebug("Backward[Cpu] : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); if (s.SetGpuEnable(true)) { HandleGPU(verbose, sw, s, inputArrayGpu); } RILogManager.Default?.ExitMethod(s.Name); }