2016-06-10 5 views
2

Ich möchte ein neuronales Netzwerk mit der Funktion sine() trainieren.Train Neuronales Netzwerk mit Sinus-Funktion

Derzeit verwende ich diesen Code und die (cerebrum gem):

require 'cerebrum' 

input = Array.new 
300.times do |i| 
    inputH = Hash.new 
    inputH[:input]=[i] 
    sinus = Math::sin(i) 
    inputH[:output] = [sinus] 
    input.push(inputH) 

end 

network = Cerebrum.new 

network.train(input, { 
    error_threshold: 0.00005, 
    iterations:  40000, 
    log:    true, 
    log_period:  1000, 
    learning_rate: 0.3 
}) 


res = Array.new 
300.times do |i| 
    result = network.run([i]) 
    res.push(result[0]) 
end 

puts "#{res}" 

Aber es funktioniert nicht, wenn ich das trainierte Netz laufen bekomme ich einige seltsame Ausgangswerte (anstatt einen Teil des Sinus des Erhaltens Kurve).

Also, was mache ich falsch?

+1

Als beiseite fällt mir ein, dass Sie erwarten, dass Math :: sin mit Grad arbeiten - es funktioniert nicht im Radianten, die viel größere Einheiten sind. Wenn Sie nur eine einzige vorhergesagte Sinuswelle sehen möchten, können Sie 'sinus = Math :: sin (i.to_f/50)' oder so verwenden –

Antwort

4

Cerebrum ist eine sehr einfache und langsame NN-Implementierung. Es gibt bessere Optionen in Ruby, z. B. ruby-fann gem.

Wahrscheinlich ist Ihr Problem das Netzwerk ist zu einfach. Sie haben keine versteckten Ebenen angegeben - es sieht so aus, als ob der Code eine standardmäßige versteckte Ebene mit 3 Neuronen für Ihren Fall zuweist.

Versuchen Sie so etwas wie:

network = Cerebrum.new({ 
    learning_rate: 0.01, 
    momentum:  0.9, 
    hidden_layers: [100] 
}) 

und erwarten, dass es ewig dauern zu trainieren, und noch nicht sehr gut sein.

Auch Ihre Auswahl von 300 Ausgängen ist zu breit - zum Netzwerk sieht es meistens wie Rauschen aus und es interpoliert nicht gut zwischen Punkten. Ein neuronales Netzwerk findet nicht irgendwie heraus "Oh, das muss eine Sinuswelle sein" und passt dazu. Stattdessen interpoliert es zwischen den Punkten - das schlaue Bit passiert, wenn es in mehreren Dimensionen gleichzeitig tut, vielleicht Struktur zu finden, die Sie so leicht mit einer manuellen Inspektion nicht entdecken konnten. Um ihm eine vernünftige Chance zu geben, etwas zu lernen, schlage ich vor, dass Sie ihm viel dichtere Punkte geben, z. wo Sie sich gerade sinus = Math::sin(i) stattdessen haben verwenden:

sinus = Math::sin(i.to_f/10) 

Das noch fast 5 Iterationen durch die Sinuswelle. Das sollte hoffentlich genug sein, um zu beweisen, dass das Netzwerk eine beliebige Funktion lernen kann.