Giter Site home page Giter Site logo

sergio0694 / neuralnetwork.net Goto Github PK

View Code? Open in Web Editor NEW
535.0 35.0 82.0 13.42 MB

A TensorFlow-inspired neural network library built from scratch in C# 7.3 for .NET Standard 2.0, with GPU support through cuDNN

License: GNU General Public License v3.0

C# 100.00%
neural-network convolutional-neural-networks backpropagation-algorithm gradient-descent machine-learning classification-algorithims cnn supervised-learning ai cuda

neuralnetwork.net's Introduction

Get it from NuGet ScuSharp STACK

NuGet NuGet AppVeyor AppVeyor tests Twitter Follow

What is it?

NeuralNetwork.NET is a .NET Standard 2.0 library that implements sequential and computation graph neural networks with customizable layers, built from scratch with C#. It provides simple APIs designed for quick prototyping to define and train models using stochastic gradient descent, as well as methods to save/load a network model and its metadata and more. The library also exposes CUDA-accelerated layers with more advanced features that leverage the GPU and the cuDNN toolkit to greatly increase the performances when training or using a neural network.

DISCLAIMER: this library is provided as is, and it's no longer being actively maintained. NeuralNetwork.NET was developed during a university course and it's not meant to be a replacement for other well known machine learning frameworks. If you're looking for a machine learning library for .NET to use in production, I recommend trying out ML.NET or alternatively TensorFlow.NET.

Table of Contents

Installing from NuGet

To install NeuralNetwork.NET, run the following command in the Package Manager Console

Install-Package NeuralNetwork.NET

More details available here.

Quick start

The NeuralNetwork.NET library exposes easy to use classes and methods to create a new neural network, prepare the datasets to use and train the network. These APIs are designed for rapid prototyping, and this section provides an overview of the required steps to get started.

Supervised learning

The first step is to create a custom network structure. Here is an example with a sequential network (a stack of layers):

INeuralNetwork network = NetworkManager.NewSequential(TensorInfo.Image<Alpha8>(28, 28),
    NetworkLayers.Convolutional((5, 5), 20, ActivationType.Identity),
    NetworkLayers.Pooling(ActivationType.LeakyReLU),
    NetworkLayers.Convolutional((3, 3), 40, ActivationType.Identity),
    NetworkLayers.Pooling(ActivationType.LeakyReLU),
    NetworkLayers.FullyConnected(125, ActivationType.LeakyReLU),
    NetworkLayers.FullyConnected(64, ActivationType.LeakyReLU),
    NetworkLayers.Softmax(10));

The next step is to prepare the datasets to use, through the APIs in the DatasetLoader class:

// A training dataset with a batch size of 100
IEnumerable<(float[] x, float[] u)> data = ... // Your own dataset parsing routine
ITrainingDataset dataset = DatasetLoader.Training(data, 100);

// An optional test dataset with a callback to monitor the progress
ITestDataset test = DatasetLoader.Test(..., p =>
{
    Console.WriteLine($"Epoch {p.Iteration}, cost: {p.Cost}, accuracy: {p.Accuracy}"); // Progress report
});

Training a neural network is pretty straightforward - just use the methods in the NetworkManager class:

// Train the network using Adadelta and 0.5 dropout probability
TrainingSessionResult result = NetworkManager.TrainNetwork(
    network,                                // The network instance to train
    dataset,                                // The ITrainingDataset instance   
    TrainingAlgorithms.AdaDelta(),          // The training algorithm to use
    60,                                     // The expected number of training epochs to run
    0.5f,                                   // Dropout probability
    p => ...,                               // Optional training epoch progress callback
    null,                                   // Optional callback to monitor the training dataset accuracy
    null,                                   // Optional validation dataset
    test,                                   // Test dataset
    token);                                 // Cancellation token for the training

Note: the NetworkManager methods are also available as asynchronous APIs.

GPU acceleration

When running on a supported framework (.NET Framework, Xamarin or Mono), it is possible to use a different implementation of the available layers that leverages the cuDNN toolkit and parallelizes most of the work on the available CUDA-enabled GPU. To do that, just use the layers from the CuDnnNetworkLayers class when creating a network.

Some of the cuDNN-powered layers support additional options than the default layers. Here's an example:

// A cuDNN convolutional layer, with custom mode, padding and stride
LayerFactory convolutional = CuDnnNetworkLayers.Convolutional(
    ConvolutionInfo.New(ConvolutionMode.CrossCorrelation, 3, 3, 2, 2),
    (7, 7), 20, ActivationType.ReLU);
    
