2

Ich versuche, die Char-Ebene CNN in this paper neu zu erstellen und bin ein wenig stecken im letzten Schritt, wo ich eine K-Max-Pooling-Schicht erstellen muss, da ich MXNet und es verwende hat das nicht.Python KMax Pooling (MXNet)

Ein wichtiger Unterschied ist auch die Einführung von mehreren temporalen k-Max-Pooling-Schichten. Dies ermöglicht die Erkennung der wichtigsten Funktionen in einem Satz, unabhängig von ihrer spezifischen Position, Erhalt ihrer relativen Reihenfolge.

Allerdings ist MxNet die Fähigkeit, add a new-op, die ich versucht habe, wie dies zu tun (wenn auch ein wenig verwirrt mit der Form der Daten zu erhalten, da Filter und Batch-Größe).

Die Form der Daten in den kommenden:

128 (min-batch) x 512 (number of filters) x 1 (height) x 125 (width) 

Die Form der Daten kommen aus (k-max-Pooling, k = 7):

128 (min-batch) x 512 (number of filters) x 1 (height) x 7 (width) 

Meine Idee so weit .. .:

class KMaxPooling(mx.operator.CustomOp): 
    def forward(self, is_train, req, in_data, out_data, aux): 
     # Desired (k=3): 
     # in_data = np.array([1, 2, 4, 10, 5, 3]) 
     # out_data = [4, 10, 5] 
     x = in_data[0].asnumpy() 
     idx = x.argsort()[-k:] 
     idx.sort(axis=0) 
     y = x[idx] 

Allerdings bin ich über einige Dinge nicht sicher:

  1. So testen Sie, ob das funktioniert (sobald ich einen vollständigen Code habe)
  2. Wie sollten die Abmessungen sein? Ich bin auf der letzten Dimension Sortierung (Achse = 0)
  3. Was für die Rückwärts() Funktion dh die Steigung propogation
  4. Ob dies funktionieren wird mit GPU zu tun - ich vermute ich es neu zu schreiben, müssen in C/Cuda?

ich dieses Beispiel gefunden von jemand anderem für keras (aber nicht über die rep zu verbinden):

import numpy as np 
import theano.tensor as T 
from keras.layers.core import MaskedLayer 

class KMaxPooling(MaskedLayer): 
    def __init__(self, pooling_size): 
     super(MaskedLayer, self).__init__() 
     self.pooling_size = pooling_size 
     self.input = T.tensor3() 

    def get_output_mask(self, train=False): 
     return None 

    def get_output(self, train=False): 
     data = self.get_input(train) 
     mask = self.get_input_mask(train) 

     if mask is None: 
      mask = T.sum(T.ones_like(data), axis=-1) 
     mask = mask.dimshuffle(0, 1, "x") 

     masked_data = T.switch(T.eq(mask, 0), -np.inf, data) 

     result = masked_data[T.arange(masked_data.shape[0]).dimshuffle(0, "x", "x"), 
          T.sort(T.argsort(masked_data, axis=1)[:, -self.pooling_size:, :], axis=1), 
          T.arange(masked_data.shape[2]).dimshuffle("x", "x", 0)] 

Antwort

1

der Tat gibt es keine KMaxPooling Unterstützung in MxNet so weit, und es könnte sein, schwierig, es zu implementieren. Dennoch kann ich einige Tipps denke, Ihnen zu helfen, wenn Sie es entscheiden Umsetzung:

  1. Wenn Sie Gluon verwenden, dann können Sie KMaxPooling als HybridBlock implementieren und dann HybridSequential verwenden, um sie auszuführen. Solange Sie Funktionen aus dem als Argument bereitgestellten "F" -Backend verwenden (vermeiden Sie die Verwendung von numpy), können Sie Ihren Code auf der GPU ausführen. Also müssen Sie C++ nicht machen.

  2. Mit HybridBlock und Funktionen von "F" -Backend wird nur das Problem der Rückwärtsausbreitung auch lösen. Sie müssen es im Grunde nicht schreiben, denn Autograd wird es für Sie tun.

  3. Mit HybridBlock können Sie Ihren Code einfacher debuggen. Sie rufen einfach nicht net.hybridize() -Methode, und Sie erhalten "nd" -Backend, die langsamer als "sym" -Backend ist, aber Sie können einen Debugger verwenden.

  4. Wie für Dimensionen, wenn Sie feststellen, gibt es verschiedene Version von MaxPool Block in Gluon: MaxPool1D, MaxPool2D, MaxPool3D. Sie können nur 1 KMaxPool1D für Ihren Fall implementieren.Sie werden dann die Ausgabe von KMaxPool1D so stapeln, als ob mehrere Filter angewendet würden, was im Wesentlichen Werte zum Ende der "z" -Dimension hinzufügt.

Hoffe, dass hilft.