1

Wir verwenden Tensorflow, um einen binären Klassifikations-Bilddatensatz mit 700 images zu trainieren, wobei jedes Bild 256*256*1 ist und der Datensatz gleichmäßig auf die beiden Klassen aufgeteilt ist. Wir haben das Cifar10 Modell auf Tensorflow leicht geändert und der Code unseres Modells konnte unten gesehen werden.Wie ändere ich ein neuronales Netzwerk, um die Genauigkeit des Validierungssatzes zu verbessern?

# conv1 
with tf.variable_scope('conv1') as scope: 
    kernel = _variable_with_weight_decay('weights', 
            shape=[5, 5, 1, 256], 
            stddev=5e-2, 
            wd=0.0) 
    conv = tf.nn.conv2d(images, kernel, [1, 1, 1, 1], padding='SAME') 
    biases = _variable_on_cpu('biases', [256], tf.constant_initializer(0.0)) 
    pre_activation = tf.nn.bias_add(conv, biases) 
    conv1 = tf.nn.relu(pre_activation, name=scope.name) 
    _activation_summary(conv1) 

# pool1 
pool1 = tf.nn.max_pool(conv1, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], 
        padding='SAME', name='pool1') 
# norm1 
norm1 = tf.nn.lrn(pool1, 4, bias=1.0, alpha=0.001/9.0, beta=0.75, 
       name='norm1') 

# conv2 
with tf.variable_scope('conv2') as scope: 
    kernel = _variable_with_weight_decay('weights', 
            shape=[5, 5, 256, 256], 
            stddev=5e-2, 
            wd=0.0) 
    conv = tf.nn.conv2d(norm1, kernel, [1, 1, 1, 1], padding='SAME') 
    biases = _variable_on_cpu('biases', [256], tf.constant_initializer(0.1)) 
    pre_activation = tf.nn.bias_add(conv, biases) 
    conv2 = tf.nn.relu(pre_activation, name=scope.name) 
    _activation_summary(conv2) 

# norm2 
norm2 = tf.nn.lrn(conv2, 4, bias=1.0, alpha=0.001/9.0, beta=0.75, 
       name='norm2') 
# pool2 
pool2 = tf.nn.max_pool(norm2, ksize=[1, 3, 3, 1], 
        strides=[1, 2, 2, 1], padding='SAME', name='pool2') 

# local3 
with tf.variable_scope('local3') as scope: 
    reshape = tf.reshape(pool2, [FLAGS.batch_size, -1]) 
    dim = reshape.get_shape()[1].value 
    weights = _variable_with_weight_decay('weights', shape=[dim, 384], 
             stddev=0.04, wd=0.004) 
    biases = _variable_on_cpu('biases', [384], tf.constant_initializer(0.1)) 

    local3 = tf.nn.relu(tf.matmul(reshape, weights) + biases, name=scope.name) 
    _activation_summary(local3) 

# local4 
with tf.variable_scope('local4') as scope: 
    weights = _variable_with_weight_decay('weights', shape=[384, 192], 
             stddev=0.04, wd=0.004) 
    biases = _variable_on_cpu('biases', [192], tf.constant_initializer(0.1)) 
    local4 = tf.nn.relu(tf.matmul(local3, weights) + biases, name=scope.name) 
    _activation_summary(local4) 

with tf.variable_scope('softmax_linear') as scope: 
    weights = _variable_with_weight_decay('weights', [192, NUM_CLASSES], 
             stddev=1/192.0, wd=0.0) 
    biases = _variable_on_cpu('biases', [NUM_CLASSES], 
          tf.constant_initializer(0.0)) 
    softmax_linear = tf.add(tf.matmul(local4, weights), biases, name=scope.name) 
    _activation_summary(softmax_linear) 

Wir verwenden batchsize = 2 und Lernrate = 0,005.

Derzeit sehen die loss und validation accuracy wie folgt aus. Die maximale Genauigkeit springt zwischen 65% und 70%.

Welche Arten von Parametern sollte ich ändern, um eine höhere Genauigkeit zu erhalten? Ich habe versucht, die Filtergröße auf 3 zu reduzieren und zwei Dropout-Layer (0,5) hinzuzufügen, aber es scheint nichts zu ändern.

Antwort

0

Für mich sieht es wie Ihr Modell overfitting auf den Trainingsdaten aus. Dies bedeutet, dass Ihr Modell nicht wirklich verallgemeinert wird, um die zugrundeliegenden Konzepte der Daten wirklich zu lernen, sondern einfach die 700 Trainingsbilder auswendig zu lernen. Es wäre hilfreich, wenn Sie Ihre Trainingsdaten in einer Genauigkeitskurve sehen, die irgendwo im Bereich von 90% - 98% liegt. Ihre Verlustfunktion zeigt eine sehr steile Abnahme, während die Genauigkeit Ihrer Validierungsgruppe auf ~ 65% ansteigt. Dies ist ein starker Indikator für ein überdimensioniertes Modell.

Es gibt ein paar Optionen zu gehen. Zunächst ist ein Trainingssatz von nur 700 Bildern in den meisten Fällen viel zu klein, was dazu führt, dass das Netzwerk die Daten ziemlich schnell speichert. Sie sollten versuchen, entweder mehr Trainingsdaten zu sammeln und/oder die Datenerweiterung auf Ihre Trainingsdaten anzuwenden, um die Gesamtzahl der Trainingsbilder zu erhöhen. Dies erschwert es dem Netzwerk, jedes einzelne Bild und sein korrektes Etikett zu speichern.

Des Weiteren sollten Sie regularization operations (lecture slides) wie wiegen Zerfall (L1, L2-Norm) oder Dropout auf Ihr Modell anwenden, die das Netzwerk helfen, die Daten zu verallgemeinern gut auf.

+0

Ich habe gerade eine Validierung von 180 Bildern des Trainingsdatensatzes durchgeführt. Es ist in der Tat 100% ... also ist es definitiv übermäßig. Wir haben 350 Bilder für jede Klasse und wir haben insgesamt 2 Klassen. Was wäre eine optimale Anzahl von Bildern, die wir für jede Klasse benötigen? Vielen Dank für Ihre Vorschläge! Sie sind sehr hilfreich. – taylorm

+0

Das ist nicht leicht zu sagen ... Je mehr, desto besser, in der Regel ein paar tausend pro Klasse wäre gut. Beachten Sie, dass Sie die Anzahl der Trainingsbilder in den meisten Fällen relativ einfach erhöhen können, indem Sie für jedes Bild Datenerhöhungsoperationen wie horizontales Spiegeln, zufälliges Ausschneiden oder Farbjitterung anwenden. Es gibt einige sehr nützliche vordefinierte Skripte, die Sie über Ihre Datenmenge ausführen können, um sie zu erweitern. Führen Sie die Augmentation nicht live aus, bevor Sie sie durch Ihr Netzwerk propagieren, tun Sie dies vor dem eigentlichen Training und speichern Sie sie in einer LMDB- oder HD5-Datenbank für einen schnellen Zugriff. –

Verwandte Themen