NeuralNetwork.net est une bibliothèque .NET Standard 2.0 qui implémente les réseaux de neurones séquentiels et de calcul avec des couches personnalisables, construites à partir de zéro avec C #. Il fournit des API simples conçues pour un prototypage rapide afin de définir et de former des modèles en utilisant une descente de gradient stochastique, ainsi que des méthodes pour enregistrer / charger un modèle de réseau et ses métadonnées et plus encore. La bibliothèque expose également les couches accélérées par Cuda avec des fonctionnalités plus avancées qui exploitent le GPU et la boîte à outils CUDNN pour augmenter considérablement les performances lors de la formation ou de l'utilisation d'un réseau de neurones.
Avertissement: cette bibliothèque est fournie telle qu'elle est, et elle n'est plus activement entretenue. NeuralNetwork.net a été développé lors d'un cours universitaire et il n'est pas censé remplacer d'autres cadres d'apprentissage automatique bien connu. Si vous recherchez une bibliothèque d'apprentissage automatique pour .NET à utiliser en production, je recommande d'essayer ML.NET ou de Tensorflow.net alternativement.
Pour installer neuralnetwork.net , exécutez la commande suivante dans la console du gestionnaire de packages
Install-Package NeuralNetwork.NET
Plus de détails disponibles ici.
La bibliothèque NeuralNetwork.net expose des classes et méthodes faciles à utiliser pour créer un nouveau réseau neuronal, préparer les ensembles de données pour utiliser et former le réseau. Ces API sont conçues pour un prototypage rapide, et cette section donne un aperçu des étapes requises pour commencer.
La première étape consiste à créer une structure de réseau personnalisée. Voici un exemple avec un réseau séquentiel (une pile de couches):
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 ) ) ;
L'étape suivante consiste à préparer les ensembles de données à utiliser, via les API de la classe DatasetLoader
:
// 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
} ) ;
La formation d'un réseau neuronal est assez simple - utilisez simplement les méthodes de la classe NetworkManager
:
// 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
Remarque: Les méthodes NetworkManager
sont également disponibles en tant qu'API asynchrones.
Lorsque vous exécutez un framework pris en charge (.NET Framework, Xamarin ou Mono), il est possible d'utiliser une implémentation différente des couches disponibles qui exploite la boîte à outils CUDNN et parallélise la plupart des travaux sur le GPU compatible CUDA disponible. Pour ce faire, utilisez simplement les couches de la classe CuDnnNetworkLayers
lors de la création d'un réseau.
Certaines des couches alimentées par CUDNN prennent en charge les options supplémentaires que les couches par défaut. Voici un exemple:
// 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
Ces instances LayerFactory
peuvent être utilisées pour créer un nouveau réseau comme dans l'exemple CPU.
Remarque: Pour utiliser cette fonctionnalité, les kits d'outils CUDA et CUDNN doivent être installés sur le système actuel, un GPU NVIDIA GEFORCE / Quadro compatible CUDA doit être disponible et le package ALEA NUGET doit être installé dans l'application à l'aide du NeuralNetwork.net bibliothèque aussi. Des informations supplémentaires sont disponibles ici.
Certaines structures de réseaux complexes, comme les réseaux résiduels ou les modules de création, ne peuvent pas être exprimés comme une simple structure de réseau séquentielle: c'est là que les réseaux de graphiques de calcul entrent en jeu. Au lieu de transmettre les entrées via une pile linéaire de couches, un graphique de calcul a une structure spatiale spécifique qui permet à différents nœuds d'être connectés ensemble. Par exemple, il est possible de canaliser les données via différents pipelines parallèles qui sont fusionnés plus tard dans le graphique, ou d'avoir des classificateurs auxiliaires qui contribuent à la rétro-propagation du gradient pendant la phase de formation.
Les réseaux de graphiques de calcul sont créés à l'aide de l'API NetworkManager.NewGraph
, voici un exemple:
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 ) ) ;
} ) ;
NeuralNetwork.net fournit divers paramètres partagés disponibles via la classe NetworkSettings
. Cette classe agit comme un conteneur pour vérifier et modifier rapidement tout paramètre à tout moment, et ces paramètres influenceront le comportement de toute instance INeuralNetwork
existante et de la bibliothèque en général.
Par exemple, il est possible de personnaliser les critères utilisés par les réseaux pour vérifier leurs performances pendant la formation
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
Lorsque vous utilisez des réseaux alimentés par CUDA, parfois le GPU utilisé peut ne pas être en mesure de traiter l'ensemble des ensembles de données de test ou de validation en une seule réussite, ce qui est le comportement par défaut (ces ensembles de données ne sont pas divisés en lots). Pour éviter les problèmes de mémoire, il est possible de modifier ce comportement:
NetworkSettings . MaximumBatchSize = 400 ; // This will apply to any test or validation dataset
L'interface INeuralNetwork
expose une méthode Save
qui peut être utilisée pour sérialiser n'importe quel réseau à tout moment. Afin d'obtenir une nouvelle instance réseau à partir d'un fichier ou d'un flux enregistré, utilisez simplement la méthode NetworkLoader.TryLoad
.
Étant donné que plusieurs types de couches ont des implémentations différentes entre les bibliothèques disponibles, vous pouvez spécifier les fournisseurs de couche à utiliser lors du chargement d'un réseau enregistré. Par exemple, voici comment charger un réseau à l'aide des couches CUDNN, lorsque cela est possible:
FileInfo file = new FileInfo ( @"C:...MySavedNetwork.nnet" ) ;
INeuralNetwork network = NetworkLoader . TryLoad ( file , ExecutionModePreference . Cuda ) ;
Remarque: L'option ExecutionModePreference
indique le type de couches souhaité à désérialiser chaque fois que possible. Par exemple, en utilisant ExecutionModePreference.Cpu
, le réseau chargé n'aura que des couches alimentées par CPU, si elle est prise en charge.
Il existe également une méthode supplémentaire SaveMetadataAsJson
pour exporter les métadonnées d'une instance INeuralNetwork
.
L'espace de noms NeuralNetworkNET.Datasets
comprend des classes statiques pour charger rapidement un ensemble de données populaire et obtenir une instance IDataset
prête à l'emploi avec un nouveau réseau neuronal. À titre d'exemple, voici comment obtenir l'ensemble de données MNIST:
ITrainingDataset trainingData = await Mnist . GetTrainingDatasetAsync ( 400 ) ; // Batches of 400 samples
ITestDataset testData = await Mnist . GetTestDatasetAsync ( p => .. . /* Optional callback */ ) ;
Chaque API de cet espace de noms prend également en charge un CancellationToken
facultatif pour arrêter le chargement de l'ensemble de données, car les données source sont téléchargées à partir d'Internet et peuvent prendre un certain temps pour être disponible, selon l'ensemble de données utilisé.
La bibliothèque NeuralNetWork.Net nécessite une prise en charge de .NET Standard 2.0, il est donc disponible pour le ciblage des applications:
En plus des frameworks ci-dessus, vous avez besoin d'un IDE avec une prise en charge C # 7.3 pour compiler la bibliothèque sur votre PC.