Ich bin neu in der Bibliothek deeplearning4j, aber ich habe etwas Erfahrung mit neuronalen Netzen im Allgemeinen.
Ich versuche ein wiederkehrendes neuronales Netzwerk (insbesondere ein LSTM) zu trainieren, das Beats in Musik in Echtzeit erkennen soll. Alle Beispiele für die Verwendung von rekurrenten neuronalen Netzen mit deeplearning4j, die ich bisher gefunden habe, verwenden einen Leser, der die Trainingsdaten aus einer Datei liest. Da ich Musik in Echtzeit über ein Mikrofon aufnehmen möchte, kann ich einige vorgenerierte Dateien nicht lesen, so dass die Daten, die in das neuronale Netzwerk eingespeist werden, von meiner Anwendung in Echtzeit erzeugt werden.Train recurrent neuronales Netz in deeplearning4j mit Daten, die während der Laufzeit generiert wird
Dies ist der Code, den ich bin mit Netz zu generieren: Ich verwende etwa 700 Eingänge, 1 Ausgang (die FFT-Daten des aufgezeichneten Audio sind meist)
NeuralNetConfiguration.ListBuilder builder = new NeuralNetConfiguration.Builder()
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT).iterations(1)
.learningRate(0.1)
.rmsDecay(0.95)
.regularization(true)
.l2(0.001)
.weightInit(WeightInit.XAVIER)
.updater(Updater.RMSPROP)
.list();
int nextIn = hiddenLayers.length > 0 ? hiddenLayers[0] : numOutputs;
builder = builder.layer(0, new GravesLSTM.Builder().nIn(numInputs).nOut(nextIn).activation("softsign").build());
for(int i = 0; i < hiddenLayers.length - 1; i++){
nextIn = hiddenLayers[i + 1];
builder = builder.layer(i + 1, new GravesLSTM.Builder().nIn(hiddenLayers[i]).nOut(nextIn).activation("softsign").build());
}
builder = builder.layer(hiddenLayers.length, new RnnOutputLayer.Builder(LossFunctions.LossFunction.MCXENT).nIn(nextIn).nOut(numOutputs).activation("softsign").build());
MultiLayerConfiguration conf = builder.backpropType(BackpropType.TruncatedBPTT).tBPTTForwardLength(DEFAULT_RECURRENCE_DEPTH).tBPTTBackwardLength(DEFAULT_RECURRENCE_DEPTH)
.pretrain(false).backprop(true)
.build();
net = new MultiLayerNetwork(conf);
net.init();
In diesem Fall (was eine Zahl zwischen 0 [no beat] und 1 [beat] ausgeben soll) und mein hiddenLayers Array besteht aus den Ints {50, 25, 10}.
Für die Ausgabe des Netzes immer ich verwende diesen Code:
double[] output = new double[]{net.rnnTimeStep(Nd4j.create(netInputData)).getDouble(0)};
wo netInputData die Daten, die ich in das Netzwerk Eingang als eindimensionaler Doppel Array will.
Ich bin relativ sicher, dass dieser Code gut funktioniert, da ich etwas Ausgabe für ein untrainiertes Netzwerk bekomme, das something like this aussieht, wenn ich es plotte.
Aber sobald ich versuche, ein Netzwerk zu trainieren (auch wenn ich es nur für eine kurze Zeit trainiere, was die Gewichte des Netzwerkes nur ein bisschen ändern sollte, so dass die Ausgabe dem ungeschulten Netzwerk sehr ähnlich sein sollte), Ich bekomme eine Ausgabe, die .
Dies ist der Code, den ich bin mit dem Netzwerk zu trainieren:
for(int timestep = 0; timestep < trainingData.length - DEFAULT_RECURRENCE_DEPTH; timestep++){
INDArray inputDataArray = Nd4j.create(new int[]{1, numInputs, DEFAULT_RECURRENCE_DEPTH},'f');
for(int inputPos = 0; inputPos < trainingData[timestep].length; inputPos++)
for(int inputTimeWindowPos = 0; inputTimeWindowPos < DEFAULT_RECURRENCE_DEPTH; inputTimeWindowPos++)
inputDataArray.putScalar(new int[]{0, inputPos, inputTimeWindowPos}, trainingData[timestep + inputTimeWindowPos][inputPos]);
INDArray desiredOutputDataArray = Nd4j.create(new int[]{1, numOutputs, DEFAULT_RECURRENCE_DEPTH},'f');
for(int outputPos = 0; outputPos < desiredOutputData[timestep].length; outputPos++)
for(int inputTimeWindowPos = 0; inputTimeWindowPos < DEFAULT_RECURRENCE_DEPTH; inputTimeWindowPos++)
desiredOutputDataArray.putScalar(new int[]{0, outputPos, inputTimeWindowPos}, desiredOutputData[timestep + inputTimeWindowPos][outputPos]);
net.fit(new DataSet(inputDataArray, desiredOutputDataArray));
}
Noch einmal, ich habe meine Daten für die Eingabe und für die gewünschte Ausgabe als Doppel-Array bekam. Diesmal sind die beiden Arrays zweidimensional. Der erste Index repräsentiert die Zeit (wobei Index 0 die ersten Audiodaten des aufgezeichneten Audios ist) und der zweite Index repräsentiert die Eingabe (bzw. die gewünschte Ausgabe) für diesen Zeitschritt.
Angesichts der gezeigten Ausgabe nach dem Training eines Netzwerks, neige ich dazu zu denken, dass etwas mit meinem Code falsch sein muss, der für die Erstellung der INDArrays aus meinen Daten verwendet wird. Fehle ich einen wichtigen Schritt für die Initialisierung dieser Arrays oder habe ich die Reihenfolge verkompliziert, die ich brauche, um meine Daten in diese Arrays zu bringen?
Vielen Dank für jede Hilfe im Voraus.
ausgezeichnete Frage. Bitte treten Sie der Community bei Gitter bei. https://gitter.im/deeplearning4j/deeplearning4j Committer auf dem Kanal können dir helfen! – tremstat