2017-07-13 2 views
1

Ich mache eine binäre Klassifizierung mit CNN mit Matconvnet auf Matconvnet. Und jetzt versuche ich es durch Keras auf Python zu realisieren. Das Netzwerk ist überhaupt nicht komplex und ich erreichte eine Genauigkeit von 96% auf Matconvnet. Aber mit Keras, auch wenn ich mein Bestes gegeben habe, um sicherzustellen, dass alle Einstellungen exakt gleich sind, kann ich nicht das gleiche Ergebnis erzielen. Oder schlimmer, das Modell funktioniert überhaupt nicht.Importieren Sie ein CNN-Modell von Matlab (Matconvnet) zu Python (Keras)

Hier sind einige Details zur Einstellung. Irgendwelche Ideen oder Hilfe werden geschätzt!

  • Eingangs

    Die Bilder sind 20 * 20 groß. Trainingsgröße 400 und Testgröße 100, Validierungs- Größe 132.

    • Matconvnet: Bilder gespeichert in 20 * 20 * SAMPLE_SIZE Methode
    • Keras Bilder in SAMPLE_SIZE gespeichert * 20 * 20 * 1 Methode
  • Structure CNN (3 * 3) * 3 conv- (2 * 2) maxpooling- vollständig connected- softmax- logloss

    • Matconvnet: Verwende Convolutionized Layer anstelle von Fully Connected Layer. Hier ist der Code:

      function net = initializeCNNA() 
      f=1/100 ; 
      net.layers = {} ; 
      net.layers{end+1} = struct('type', 'conv', ... 
            'weights', {{f*randn(3,3,1,3, 'single'), zeros(1, 3, 'single')}}, ... 
            'stride', 1, ... 
            'pad', 0) ;  
      net.layers{end+1} = struct('type', 'pool', ... 
            'method', 'max', ... 
            'pool', [2 2], ... 
            'stride', 2, ... 
            'pad', 0) ; 
      net.layers{end+1} = struct('type', 'conv', ... 
            'weights', {{f*randn(9,9,3,2, 'single'),             zeros(1,2,'single')}}, ... 
            'stride', 1, ... 
            'pad', 0) ; 
      net.layers{end+1} = struct('type', 'softmaxloss') ;  
      net = vl_simplenn_tidy(net) ; 
      
    • Keras:

 model = Sequential() 
     model.add(Conv2D(3, (3,3),kernel_initializer=\ 
     keras.initializers.RandomNormal(mean=0.0, stddev=0.1, seed=None), input_shape=input_shape)) 
     model.add(MaxPooling2D(pool_size=(2, 2),strides=(2, 2))) 
     model.add(Flatten()) 
     model.add(Dense(2,activation='softmax',\ 
     kernel_initializer=keras.initializers.RandomNormal(mean=0.0, stddev=0.1, seed=None))) 
  • Verlustfunktion
    • Matconvnet: softmaxloss
    • Keras: binary_crossentropy
  • Optimizer

    • Matconvnet: SGD

      trainOpts.batchSize = 50; 
      trainOpts.numEpochs = 20 ; 
      trainOpts.learningRate = 0.001 ; 
      trainOpts.weightDecay = 0.0005 ; 
      trainOpts.momentum = 0.9 ; 
      
    • Keras: SGD

      sgd = optimizers.SGD(lr=0.001, momentum=0.9, decay=0.0005) 
      model.compile(loss='binary_crossentropy', 
      optimizer=sgd, 
      metrics=['accuracy']) 
      
  • Initialization: Filter: N (0,0.1), Vorspannung: 0
  • Normalisierungs: keine Charge Normalisierung außer Normalisierung während der Eingang 0 Mittelwert und 1 std für Bilder haben.

Oben sind die Aspekte, die ich überprüft habe, um sicherzustellen, dass ich die korrekte Replikation vorgenommen habe.Aber ich verstehe nicht, warum es bei Keras nicht funktioniert. Hier sind ein paar Vermutungen:

  • Matconvnet verwendet eine Convolutionized-Ebene anstelle einer vollständig verbundenen Ebene und kann eine raffinierte Möglichkeit zur Aktualisierung der Parameter enthalten.
  • Sie verwenden einen anderen Algorithmus, um SGD anzuwenden, dessen Parameter unterschiedliche Bedeutung haben.
  • Ich habe auch andere versucht:

    • ändern Optimierer in Keras in Adadelta(). Keine Verbesserung.
    • Ändern Sie die Netzwerkstruktur und machen Sie sie tiefer. Es klappt!

      Aber immer noch wollen wissen, warum Matconvnet dieses gute Ergebnis mit einem viel einfacheren erzielen kann.

    Antwort

    0

    "Matconvnet verwendet eine Convolutionized-Ebene anstelle einer vollständig verbundenen Ebene und kann eine raffinierte Möglichkeit zur Aktualisierung der Parameter enthalten."

    Nein. Technisch gesehen sollte zwischen Faltung und vollständig verbundenen Schichten kein Unterschied bestehen. Ich bin mir ziemlich sicher, dass es keine schicke Möglichkeit gibt, die Parameter zu aktualisieren.

    Weitere Kommentare kommen ..

    ein Teil der Diskussion in diesem Beitrag nicht helfen kann: Can't replicate a matconvnet CNN architecture in Keras