// An inception module, from the design of the GoogLeNet network
LayerFactory inception = CuDnnNetworkLayers.Inception(InceptionInfo.New(
    10,     // 1x1 convolution kernels
    20, 10, // 1x1 + 3x3 convolution pipeline kernels
    20, 10, // 1x1 + 5x5 convolution pipeline kernels
    PoolingMode.AverageExcludingPadding, 10)); // Pooling mode and 1x1 convolution kernels

These LayerFactory instances can be used to create a new network just like in the CPU example.

NOTE: in order to use this feature, the CUDA and cuDNN toolkits must be installed on the current system, a CUDA-enabled nVidia GeForce/Quadro GPU must be available and the Alea NuGet package must be installed in the application using the NeuralNetwork.NET library as well. Additional info are available here.

Computation graphs

Some complex network structures, like residual networks or inception modules , cannot be expressed as a simple sequential network structure: this is where computation graph networks come into play. Instead of forwarding the inputs through a linear stack of layers, a computation graph has a specific spatial structure that allows different nodes to be connected together. For example, it is possible to channel data through different parallel pipelines that are merged later on in the graph, or to have auxiliary classifiers that contribute to the gradient backpropagation during the training phase.

Computation graph networks are created using the NetworkManager.NewGraph API, here's an example:

INeuralNetwork network = NetworkManager.NewGraph(TensorInfo.Image<Rgb24>(32,32), root =>
{
    var conv1 = root.Layer(CuDnnNetworkLayers.Convolutional((5, 5), 20, ActivationType.Identity));
    var pool1 = conv1.Layer(CuDnnNetworkLayers.Pooling(ActivationType.ReLU));

    var conv2 = pool1.Pipeline(
        CuDnnNetworkLayers.Convolutional((1, 1), 20, ActivationType.ReLU),
        CuDnnNetworkLayers.Convolutional(ConvolutionInfo.Same(), (5, 5), 40, ActivationType.ReLU),
        CuDnnNetworkLayers.Convolutional((1, 1), 20, ActivationType.ReLU));
    var sum = conv2 + pool1;

    var fc1 = sum.Layer(CuDnnNetworkLayers.FullyConnected(250, ActivationType.LeCunTanh));
    var fc2 = fc1.Layer(CuDnnNetworkLayers.FullyConnected(125, ActivationType.LeCunTanh));
    _ = fc2.Layer(CuDnnNetworkLayers.Softmax(10));
});

Library settings

NeuralNetwork.NET provides various shared settings that are available through the NetworkSettings class. This class acts as a container to quickly check and modify any setting at any time, and these settings will influence the behavior of any existing INeuralNetwork instance and the library in general.

For example, it is possible to customize the criteria used by the networks to check their performance during training

NetworkSettings.AccuracyTester = AccuracyTesters.Argmax();       // The default mode (mutually-exclusive classes)

// Other testers are available too
NetworkSettings.AccuracyTester = AccuracyTesters.Threshold();    // Useful for overlapping classes
NetworkSettings.AccuracyTester = AccuracyTesters.Distance(0.2f); // Distance between results and expected outputs

When using CUDA-powered networks, sometimes the GPU in use might not be able to process the whole test or validation datasets in a single pass, which is the default behavior (these datasets are not divided into batches). To avoid memory issues, it is possible to modify this behavior:

NetworkSettings.MaximumBatchSize = 400;   // This will apply to any test or validation dataset

Serialization and deserialization

The INeuralNetwork interface exposes a Save method that can be used to serialize any network at any given time. In order to get a new network instance from a saved file or stream, just use the NetworkLoader.TryLoad method.

As multiple layer types have different implementations across the available libraries, you can specify the layer providers to use when loading a saved network. For example, here's how to load a network using the cuDNN layers, when possible:

FileInfo file = new FileInfo(@"C:\...\MySavedNetwork.nnet");
INeuralNetwork network = NetworkLoader.TryLoad(file, ExecutionModePreference.Cuda);

Note: the ExecutionModePreference option indicates the desired type of layers to deserialize whenever possible. For example, using ExecutionModePreference.Cpu, the loaded network will only have CPU-powered layers, if supported.

There's also an additional SaveMetadataAsJson method to export the metadata of an INeuralNetwork instance.

Built-in datasets

The NeuralNetworkNET.Datasets namespace includes static classes to quickly load a popular dataset and get an IDataset instance ready to use with a new neural network. As an example, here's how to get the MNIST dataset:

