2017-06-26 3 views
0

Ich versuche eine benutzerdefinierte Ebene in Keras zu schreiben, um auf bestimmte Architektur in einem Papier vorgeschlagen zu replizieren. Die Schicht hat keine trainierbaren Gewichte. Ich glaube, dass dies relevant sein könnte, da es nicht notwendig wäre, die Klasse Layer zu erweitern.Keras mit CNTK-Backend: Schreiben von benutzerdefinierten Ebenen

Ich benutze das CNTK-Backend, aber ich versuche, den Code so Backend-agnostisch wie möglich zu halten, also verlasse ich mich auf die in keras.backend definierten Schnittstellen, anstatt direkt CNTK zu verwenden.

Im Moment versuche ich nur ein kleines Beispiel zu arbeiten. Das Beispiel ist wie folgt:

import numpy as np 

from scipy.misc import imread 
from keras import backend as K 

im = imread('test.bmp') 

#I'm extending a grayscale image to behave as a color image 
ex_im = np.empty([im.shape[0],im.shape[1],3]) 

ex_im[:,:,0] = im 
ex_im[:,:,1] = im 
ex_im[:,:,2] = im 

conv_filter = K.ones([3,3,ex_im.shape[2],ex_im.shape[2]]) 
x = K.conv2d(ex_im,conv_filter,padding='same') 

Dieser Code führt jedoch zu dem folgenden Fehler:

RuntimeError: Convolution currently requires the main operand to have dynamic axes

CNTK die Eingabe an die Faltung erfordert dynamische Achsen zu haben, sonst wäre es die erste Dimension zu interpretieren der Eingabe als die Batch-Größe. Also habe ich versucht, mit Platzhalter (die einzige Art, wie ich dies zu tun finden konnten) die Achsen dynamisch zu machen:

import numpy as np 

from scipy.misc import imread 
from keras import backend as K 

im = imread('test.bmp') 

ex_im = np.empty([1,im.shape[0],im.shape[1],3]) 

ex_im[0,:,:,0] = im 
ex_im[0,:,:,1] = im 
ex_im[0,:,:,2] = im 

place = K.placeholder(shape=((None,) + ex_im.shape[1:])) 

conv_filter = K.ones([3,3,ex_im.shape[3],ex_im.shape[3]]) 
x = K.conv2d(place,conv_filter,padding='same') 

Das Bild ist jetzt eine Reihe von Bildern, mit dem, was ist im Grunde eine Chargengröße von 1.

Dies funktioniert ordnungsgemäß. Ich kann jedoch nicht herausfinden, wie eine Eingabe dem Platzhalter zugeführt wird, um meinen Code zu testen. eval() nimmt keine Argumente, und es scheint keine Möglichkeit zu geben, die Eingabe als Argument für die Auswertung zu übergeben.

Gibt es eine Möglichkeit, dies ohne Platzhalter zu tun? Oder eine Möglichkeit, die Eingaben dem Platzhalter zuzuführen? Mache ich etwas grundlegend falsches und sollte ich einen anderen Weg gehen?

Ich sollte hinzufügen, dass ich wirklich vermeiden möchte, in einem Backend gesperrt werden, so dass alle Lösungen Backend-Agnostic sein sollten.

Antwort

0

Wenn Sie benutzerdefinierte Layer verwenden, definieren Sie keine Tensoren, lassen Sie Keras dies für Sie tun. Gerade die Ebene schaffen, und was zu der Schicht gegeben wird, wird bereits eine richtige Tensor sein:

images = np.ones((1,50,50,3)) 

def myFunc(x): 
    conv_filter = K.ones([3,3,3,3]) 
    return K.conv2d(x,conv_filter,padding='same') 

inp = Input((50,50,3)) 
out = Lambda(myFunc, output_shape=(50,50,3))(inp) 

model = Model(inp,out) 
print(model.predict(images)) 
+0

einfach mit place = K.variable (ex_im) noch ergibt sich die gleiche Runtime wie ich in der Original-Beitrag erwähnt. Fehle ich etwas? – fnw

+0

Meine Antwort wurde mit einem Arbeitsbeispiel aktualisiert. –

+0

Diese Antwort tut, was ich brauchte, danke. Um diese Frage in der Zukunft zu beantworten: Ich brauchte das, um einen Code zu testen, den ich entwickelte. Diese Layer werden in ein vorhandenes Modell integriert, sodass für diese Layer kein separates Modell erstellt werden muss. – fnw

Verwandte Themen