2017-02-06 2 views
1

Ich möchte die Ausgabe einer bestimmten Caffe-Ebene in eine Datei schreiben. Ich würde das gerne für mehr als ein Bild machen, also habe ich einige Änderungen am HDF5-Ausgabeschicht-Code vorgenommen, um die Erstellung einer Datei für jedes Bild zu ermöglichen, das die Merkmale für jedes Bild enthält. Hier ist die modifizierte SaveBlobs Funktion:Warum schreibt die HDF5 Output Caffe-Schicht Daten mit scheinbar falschen Abmessungen?

template <typename Dtype> void HDF5OutputLayer<Dtype>::SaveBlobs() {        
    LOG(INFO) << "Saving HDF5 file " << file_name_ << "ds: " << ds_iter_; 
    CHECK_EQ(data_blob_.num(), label_blob_.num()) <<      
     "data blob and label blob must have the same batch size";   

    // Open hdf5 file to write this blob         
    file_name_ = this->layer_param_.hdf5_output_param().file_name();   
    ostringstream appender;             
    appender << "_" << ds_iter_ << ".h5";         
    file_name_.append(appender.str());          
    file_id_ = H5Fcreate(file_name_.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, 
         H5P_DEFAULT);          
    CHECK_GE(file_id_, 0) << "Failed to open HDF5 file" << file_name_;   

    // Write the data and label            
    hdf5_save_nd_dataset(file_id_, HDF5_DATA_DATASET_NAME, data_blob_);  
    hdf5_save_nd_dataset(file_id_, HDF5_DATA_LABEL_NAME, label_blob_);   
    LOG(INFO) << "Successfully saved " << data_blob_.num() << " rows";   
    LOG(INFO) << "SAVEBLOB - Data size is: " << data_blob_.shape_string(); 
    LOG(INFO) << "SAVEBLOB - Label size is: " << label_blob_.shape_string(); 

    // Close the file              
    herr_t status = H5Fclose(file_id_);          
    CHECK_GE(status, 0) << "Failed to close HDF5 file " << file_name_;   

    // Update iterator for next image          
    ds_iter_++;                
} 

Der Code fast funktioniert gut, da ich in der Lage bin, um erfolgreich Dateien zu erstellen für jedes Bild, das in der Tat enthält Daten. Leider scheint es, als ob die falschen Daten geschrieben werden, da sowohl die im Protokoll als auch in der resultierenden Ausgabedatei angezeigten Dimensionen falsch sind. Hier ist, wo ich meine Ausgangsschicht (im Netzwerk Proto) angeben:

layer {                 
    name: "conv5_3"               
    type: "Convolution"              
    bottom: "conv5_2"              
    top: "conv5_3"               
    param {                 
    lr_mult: 1               
    decay_mult: 1               
    }                  
    param {                 
    lr_mult: 2               
    decay_mult: 0               
    }                  
    convolution_param {              
    num_output: 512              
    pad: 1                
    kernel_size: 3              
    }                  
}                   
layer {                 
    name: "relu5_3"               
    type: "ReLU"               
    bottom: "conv5_3"              
    top: "conv5_3"               
}                   

#===== Data Logging =======            

layer {                 
    type: "HDF5Output"              
    name: "hdf5output"              
    bottom: "conv5_3" #             
    bottom: "conv5_3" #             
    hdf5_output_param {             
    # File name is only a base           
    file_name: "./test_features/image"         
    }                  
} 

Mein Grund zu der Annahme besteht, dass die falschen Daten gespeichert werden, weil, wenn ich die Netzwerkeinrichtung beobachten, die Abmessungen für die oben conv5_3 sind wie folgt dargestellt:

I0206 23:07:44.815330 7630 layer_factory.hpp:77] Creating layer conv5_3_relu5_3_0_split 
I0206 23:07:44.815343 7630 net.cpp:106] Creating Layer conv5_3_relu5_3_0_split 
I0206 23:07:44.815348 7630 net.cpp:454] conv5_3_relu5_3_0_split <- conv5_3 
I0206 23:07:44.815356 7630 net.cpp:411] conv5_3_relu5_3_0_split -> conv5_3_relu5_3_0_split_0 
I0206 23:07:44.815366 7630 net.cpp:411] conv5_3_relu5_3_0_split -> conv5_3_relu5_3_0_split_1 
I0206 23:07:44.815372 7630 net.cpp:411] conv5_3_relu5_3_0_split -> conv5_3_relu5_3_0_split_2 
I0206 23:07:44.815382 7630 net.cpp:411] conv5_3_relu5_3_0_split -> conv5_3_relu5_3_0_split_3 
I0206 23:07:44.815459 7630 net.cpp:150] Setting up conv5_3_relu5_3_0_split 
I0206 23:07:44.815467 7630 net.cpp:157] Top shape: 1 512 14 14 (100352) 
I0206 23:07:44.815474 7630 net.cpp:157] Top shape: 1 512 14 14 (100352) 
I0206 23:07:44.815479 7630 net.cpp:157] Top shape: 1 512 14 14 (100352) 
I0206 23:07:44.815484 7630 net.cpp:157] Top shape: 1 512 14 14 (100352) 
I0206 23:07:44.815495 7630 net.cpp:165] Memory required for data: 116006912 
I0206 23:07:44.815500 7630 layer_factory.hpp:77] Creating layer hdf5output 
I0206 23:07:44.815511 7630 net.cpp:106] Creating Layer hdf5output 
I0206 23:07:44.815515 7630 net.cpp:454] hdf5output <- conv5_3_relu5_3_0_split_0 
I0206 23:07:44.815521 7630 net.cpp:454] hdf5output <- conv5_3_relu5_3_0_split_1 
I0206 23:07:44.815527 7630 net.cpp:150] Setting up hdf5output 
I0206 23:07:44.815531 7630 net.cpp:165] Memory required for data: 116006912 