ITrainingDataset trainingData = await Mnist.GetTrainingDatasetAsync(400); // Batches of 400 samples
ITestDataset testData = await Mnist.GetTestDatasetAsync(p => ... /* Optional callback */);

Each API in this namespace also supports an optional CancellationToken to stop the dataset loading, as the source data is downloaded from the internet and can take some time to be available, depending on the dataset being used.

Requirements

The NeuralNetwork.NET library requires .NET Standard 2.0 support, so it is available for applications targeting:

  • .NET Framework >= 4.6.1
  • .NET Core >= 2.0
  • UWP (from SDK 10.0.16299)
  • Mono >= 5.4
  • Xamarin.iOS 10.14, Xamarin.Mac 3.8, Xamarin.Android 8.0

In addition to the frameworks above, you need an IDE with C# 7.3 support to compile the library on your PC.

neuralnetwork.net's People

Contributors

dariooo512 avatar sergio0694 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

neuralnetwork.net's Issues

Failing to Load Saved Model

I'm finding the library very useful, however I've noticed that the TryLoad for loading a saved model fails and always returns null.

I'm training and saving the model with the below code;

var result = NetworkManager.TrainNetwork(
                network,                                                  
                trainingDataSet,                                           
                TrainingAlgorithms.AdaDelta(),                                 
                _epochsToRun,                                               
                _dropoutProb,                                      
                null,                                                        
                (prog) =>
                {
                    _currentTrainAccuracy = prog.Result.Accuracy;
                    _currentTrainCost = prog.Result.Cost;
                },                                                          
                null,                                                            
                testingDataSet,                                                
                cancellationToken.ShutdownToken);                                 

var fileInfo = new FileInfo(_settings.NeuralNetworkFilePath);
network.Save(fileInfo);

And then loading with the following;

var fileInfo = new FileInfo(_settings.NeuralNetworkFilePath);
var model = NetworkLoader.TryLoad(fileInfo, ExecutionModePreference.Cpu);

However, the model is always null, regardless of the file I try to load.

I've taken a look at the serialization and deserialization and noticed the issue occurs in the FullyConnectedLayer's Deserialize function.

public static INetworkLayer Deserialize([NotNull] Stream stream)
        {
            if (!stream.TryRead(out TensorInfo input)) return null;
            if (!stream.TryRead(out TensorInfo output)) return null;
            if (!stream.TryRead(out ActivationType activation)) return null;
            if (!stream.TryRead(out int wLength)) return null;
            float[] weights = stream.ReadUnshuffled(wLength);
            if (!stream.TryRead(out int bLength)) return null;
            float[] biases = stream.ReadUnshuffled(bLength);
            return new FullyConnectedLayer(input, output.Size, weights, biases, activation);
        }

I monitored the bytes being stored in the serialization for the lengths of the weights and bias arrays, and noticed that the wLength value is correctly read from the stream, but when it gets to reading the bLength value, the bytes read are entirely different to those that were recorded and an exception is thrown because bLength becomes an absurdly large or small number and an array of that size isn't possible to create.

My assumption is that there's some issue with the reading of weights that ends up moving the stream position to the wrong place, but streams aren't exactly something I'm overly used to working with!

I'm aware this project is no longer maintained, but if anyone could suggest a workaround or fix, it'd certainly be helpful and very much appreciated!

I was able to quickly reproduce the problem by creating a new CLI project and using the following Program.cs;

using NeuralNetworkNET.APIs;
using NeuralNetworkNET.APIs.Structs;

var testNet = NetworkManager.NewSequential(TensorInfo.Linear(505),
    NetworkLayers.FullyConnected(14, NeuralNetworkNET.APIs.Enums.ActivationType.ReLU),
    NetworkLayers.Softmax(2));

testNet.Save(new FileInfo("D:\\TestNet.nnet"));

var file = "D:\\TestNet.nnet";
var fInfo = new FileInfo(file);
var model = NetworkLoader.TryLoad(fInfo, NeuralNetworkNET.APIs.Enums.ExecutionModePreference.Cpu);
var res = model != null;

Simple request: plain output

I need a plain output layer, I could also implement it myself if you give some hint.

I want to do a time series forecasting and it took a while to realize I was misusing the softmax layer which is not what I need.

I don't need the GPU version, so:

I think I should implement a subclass of OutputLayerBase that relies on some CpuDnn.SOMETHINGFORWARD.. correct?

