NeuralNetwork.net ist eine .NET Standard 2.0 -Bibliothek, die sequentielle und berechnungsgrafische neuronale Netzwerke mit anpassbaren Ebenen implementiert, die von Grund auf mit C#erstellt wurden. Es bietet einfache APIs, die für schnelle Prototypen entwickelt wurden, um Modelle mit stochastischen Gradientenabfällen sowie Methoden zum Speichern/Laden eines Netzwerkmodells und seiner Metadaten und vielem mehr zu definieren und zu trainieren. Die Bibliothek enthält auch Cuda-beschleunigte Ebenen mit fortgeschritteneren Funktionen, die die GPU und das Cudnn Toolkit nutzen, um die Leistungen beim Training oder die Verwendung eines neuronalen Netzwerks erheblich zu erhöhen.
Haftungsausschluss: Diese Bibliothek wird so bereitgestellt und wird nicht mehr aktiv gepflegt. NeuralNetwork.net wurde während eines Universitätskurs entwickelt und ist nicht als Ersatz für andere bekannte Rahmenbedingungen für maschinelles Lernen gedacht. Wenn Sie nach einer maschinellen Lernbibliothek für .NET in der Produktion suchen, empfehle ich, ml.net oder alternativ Tensorflow.net auszuprobieren.
Führen Sie den folgenden Befehl in der Package Manager -Konsole aus, um neuralNetwork.net zu installieren, um den folgenden Befehl auszuführen
Install-Package NeuralNetwork.NET
Weitere Details sind hier verfügbar.
Die Bibliothek von NeuralNetwork.net enthält einfach zu verwendende Klassen und Methoden, um ein neues neuronales Netzwerk zu erstellen, die Datensätze für die Verwendung und Ausbildung des Netzwerks vorzubereiten. Diese APIs sind für schnelle Prototypen ausgelegt, und dieser Abschnitt bietet einen Überblick über die erforderlichen Schritte, um loszulegen.
Der erste Schritt besteht darin, eine benutzerdefinierte Netzwerkstruktur zu erstellen. Hier ist ein Beispiel mit einem sequentiellen Netzwerk (ein Stapel von Schichten):
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 ) ) ;
Der nächste Schritt besteht darin, die zu verwendenden Datensätze über die APIs in der DatasetLoader
-Klasse vorzubereiten:
// 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
} ) ;
Das Training eines neuronalen Netzwerks ist ziemlich einfach. Verwenden Sie einfach die Methoden in der NetworkManager
-Klasse:
// 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
HINWEIS: Die Methoden NetworkManager
sind auch als asynchrone APIs verfügbar.
Beim Ausführen eines unterstützten Frameworks (.NET Framework, Xamarin oder Mono) können Sie eine andere Implementierung der verfügbaren Ebenen verwenden, die das Cudnn-Toolkit nutzt und die meisten Arbeiten an der verfügbaren Cuda-fähigen GPU parallelisiert. Verwenden Sie dazu einfach die Ebenen aus der CuDnnNetworkLayers
-Klasse beim Erstellen eines Netzwerks.
Einige der von Cudnn betriebenen Ebenen unterstützen zusätzliche Optionen als die Standardebenen. Hier ist ein Beispiel:
// 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
Diese LayerFactory
-Instanzen können verwendet werden, um wie im CPU -Beispiel ein neues Netzwerk zu erstellen.
HINWEIS: Um diese Funktion zu verwenden Bibliothek auch. Weitere Informationen finden Sie hier.
Einige komplexe Netzwerkstrukturen, wie Restnetzwerke oder Inception -Module, können nicht als einfache sequentielle Netzwerkstruktur ausgedrückt werden: Hier werden Berechnungsgraphennetzwerke gespielt. Anstatt die Eingänge über einen linearen Schichtstapel weiterzuleiten, verfügt ein Rechendiagramm über eine spezifische räumliche Struktur, mit der verschiedene Knoten miteinander verbunden werden können. Zum Beispiel ist es möglich, Daten über verschiedene parallele Pipelines zu kanalisieren, die später im Diagramm verschmolzen werden, oder Hilfsklassifizierer zu haben, die während der Trainingsphase zum Gradienten -Backpropagation beitragen.
Berechnungsgrafiknetzwerke werden mit der NetworkManager.NewGraph
-API erstellt. Hier finden Sie ein Beispiel:
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 bietet verschiedene gemeinsam genutzte Einstellungen, die über die NetworkSettings
-Klasse verfügbar sind. Diese Klasse fungiert als Container, um die Einstellung jederzeit schnell zu überprüfen und zu ändern. Diese Einstellungen beeinflussen das Verhalten einer vorhandenen INeuralNetwork
-Instanz und der Bibliothek im Allgemeinen.
Zum Beispiel ist es möglich, die von den Netzwerken verwendeten Kriterien anzupassen, um ihre Leistung während des Trainings zu überprüfen
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
Bei Verwendung von Cuda-betriebenen Netzwerken kann die verwendete GPU manchmal nicht die gesamten Test- oder Validierungsdatensätze in einem einzigen Pass verarbeiten, was das Standardverhalten ist (diese Datensätze werden nicht in Chargen unterteilt). Um Speicherprobleme zu vermeiden, ist es möglich, dieses Verhalten zu ändern:
NetworkSettings . MaximumBatchSize = 400 ; // This will apply to any test or validation dataset
Die INeuralNetwork
-Schnittstelle enthält eine Save
, mit der zu einem bestimmten Zeitpunkt jedes Netzwerk serialisiert werden kann. Um eine neue Netzwerkinstanz aus einer gespeicherten Datei oder einem Stream zu erhalten, verwenden Sie einfach die Methode NetworkLoader.TryLoad
.
Da mehrere Layer -Typen in den verfügbaren Bibliotheken unterschiedliche Implementierungen haben, können Sie die Layer -Anbieter beim Laden eines gespeicherten Netzwerks angeben. So laden Sie beispielsweise ein Netzwerk mit den Cudnn -Ebenen, wenn möglich:
FileInfo file = new FileInfo ( @"C:...MySavedNetwork.nnet" ) ;
INeuralNetwork network = NetworkLoader . TryLoad ( file , ExecutionModePreference . Cuda ) ;
HINWEIS: Die Option ExecutionModePreference
gibt den gewünschten Typ von Ebenen an, die nach Möglichkeit zu Deserialisierung sind. Beispielsweise verfügt das geladene Netzwerk unter Verwendung ExecutionModePreference.Cpu
nur mit CPU-gestützten Schichten, wenn sie unterstützt werden.
Es gibt auch eine zusätzliche SaveMetadataAsJson
-Methode, um die Metadaten einer INeuralNetwork
-Instanz zu exportieren.
Der Namespace NeuralNetworkNET.Datasets
enthält statische Klassen, um einen beliebten Datensatz schnell zu laden und eine IDataset
-Instanz zu erhalten, die mit einem neuen neuronalen Netzwerk verwendet werden kann. So erhalten Sie wie Sie den MNIST -Datensatz erhalten:
ITrainingDataset trainingData = await Mnist . GetTrainingDatasetAsync ( 400 ) ; // Batches of 400 samples
ITestDataset testData = await Mnist . GetTestDatasetAsync ( p => .. . /* Optional callback */ ) ;
Jede API in diesem Namespace unterstützt auch eine optionale CancellationToken
, um das Laden des Datensatzes zu stoppen, da die Quelldaten aus dem Internet heruntergeladen werden und sich einige Zeit in Anspruch nehmen können, um verfügbar zu sein, abhängig vom verwendeten Datensatz.
Die neuralNetwork.net -Bibliothek erfordert die Unterstützung von .NET Standard 2.0, sodass sie für Anwendungen zur Verfügung steht: Targeting:
Zusätzlich zu den obigen Frameworks benötigen Sie eine IDE mit C# 7.3 -Unterstützung, um die Bibliothek auf Ihrem PC zu kompilieren.