so groß, erwarte ich Leider haben Daten von Dimensionen 1 512 14 14, wenn ich Inferenz auf dem Modell laufe ich in meinem Log sehen, dass die falschen Dimensionen zeigen sich:

I0206 23:07:46.108660 7630 hdf5_output_layer.cpp:31] Saving HDF5 file ds: 0 
I0206 23:07:46.115536 7630 hdf5_output_layer.cpp:48] Successfully saved 1 rows 
I0206 23:07:46.115557 7630 hdf5_output_layer.cpp:49] SAVEBLOB - Data size is: 1 512 54 38 (1050624) 
I0206 23:07:46.115566 7630 hdf5_output_layer.cpp:50] SAVEBLOB - Label size is: 1 512 54 38 (1050624) 
I0206 23:07:46.316557 7630 hdf5_output_layer.cpp:31] Saving HDF5 file ./test_features/image_0.h5ds: 1 
I0206 23:07:46.322437 7630 hdf5_output_layer.cpp:48] Successfully saved 1 rows 
I0206 23:07:46.322456 7630 hdf5_output_layer.cpp:49] SAVEBLOB - Data size is: 1 512 56 38 (1089536) 
I0206 23:07:46.322463 7630 hdf5_output_layer.cpp:50] SAVEBLOB - Label size is: 1 512 56 38 (1089536) 
I0206 23:07:46.457828 7630 hdf5_output_layer.cpp:31] Saving HDF5 file ./test_features/image_1.h5ds: 2 
I0206 23:07:46.463618 7630 hdf5_output_layer.cpp:48] Successfully saved 1 rows 
I0206 23:07:46.463636 7630 hdf5_output_layer.cpp:49] SAVEBLOB - Data size is: 1 512 38 50 (972800) 
I0206 23:07:46.463644 7630 hdf5_output_layer.cpp:50] SAVEBLOB - Label size is: 1 512 38 50 (972800) 
I0206 23:07:46.594746 7630 hdf5_output_layer.cpp:31] Saving HDF5 file ./test_features/image_2.h5ds: 3 

Dies zeigt, dass nicht nur die Dimensionen der Ausgabe falsch sind, sondern auch zwischen Iterationen (Bildern) variieren! Die Dimensionen, die im Protokoll angezeigt werden, stimmen mit den Dimensionen der Daten überein, die in die h5-Dateien geschrieben wurden. Daher beschreibt das Protokoll genau das Verhalten des Codes. Meine Frage ist, warum könnte das der Fall sein? Es scheint, dass ich alles richtig eingerichtet habe, aber da muss etwas sein, das mir fehlt ...

+0

Sind Sie sicher, dass alle Eingabebilder, die Sie in das Netzwerk eingeben, die gleiche Größe haben? – hbaderts

+0

Danke für die Antwort! Die JPEG-Bilder sind von unterschiedlicher Größe, die Eingabedatenebene wird jedoch als 1 × 3 × 224 × 224 spezifiziert. Es sieht also so aus, als ob das Netzwerk alle Bilder von derselben Größe wie diese Eingabedimensionen skaliert . – Kantthpel

+1

Lassen Sie mich raten: Ihr erstes Bild ist 864x608 Pixel, das zweite ist 896x608 Pixel, und das dritte ist 608x800 Pixel? Können Sie zeigen, wie Sie die Bilder in das Netzwerk laden? I.e. Welche Datenschicht hast du und wie läuft Caffe? Ich denke, dass Ihre modifizierte HDF5-Schicht in Ordnung ist, und dass das Laden der Daten das Problem ist. – hbaderts

Antwort

0

Da @hbaderts mir geholfen hat aufzudecken, stellt sich heraus, dass die HDF5-Schicht korrekt ist und Daten ausgibt die richtigen Dimensionen. Meine Verwechslung mit den Dimensionen war auf die scheinbar statische Definition der Eingabedimensionen in der Testversion des Netzwerkprototextes zurückzuführen. Es stellt sich heraus, dass, weil ich Daten mit der Pycaffe-Funktion net.forward (** forward_kwargs) einlade, sich die Faltungslayer selbst skalieren, um den unterschiedlichen Eingabeabmessungen meiner Eingabebilder zu entsprechen. Dies erklärt sowohl die größer als erwarteten Feature-Dimensionen als auch die Tatsache, dass sie zwischen den Bildern variieren.

Verwandte Themen