Could not load file or assembly Alea when using CuDnnNetworkLayers

Expected Behavior

The instruction CuDnnNetworkLayers.IsCudaSupportAvailable should return True if Cuda is available, False otherwise

Current Behavior

Exception is raised:
System.IO.FileNotFoundException: 'Could not load file or assembly 'Alea, Version=3.0.0.0, Culture=neutral, PublicKeyToken=ba52afc3c2e933d6'.

Gym.NET/examples/AtariDeepQLearner/AtariDeepQLearner/Trainer.cs line 32

Steps to Reproduce

  1. Clone this repo (branch: dev)
  2. Go to folder examples/AtariDeepQLearner
  3. Set AtariDeepQLearner.Runner as startup project
  4. Run

Using Forward with CPU builded in CUDA

Hey Serio0694,
really nice libary. I love this libary.
For my question:
Iยดm able to train my network with cuda, save the network and load it with CPU only for the function "Forward" ?.
Thanks in advance.

Installation error by NuGet VS2015

I tried to install it on NuGet, but with error:

Could not install package 'NeuralNetwork.NET 2.1.3'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.6.1', but the package does not contain any assembly references or content files that are compatible with that framework.

could anyone help me ?

thanks

Import Tensorflow models

Is it possible to import TensorFlow models to this library? is it a feature? if not is it planned? if not again xD, is there a way that i can do that manually?

Reloading *.nnet TrainResult different

Dear Sergio,
After reloading the * .nnet file, the result in the train result is different. Before reloading 28% and after Reloading 24%. How come?

Great

Zeljko

replacement for Alea for CUDA?

I don't know if this project is actively maintained anymore, but just in case, I'd mention that I got it working fine with CPU but GPU/CUDA does not seem to work since the Alea file isn't found. Running in .NET Framework 7.0.

Graph Neural Networks possible?

I am trying to learn about Graph Neural Networks and wanted to know if they are possible to build using this library.

I see all of the basic building blocks, but I couldn't find how to create a layer that is connected in the same way as a graph, I was looking for someway to provide an adjacency list but was unsuccessful.

Is there an example to show how, or clarity on if it is possible with this library?

Thanks!

Simple XOR Problem

Thanks for the library, Sergio. I have a question that is similar to @quequiere's - I am trying to create a simple example (the XOR problem( to help understand your library but am struggling to get it to produce the correct results. Can you see what I'm doing incorrectly?

` var network = NetworkManager.NewSequential(TensorInfo.Linear(2),
NetworkLayers.FullyConnected(2, ActivationType.Sigmoid),
NetworkLayers.Softmax(1));

IEnumerable<(float[] x, float[] u)> data = new List<(float[] x, float[] u)>
{
	(new[] {0f, 0f}, new[] {0f}),
	(new[] {0f, 1f}, new[] {1f}),
	(new[] {1f, 0f}, new[] {1f}),
	(new[] {1f, 1f}, new[] {0f})
};

var trainingData = DatasetLoader.Training(data, 10);

var result = NetworkManager.TrainNetwork(
	network,
	trainingData,
	TrainingAlgorithms.StochasticGradientDescent(),
	100,
	0.5f,
	p => { Console.WriteLine($"Progress: {p.Percentage}%, Processed {p.ProcessedItems}"); },
	t => { Console.WriteLine($"Training: Iteration {t.Iteration}, Accuracy {t.Result.Accuracy}, Cost {t.Result.Cost}"); });

Console.WriteLine(network.Forward(new float[] { 0, 0 })[0]);
Console.WriteLine(network.Forward(new float[] { 0, 1 })[0]);
Console.WriteLine(network.Forward(new float[] { 1, 0 })[0]);
Console.WriteLine(network.Forward(new float[] { 1, 1 })[0]);`

Which version of cuDNN should I install?

Hello! I'm really intrested in your project. I read the thread #83 which says that the solution should work with cudnn64_5.dll. But all of I found here for cuda9 contains cudnn64_7.dll (for win10, or even win7). Where can I find properly versions of cuda and cudnn?

Getting alot of NumericOverflow.

TrainingStopReason.NumericOverflow. It happens quite a lot but the settings have a huge impact on how often. Is there a way to mitigate this?

Brilliant work btw!

Prediction

Hello, I accomplish to train the network by my own dataset,
but I dont know, how can I predict or classify (or simulate or whatever the name) any input data.

for example in matlap:
y=sim(net, x);

Thank you.

