2017-11-10 4 views
1

ich die folgende binäre Klassifizierung Keras Modell, das nicht gut trainiert, aber die Züge:Unable Modell von Keras zu konvertieren Tensorflow

def vgg_stack(self): 
    def func(x): 
     x = layers.Conv2D(64, (3, 3), activation='relu')(x) 
     x = layers.MaxPooling2D((3, 3), strides=(2, 2))(x) 

     x = layers.Conv2D(128, (3, 3), activation='relu')(x) 
     x = layers.MaxPooling2D((2, 2), strides=(2, 2))(x) 

     x = layers.Conv2D(128, (3, 3), activation='relu')(x) 
     x = layers.MaxPooling2D((2, 2), strides=(2, 2))(x) 

     x = layers.Conv2D(64, (3, 3), activation='relu')(x) 
     x = layers.MaxPooling2D((2, 2), strides=(2, 2))(x) 

     x = layers.Flatten()(x) 
     x = layers.Dense(512, activation='relu')(x) 
     x = layers.Dense(256, activation='relu')(x) 
     x = layers.Dense(1, activation='sigmoid')(x) 

     return x 

    return func 

def implement(self): 
    self.inputs = layers.Input((self.input_width, self.input_height, self.input_depth)) 
    self.outputs = self.vgg_stack()(self.inputs) 

    self.opt = optimizers.Adam(lr=self.learning_rate) 
    self.model = models.Model(inputs=self.inputs, outputs=self.outputs) 
    self.model.compile(loss='binary_crossentropy', optimizer=self.opt) 

def fit_predict(self): 
    ... 
    self.model.fit(data_train, actuals_train, batch_size=self.batch_size, epochs=10, verbose=1, 
        validation_data=[data_validation, actuals_validation], callbacks=[self]) 

es Prognosen wie folgt aussehen

ist
[[ 0.58952832] 
[ 0.89163774] 
[ 0.99083483] 
..., 
[ 0.52727282] 
[ 0.72056866] 
[ 0.99504411]] 

D.h. es ist etwas.

ich versuchte, um das Modell zu reinem tensroflow zu konvertieren und bekam

def conv2drelu(self, x, filters, kernel_size, padding='VALID'): 

    input_depth = int(x.get_shape()[-1]) 

    weights = tf.Variable(tf.truncated_normal([kernel_size[0], kernel_size[0], input_depth, filters], 
               dtype=tf.float32, stddev=self.init_stddev)) 

    self.var_list.append(weights) 

    biases = tf.Variable(tf.constant(0.0, shape=[filters], dtype=tf.float32)) 

    self.var_list.append(biases) 

    y = tf.nn.conv2d(x, weights, [1, 1, 1, 1], padding=padding) 

    y = tf.nn.bias_add(y, biases) 

    y = tf.nn.relu(y) 

    return y 

def maxpooling(self, x, pool_size, strides, padding='VALID'): 

    y = tf.nn.max_pool(x, ksize=[1, pool_size[0], pool_size[1], 1], strides=[1, strides[0], strides[1], 1], 
         padding=padding) 

    return y 

def flatten(self, x): 

    shape = int(np.prod(x.get_shape()[1:])) 

    y = tf.reshape(x, [-1, shape]) 

    return y 

def dense(self, x, units, activation): 

    shape = int(x.get_shape()[1]) 

    weights = tf.Variable(tf.truncated_normal([shape, units], dtype=tf.float32, stddev=self.init_stddev)) 

    self.var_list.append(weights) 

    biases = tf.Variable(tf.constant(0.0, shape=[units], dtype=tf.float32)) 

    self.var_list.append(biases) 

    y = tf.matmul(x, weights) 

    y = tf.nn.bias_add(y, biases) 

    if activation == 'relu': 

     y = tf.nn.relu(y) 

    elif activation == 'sigmoid': 

     y = tf.nn.sigmoid(y) 

    return y 

def vgg_stack(self, x): 

    x = self.conv2drelu(x, 64, (3, 3)) 
    x = self.maxpooling(x, (3, 3), strides=(2, 2)) 

    x = self.conv2drelu(x, 128, (3, 3)) 
    x = self.maxpooling(x, (2, 2), strides=(2, 2)) 

    x = self.conv2drelu(x, 128, (3, 3)) 
    x = self.maxpooling(x, (2, 2), strides=(2, 2)) 

    x = self.conv2drelu(x, 64, (3, 3)) 
    x = self.maxpooling(x, (2, 2), strides=(2, 2)) 

    x = self.flatten(x) 

    x = self.dense(x, 512, activation='relu') 
    x = self.dense(x, 256, activation='relu') 
    x = self.dense(x, 1, activation='sigmoid') 

    return x 

def implement(self): 

    self.var_list = [] 

    self.input_data = tf.placeholder(tf.float32, shape=(None, self.width, self.height, self.depth)) 

    self.prediction = self.vgg_stack(self.input_data) 

    self.actual = tf.placeholder(tf.float32, shape=(None, 1)) 

    self.log_loss = tf.losses.log_loss(self.actual, self.prediction) 

    opt = tf.train.AdamOptimizer(learning_rate=self.learning_rate) 

    # self.step = opt.minimize(self.mean_squared_error, var_list=self.var_list) 
    self.step = opt.minimize(self.log_loss, var_list=self.var_list) 

d.h. I versuche Funktionen zu schreiben äquivalente Schicht zu jeder Keras und dann in die gleiche Struktur kombiniert werden.

Ich habe alle die gleichen Nummern verwendet. Leider liefert das Netzwerk etwas Abgebautes:

[[ 0.46732453] 
[ 0.46732453] 
[ 0.46732453] 
..., 
[ 0.46732453] 
[ 0.46732453] 
[ 0.46732453]] 

I.e. die gleichen Werte für alle Proben.

Was kann der Grund dafür sein?

+0

Füttern Sie in beiden Fällen dieselben Eingabedaten? – Ashalynd

+0

Ja, ich habe nur eine Funktion, um Daten abzurufen und zu verwenden. Ich habe auch versucht, das Mischen in 'Keras' zu deaktivieren, aber es macht immer noch einen Zug. Sieht aus, als ob ich unter der ungebrochenen Symmetrie leide? Sehen Sie auch Fehler in meinen Layer-Implementierungen? – Dims

Antwort

2

Die Konvertierung war korrekt. Ich habe Unitests für Faltungsschichten von Keras und Tensorflow geschrieben und festgestellt, dass sie numerisch identische Ergebnisse liefern.

Zusätzlich ersetzte ich das Optimierungsziel von nur Log-Verlust zu sigmoid_cross_entropy_with_logits, aber das half nicht allein.

Das Problem war mit stdev von Initialisierungswerten zu klein.

Ich dachte, es ist genug, es ist sehr klein zu haben Symmetrie zu brechen, und wurde zu 1e-8 oder 1e-5 Einstellung, aber das war falsch: so kleine Werte Nullen nahezu identisch waren und nach mehreren Schichten Netzwerk begann zu produzieren identische Ergebnisse für alle Proben.

Nachdem ich stdev zu 1e-1 geändert habe, begann netwrok, wie in Keras zu performen.

Verwandte Themen