About NeuralNetwork.NET, interests and DeepLearningFramework.

Hi, I am Faruk. I found your repo via someone who was discussing some topic with me on Github. Special Thanks to Github for this.

I have been also developing a deep learning library in .NET 5 for 9 months and have developed the project enough to be considered as mature. I see you achieved NeuralNetwork.NET your own. That's a huge effort really. Thank you for that as well.

Your library seems to be similar to tensorflow. Do you have static or dynamic computation graph in the background?

My network type is dynamic graph like in pytorch. My aim is/was to develop a library to give the scientist the best experience and the most flexible library. To do so, I created multi-dimensional layers (unless you specify that it shouldn't be) and multi-inputs for an RNN layer etc. Because RNN layers are processed dynamically, there are many things you can do to control the flow of the network while it goes forward. So, how the flow will go may depend on the output of the current layer for example, or depend on the index (current time step value which is also multidimensional).

The layers that are ready to be used:
image

I separated the project into two subproject named: DeepLearningFramework and PerformanceWork.

Tensor, memory management and kernel implementations are in PerformanceWork. Other things like layers, terms, training procedures etc are in DeepLearningFramework.

The layers have terms inside them. The terms are the basic units of a graph. Terms can be thought as each box in the RNN representation. So, for each time step in a layer, there is a term corresponds to that time step. The time step is not just a number, but an n-dimensional tuple, because the network is multi-dimensional.

Example code for XOR model creation:
image

Example code for MNIST model creation:
image

The training procedure and loading data to the model are not ready for users. So, I semi-manually do that currently.

There are many things that I consider for future development such as Encoder-Decoder models and Multi-Task Learning. The library should be enough flexible to enable users to develop those models and the models that are not implemented yet in the world maybe.

Serialization is another topic that I give thoughts about. There are trade-offs between how flexible library and how easy to reload a model that is saved.

To sum up, my aim is to create the most flexible library, optimization is important of course but not the main target here. There are also distributed learning approaches for multi-GPU instances that I forgot to mention. It's pretty messed up thinking of those all together. Serialization, multi-GPU, encoder-decoder, multi-task learning... These are the things that are to be considered together while designing the library.

However, I have no strength to support my project. I believe that I have gained a lot of experience while developing the library. I also want to create it and propose to scientists and to my university maybe. Do you have any idea about how should I keep developing or should I? I'm trying to collaborate with people, but no one is coming. Every time, I write a lot of messages like this to explain the library. How did you manage to develop the library on your own? I mean it, it's really huge work. Congrats! Also, if you have enough time, you can check out my project. If you'd like to help me, I gladly accept that ๐Ÿ˜„

Compute neural network

Hi!
Sorry but I still don't understand how to compute neural network when the training is over.

Should I use:
network.ExtractDeepFeatures(input); ?

Thread-safe?

Awesome library! I wanted to ask if the library is thread-safe? We've been wanting to use it in an ASP.NET application to train (very small) NNs on the fly.

Feature Request: Add Mish activation

Mish is a new novel activation function proposed in this paper.
It has shown promising results so far and has been adopted in several packages including:

All benchmarks, analysis and links to official package implementations can be found in this repository

It would be nice to have Mish as an option within the activation function group.

This is the comparison of Mish with other conventional activation functions in a SEResNet-50 for CIFAR-10: (Better accuracy and faster than GELU)
se50_1

Is Alea relied on cuDNN 5.1?

I can not run the project DigitsCudaTest, error thrown noticed that 'Couldn't open CUDA library 'cudnn64_5''
Should i use cuDNN 5.1 or cuDNN 5.0 with CUDA 8.0?

Extremely frustrating beyond belief

Brilliant library. Beyond brilliant.
However:
Without at least one comprehensive sample trying to use ESP to figure out what the intended usage would be is ridiculous beyond belief.

Simple example:
How would we implement a tensor reshape operation between layers?
How would we implement a custom loss function?
etc...

This is such a brilliant library and quite a lot of work has been put into it. Shame there is not one comprehensive sample. Which results in hours and hours of wasted time trying to figure out howto use it.

As a matter of fact the only way to really figure it out is to download the master source. Then wade through the source code looking for a glimpse of maybe a unit test or some snippet of code from which the intended usage can be inferred.

@Sergio0694 Just because your IQ is way beyond most humans does not mean that you can expect the rest of us to operate at the same level. Why build and publish this library if you don't actually want anyone without Extra Sensory Perception and mind reading abilities to be able to use it?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.