Path: blob/master/modules/dnn/src/caffe/caffe_io.cpp
16339 views
/*M///////////////////////////////////////////////////////////////////////////////////////1//2// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.3//4// By downloading, copying, installing or using the software you agree to this license.5// If you do not agree to this license, do not download, install,6// copy or use the software.7//8//9// License Agreement10// For Open Source Computer Vision Library11//12// Copyright (C) 2013, OpenCV Foundation, all rights reserved.13// Third party copyrights are property of their respective owners.14//15// Redistribution and use in source and binary forms, with or without modification,16// are permitted provided that the following conditions are met:17//18// * Redistribution's of source code must retain the above copyright notice,19// this list of conditions and the following disclaimer.20//21// * Redistribution's in binary form must reproduce the above copyright notice,22// this list of conditions and the following disclaimer in the documentation23// and/or other materials provided with the distribution.24//25// * The name of the copyright holders may not be used to endorse or promote products26// derived from this software without specific prior written permission.27//28// This software is provided by the copyright holders and contributors "as is" and29// any express or implied warranties, including, but not limited to, the implied30// warranties of merchantability and fitness for a particular purpose are disclaimed.31// In no event shall the Intel Corporation or contributors be liable for any direct,32// indirect, incidental, special, exemplary, or consequential damages33// (including, but not limited to, procurement of substitute goods or services;34// loss of use, data, or profits; or business interruption) however caused35// and on any theory of liability, whether in contract, strict liability,36// or tort (including negligence or otherwise) arising in any way out of37// the use of this software, even if advised of the possibility of such damage.38//39//M*/4041/*M///////////////////////////////////////////////////////////////////////////////////////42//COPYRIGHT43//44//All contributions by the University of California:45//Copyright (c) 2014, The Regents of the University of California (Regents)46//All rights reserved.47//48//All other contributions:49//Copyright (c) 2014, the respective contributors50//All rights reserved.51//52//Caffe uses a shared copyright model: each contributor holds copyright over53//their contributions to Caffe. The project versioning records all such54//contribution and copyright details. If a contributor wants to further mark55//their specific copyright on a particular contribution, they should indicate56//their copyright solely in the commit message of the change when it is57//committed.58//59//LICENSE60//61//Redistribution and use in source and binary forms, with or without62//modification, are permitted provided that the following conditions are met:63//64//1. Redistributions of source code must retain the above copyright notice, this65// list of conditions and the following disclaimer.66//2. Redistributions in binary form must reproduce the above copyright notice,67// this list of conditions and the following disclaimer in the documentation68// and/or other materials provided with the distribution.69//70//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND71//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED72//WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE73//DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR74//ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES75//(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;76//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND77//ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT78//(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS79//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.80//81//CONTRIBUTION AGREEMENT82//83//By contributing to the BVLC/caffe repository through pull-request, comment,84//or otherwise, the contributor releases their content to the85//license and copyright terms herein.86//87//M*/8889#include "../precomp.hpp"9091#ifdef HAVE_PROTOBUF92#include <google/protobuf/io/coded_stream.h>93#include <google/protobuf/io/zero_copy_stream_impl.h>94#include <google/protobuf/text_format.h>9596#include <opencv2/core.hpp>9798#include <map>99#include <string>100#include <fstream>101#include <vector>102103#include "caffe_io.hpp"104#include "glog_emulator.hpp"105106namespace cv {107namespace dnn {108109using std::string;110using std::map;111using namespace caffe;112using namespace ::google::protobuf;113using namespace ::google::protobuf::io;114115// Return true iff the net is not the current version.116bool NetNeedsUpgrade(const NetParameter& net_param);117118// Return true iff any layer contains parameters specified using119// deprecated V0LayerParameter.120bool NetNeedsV0ToV1Upgrade(const NetParameter& net_param);121122// Perform all necessary transformations to upgrade a V0NetParameter into a123// NetParameter (including upgrading padding layers and LayerParameters).124bool UpgradeV0Net(const NetParameter& v0_net_param, NetParameter* net_param);125126// Upgrade NetParameter with padding layers to pad-aware conv layers.127// For any padding layer, remove it and put its pad parameter in any layers128// taking its top blob as input.129// Error if any of these above layers are not-conv layers.130void UpgradeV0PaddingLayers(const NetParameter& param,131NetParameter* param_upgraded_pad);132133// Upgrade a single V0LayerConnection to the V1LayerParameter format.134bool UpgradeV0LayerParameter(V1LayerParameter* v0_layer_connection,135V1LayerParameter* layer_param);136137V1LayerParameter_LayerType UpgradeV0LayerType(const string& type);138139// Return true iff any layer contains deprecated data transformation parameters.140bool NetNeedsDataUpgrade(const NetParameter& net_param);141142// Perform all necessary transformations to upgrade old transformation fields143// into a TransformationParameter.144void UpgradeNetDataTransformation(NetParameter* net_param);145146// Return true iff the Net contains any layers specified as V1LayerParameters.147bool NetNeedsV1ToV2Upgrade(const NetParameter& net_param);148149// Perform all necessary transformations to upgrade a NetParameter with150// deprecated V1LayerParameters.151bool UpgradeV1Net(NetParameter* net_param);152153bool UpgradeV1LayerParameter(V1LayerParameter* v1_layer_param,154LayerParameter* layer_param);155156const char* UpgradeV1LayerType(const V1LayerParameter_LayerType type);157158bool NetNeedsBatchNormUpgrade(const NetParameter& net_param);159160void UpgradeNetBatchNorm(NetParameter* net_param);161162// Check for deprecations and upgrade the NetParameter as needed.163bool UpgradeNetAsNeeded(const string& param_file, NetParameter* param);164165166bool NetNeedsUpgrade(const NetParameter& net_param) {167return NetNeedsV0ToV1Upgrade(net_param) || NetNeedsV1ToV2Upgrade(net_param) ||168NetNeedsBatchNormUpgrade(net_param);169}170171bool NetNeedsV0ToV1Upgrade(const NetParameter& net_param) {172for (int i = 0; i < net_param.layers_size(); ++i) {173if (net_param.layers(i).has_layer()) {174return true;175}176}177return false;178}179180bool NetNeedsV1ToV2Upgrade(const NetParameter& net_param) {181return net_param.layers_size() > 0;182}183184bool UpgradeV0Net(const NetParameter& v0_net_param_padding_layers,185NetParameter* net_param) {186// First upgrade padding layers to padded conv layers.187NetParameter v0_net_param;188UpgradeV0PaddingLayers(v0_net_param_padding_layers, &v0_net_param);189// Now upgrade layer parameters.190bool is_fully_compatible = true;191net_param->Clear();192if (v0_net_param.has_name()) {193net_param->set_name(v0_net_param.name());194}195for (int i = 0; i < v0_net_param.layers_size(); ++i) {196is_fully_compatible &= UpgradeV0LayerParameter(v0_net_param.mutable_layers(i),197net_param->add_layers());198}199for (int i = 0; i < v0_net_param.input_size(); ++i) {200net_param->add_input(v0_net_param.input(i));201}202for (int i = 0; i < v0_net_param.input_dim_size(); ++i) {203net_param->add_input_dim(v0_net_param.input_dim(i));204}205if (v0_net_param.has_force_backward()) {206net_param->set_force_backward(v0_net_param.force_backward());207}208return is_fully_compatible;209}210211void UpgradeV0PaddingLayers(const NetParameter& param,212NetParameter* param_upgraded_pad) {213// Copy everything other than the layers from the original param.214param_upgraded_pad->Clear();215param_upgraded_pad->CopyFrom(param);216param_upgraded_pad->clear_layers();217// Figure out which layer each bottom blob comes from.218map<string, int> blob_name_to_last_top_idx;219for (int i = 0; i < param.input_size(); ++i) {220const string& blob_name = param.input(i);221blob_name_to_last_top_idx[blob_name] = -1;222}223for (int i = 0; i < param.layers_size(); ++i) {224const V1LayerParameter& layer_connection = param.layers(i);225const V0LayerParameter& layer_param = layer_connection.layer();226// Add the layer to the new net, unless it's a padding layer.227if (layer_param.type() != "padding") {228param_upgraded_pad->add_layers()->CopyFrom(layer_connection);229}230for (int j = 0; j < layer_connection.bottom_size(); ++j) {231const string& blob_name = layer_connection.bottom(j);232if (blob_name_to_last_top_idx.find(blob_name) ==233blob_name_to_last_top_idx.end()) {234LOG(FATAL) << "Unknown blob input " << blob_name << " to layer " << j;235}236const int top_idx = blob_name_to_last_top_idx[blob_name];237if (top_idx == -1) {238continue;239}240const V1LayerParameter& source_layer = param.layers(top_idx);241if (source_layer.layer().type() == "padding") {242// This layer has a padding layer as input -- check that it is a conv243// layer or a pooling layer and takes only one input. Also check that244// the padding layer input has only one input and one output. Other245// cases have undefined behavior in Caffe.246CHECK((layer_param.type() == "conv") || (layer_param.type() == "pool"))247<< "Padding layer input to "248"non-convolutional / non-pooling layer type "249<< layer_param.type();250CHECK_EQ(layer_connection.bottom_size(), 1)251<< "Conv Layer takes a single blob as input.";252CHECK_EQ(source_layer.bottom_size(), 1)253<< "Padding Layer takes a single blob as input.";254CHECK_EQ(source_layer.top_size(), 1)255<< "Padding Layer produces a single blob as output.";256int layer_index = param_upgraded_pad->layers_size() - 1;257param_upgraded_pad->mutable_layers(layer_index)->mutable_layer()258->set_pad(source_layer.layer().pad());259param_upgraded_pad->mutable_layers(layer_index)260->set_bottom(j, source_layer.bottom(0));261}262}263for (int j = 0; j < layer_connection.top_size(); ++j) {264const string& blob_name = layer_connection.top(j);265blob_name_to_last_top_idx[blob_name] = i;266}267}268}269270bool UpgradeV0LayerParameter(V1LayerParameter* v0_layer_connection_,271V1LayerParameter* layer_param) {272CV_Assert(v0_layer_connection_ != NULL);273const V1LayerParameter& v0_layer_connection = *v0_layer_connection_;274bool is_fully_compatible = true;275layer_param->Clear();276for (int i = 0; i < v0_layer_connection.bottom_size(); ++i) {277layer_param->add_bottom(v0_layer_connection.bottom(i));278}279for (int i = 0; i < v0_layer_connection.top_size(); ++i) {280layer_param->add_top(v0_layer_connection.top(i));281}282if (v0_layer_connection.has_layer()) {283const V0LayerParameter& v0_layer_param = v0_layer_connection.layer();284if (v0_layer_param.has_name()) {285layer_param->set_name(v0_layer_param.name());286}287const string& type = v0_layer_param.type();288if (v0_layer_param.has_type()) {289layer_param->set_type(UpgradeV0LayerType(type));290}291layer_param->mutable_blobs()->Swap(v0_layer_connection_->mutable_blobs());292for (int i = 0; i < v0_layer_param.blobs_lr_size(); ++i) {293layer_param->add_blobs_lr(v0_layer_param.blobs_lr(i));294}295for (int i = 0; i < v0_layer_param.weight_decay_size(); ++i) {296layer_param->add_weight_decay(v0_layer_param.weight_decay(i));297}298if (v0_layer_param.has_num_output()) {299if (type == "conv") {300layer_param->mutable_convolution_param()->set_num_output(301v0_layer_param.num_output());302} else if (type == "innerproduct") {303layer_param->mutable_inner_product_param()->set_num_output(304v0_layer_param.num_output());305} else {306LOG(ERROR) << "Unknown parameter num_output for layer type " << type;307is_fully_compatible = false;308}309}310if (v0_layer_param.has_biasterm()) {311if (type == "conv") {312layer_param->mutable_convolution_param()->set_bias_term(313v0_layer_param.biasterm());314} else if (type == "innerproduct") {315layer_param->mutable_inner_product_param()->set_bias_term(316v0_layer_param.biasterm());317} else {318LOG(ERROR) << "Unknown parameter biasterm for layer type " << type;319is_fully_compatible = false;320}321}322if (v0_layer_param.has_weight_filler()) {323if (type == "conv") {324layer_param->mutable_convolution_param()->325mutable_weight_filler()->CopyFrom(v0_layer_param.weight_filler());326} else if (type == "innerproduct") {327layer_param->mutable_inner_product_param()->328mutable_weight_filler()->CopyFrom(v0_layer_param.weight_filler());329} else {330LOG(ERROR) << "Unknown parameter weight_filler for layer type " << type;331is_fully_compatible = false;332}333}334if (v0_layer_param.has_bias_filler()) {335if (type == "conv") {336layer_param->mutable_convolution_param()->337mutable_bias_filler()->CopyFrom(v0_layer_param.bias_filler());338} else if (type == "innerproduct") {339layer_param->mutable_inner_product_param()->340mutable_bias_filler()->CopyFrom(v0_layer_param.bias_filler());341} else {342LOG(ERROR) << "Unknown parameter bias_filler for layer type " << type;343is_fully_compatible = false;344}345}346if (v0_layer_param.has_pad()) {347if (type == "conv") {348layer_param->mutable_convolution_param()->add_pad(v0_layer_param.pad());349} else if (type == "pool") {350layer_param->mutable_pooling_param()->set_pad(v0_layer_param.pad());351} else {352LOG(ERROR) << "Unknown parameter pad for layer type " << type;353is_fully_compatible = false;354}355}356if (v0_layer_param.has_kernelsize()) {357if (type == "conv") {358layer_param->mutable_convolution_param()->add_kernel_size(359v0_layer_param.kernelsize());360} else if (type == "pool") {361layer_param->mutable_pooling_param()->set_kernel_size(362v0_layer_param.kernelsize());363} else {364LOG(ERROR) << "Unknown parameter kernelsize for layer type " << type;365is_fully_compatible = false;366}367}368if (v0_layer_param.has_group()) {369if (type == "conv") {370layer_param->mutable_convolution_param()->set_group(371v0_layer_param.group());372} else {373LOG(ERROR) << "Unknown parameter group for layer type " << type;374is_fully_compatible = false;375}376}377if (v0_layer_param.has_stride()) {378if (type == "conv") {379layer_param->mutable_convolution_param()->add_stride(380v0_layer_param.stride());381} else if (type == "pool") {382layer_param->mutable_pooling_param()->set_stride(383v0_layer_param.stride());384} else {385LOG(ERROR) << "Unknown parameter stride for layer type " << type;386is_fully_compatible = false;387}388}389if (v0_layer_param.has_pool()) {390if (type == "pool") {391V0LayerParameter_PoolMethod pool = v0_layer_param.pool();392switch (pool) {393case V0LayerParameter_PoolMethod_MAX:394layer_param->mutable_pooling_param()->set_pool(395PoolingParameter_PoolMethod_MAX);396break;397case V0LayerParameter_PoolMethod_AVE:398layer_param->mutable_pooling_param()->set_pool(399PoolingParameter_PoolMethod_AVE);400break;401case V0LayerParameter_PoolMethod_STOCHASTIC:402layer_param->mutable_pooling_param()->set_pool(403PoolingParameter_PoolMethod_STOCHASTIC);404break;405default:406LOG(ERROR) << "Unknown pool method " << pool;407is_fully_compatible = false;408}409} else {410LOG(ERROR) << "Unknown parameter pool for layer type " << type;411is_fully_compatible = false;412}413}414if (v0_layer_param.has_dropout_ratio()) {415if (type == "dropout") {416layer_param->mutable_dropout_param()->set_dropout_ratio(417v0_layer_param.dropout_ratio());418} else {419LOG(ERROR) << "Unknown parameter dropout_ratio for layer type " << type;420is_fully_compatible = false;421}422}423if (v0_layer_param.has_local_size()) {424if (type == "lrn") {425layer_param->mutable_lrn_param()->set_local_size(426v0_layer_param.local_size());427} else {428LOG(ERROR) << "Unknown parameter local_size for layer type " << type;429is_fully_compatible = false;430}431}432if (v0_layer_param.has_alpha()) {433if (type == "lrn") {434layer_param->mutable_lrn_param()->set_alpha(v0_layer_param.alpha());435} else {436LOG(ERROR) << "Unknown parameter alpha for layer type " << type;437is_fully_compatible = false;438}439}440if (v0_layer_param.has_beta()) {441if (type == "lrn") {442layer_param->mutable_lrn_param()->set_beta(v0_layer_param.beta());443} else {444LOG(ERROR) << "Unknown parameter beta for layer type " << type;445is_fully_compatible = false;446}447}448if (v0_layer_param.has_k()) {449if (type == "lrn") {450layer_param->mutable_lrn_param()->set_k(v0_layer_param.k());451} else {452LOG(ERROR) << "Unknown parameter k for layer type " << type;453is_fully_compatible = false;454}455}456if (v0_layer_param.has_source()) {457if (type == "data") {458layer_param->mutable_data_param()->set_source(v0_layer_param.source());459} else if (type == "hdf5_data") {460layer_param->mutable_hdf5_data_param()->set_source(461v0_layer_param.source());462} else if (type == "images") {463layer_param->mutable_image_data_param()->set_source(464v0_layer_param.source());465} else if (type == "window_data") {466layer_param->mutable_window_data_param()->set_source(467v0_layer_param.source());468} else if (type == "infogain_loss") {469layer_param->mutable_infogain_loss_param()->set_source(470v0_layer_param.source());471} else {472LOG(ERROR) << "Unknown parameter source for layer type " << type;473is_fully_compatible = false;474}475}476if (v0_layer_param.has_scale()) {477layer_param->mutable_transform_param()->478set_scale(v0_layer_param.scale());479}480if (v0_layer_param.has_meanfile()) {481layer_param->mutable_transform_param()->482set_mean_file(v0_layer_param.meanfile());483}484if (v0_layer_param.has_batchsize()) {485if (type == "data") {486layer_param->mutable_data_param()->set_batch_size(487v0_layer_param.batchsize());488} else if (type == "hdf5_data") {489layer_param->mutable_hdf5_data_param()->set_batch_size(490v0_layer_param.batchsize());491} else if (type == "images") {492layer_param->mutable_image_data_param()->set_batch_size(493v0_layer_param.batchsize());494} else if (type == "window_data") {495layer_param->mutable_window_data_param()->set_batch_size(496v0_layer_param.batchsize());497} else {498LOG(ERROR) << "Unknown parameter batchsize for layer type " << type;499is_fully_compatible = false;500}501}502if (v0_layer_param.has_cropsize()) {503layer_param->mutable_transform_param()->504set_crop_size(v0_layer_param.cropsize());505}506if (v0_layer_param.has_mirror()) {507layer_param->mutable_transform_param()->508set_mirror(v0_layer_param.mirror());509}510if (v0_layer_param.has_rand_skip()) {511if (type == "data") {512layer_param->mutable_data_param()->set_rand_skip(513v0_layer_param.rand_skip());514} else if (type == "images") {515layer_param->mutable_image_data_param()->set_rand_skip(516v0_layer_param.rand_skip());517} else {518LOG(ERROR) << "Unknown parameter rand_skip for layer type " << type;519is_fully_compatible = false;520}521}522if (v0_layer_param.has_shuffle_images()) {523if (type == "images") {524layer_param->mutable_image_data_param()->set_shuffle(525v0_layer_param.shuffle_images());526} else {527LOG(ERROR) << "Unknown parameter shuffle for layer type " << type;528is_fully_compatible = false;529}530}531if (v0_layer_param.has_new_height()) {532if (type == "images") {533layer_param->mutable_image_data_param()->set_new_height(534v0_layer_param.new_height());535} else {536LOG(ERROR) << "Unknown parameter new_height for layer type " << type;537is_fully_compatible = false;538}539}540if (v0_layer_param.has_new_width()) {541if (type == "images") {542layer_param->mutable_image_data_param()->set_new_width(543v0_layer_param.new_width());544} else {545LOG(ERROR) << "Unknown parameter new_width for layer type " << type;546is_fully_compatible = false;547}548}549if (v0_layer_param.has_concat_dim()) {550if (type == "concat") {551layer_param->mutable_concat_param()->set_concat_dim(552v0_layer_param.concat_dim());553} else {554LOG(ERROR) << "Unknown parameter concat_dim for layer type " << type;555is_fully_compatible = false;556}557}558if (v0_layer_param.has_det_fg_threshold()) {559if (type == "window_data") {560layer_param->mutable_window_data_param()->set_fg_threshold(561v0_layer_param.det_fg_threshold());562} else {563LOG(ERROR) << "Unknown parameter det_fg_threshold for layer type "564<< type;565is_fully_compatible = false;566}567}568if (v0_layer_param.has_det_bg_threshold()) {569if (type == "window_data") {570layer_param->mutable_window_data_param()->set_bg_threshold(571v0_layer_param.det_bg_threshold());572} else {573LOG(ERROR) << "Unknown parameter det_bg_threshold for layer type "574<< type;575is_fully_compatible = false;576}577}578if (v0_layer_param.has_det_fg_fraction()) {579if (type == "window_data") {580layer_param->mutable_window_data_param()->set_fg_fraction(581v0_layer_param.det_fg_fraction());582} else {583LOG(ERROR) << "Unknown parameter det_fg_fraction for layer type "584<< type;585is_fully_compatible = false;586}587}588if (v0_layer_param.has_det_context_pad()) {589if (type == "window_data") {590layer_param->mutable_window_data_param()->set_context_pad(591v0_layer_param.det_context_pad());592} else {593LOG(ERROR) << "Unknown parameter det_context_pad for layer type "594<< type;595is_fully_compatible = false;596}597}598if (v0_layer_param.has_det_crop_mode()) {599if (type == "window_data") {600layer_param->mutable_window_data_param()->set_crop_mode(601v0_layer_param.det_crop_mode());602} else {603LOG(ERROR) << "Unknown parameter det_crop_mode for layer type "604<< type;605is_fully_compatible = false;606}607}608if (v0_layer_param.has_hdf5_output_param()) {609if (type == "hdf5_output") {610layer_param->mutable_hdf5_output_param()->CopyFrom(611v0_layer_param.hdf5_output_param());612} else {613LOG(ERROR) << "Unknown parameter hdf5_output_param for layer type "614<< type;615is_fully_compatible = false;616}617}618}619return is_fully_compatible;620}621622V1LayerParameter_LayerType UpgradeV0LayerType(const string& type) {623if (type == "accuracy") {624return V1LayerParameter_LayerType_ACCURACY;625} else if (type == "bnll") {626return V1LayerParameter_LayerType_BNLL;627} else if (type == "concat") {628return V1LayerParameter_LayerType_CONCAT;629} else if (type == "conv") {630return V1LayerParameter_LayerType_CONVOLUTION;631} else if (type == "data") {632return V1LayerParameter_LayerType_DATA;633} else if (type == "dropout") {634return V1LayerParameter_LayerType_DROPOUT;635} else if (type == "euclidean_loss") {636return V1LayerParameter_LayerType_EUCLIDEAN_LOSS;637} else if (type == "flatten") {638return V1LayerParameter_LayerType_FLATTEN;639} else if (type == "hdf5_data") {640return V1LayerParameter_LayerType_HDF5_DATA;641} else if (type == "hdf5_output") {642return V1LayerParameter_LayerType_HDF5_OUTPUT;643} else if (type == "im2col") {644return V1LayerParameter_LayerType_IM2COL;645} else if (type == "images") {646return V1LayerParameter_LayerType_IMAGE_DATA;647} else if (type == "infogain_loss") {648return V1LayerParameter_LayerType_INFOGAIN_LOSS;649} else if (type == "innerproduct") {650return V1LayerParameter_LayerType_INNER_PRODUCT;651} else if (type == "lrn") {652return V1LayerParameter_LayerType_LRN;653} else if (type == "multinomial_logistic_loss") {654return V1LayerParameter_LayerType_MULTINOMIAL_LOGISTIC_LOSS;655} else if (type == "pool") {656return V1LayerParameter_LayerType_POOLING;657} else if (type == "relu") {658return V1LayerParameter_LayerType_RELU;659} else if (type == "sigmoid") {660return V1LayerParameter_LayerType_SIGMOID;661} else if (type == "softmax") {662return V1LayerParameter_LayerType_SOFTMAX;663} else if (type == "softmax_loss") {664return V1LayerParameter_LayerType_SOFTMAX_LOSS;665} else if (type == "split") {666return V1LayerParameter_LayerType_SPLIT;667} else if (type == "tanh") {668return V1LayerParameter_LayerType_TANH;669} else if (type == "window_data") {670return V1LayerParameter_LayerType_WINDOW_DATA;671} else {672LOG(FATAL) << "Unknown layer name: " << type;673return V1LayerParameter_LayerType_NONE;674}675}676677bool NetNeedsDataUpgrade(const NetParameter& net_param) {678for (int i = 0; i < net_param.layers_size(); ++i) {679if (net_param.layers(i).type() == V1LayerParameter_LayerType_DATA) {680DataParameter layer_param = net_param.layers(i).data_param();681if (layer_param.has_scale()) { return true; }682if (layer_param.has_mean_file()) { return true; }683if (layer_param.has_crop_size()) { return true; }684if (layer_param.has_mirror()) { return true; }685}686if (net_param.layers(i).type() == V1LayerParameter_LayerType_IMAGE_DATA) {687ImageDataParameter layer_param = net_param.layers(i).image_data_param();688if (layer_param.has_scale()) { return true; }689if (layer_param.has_mean_file()) { return true; }690if (layer_param.has_crop_size()) { return true; }691if (layer_param.has_mirror()) { return true; }692}693if (net_param.layers(i).type() == V1LayerParameter_LayerType_WINDOW_DATA) {694WindowDataParameter layer_param = net_param.layers(i).window_data_param();695if (layer_param.has_scale()) { return true; }696if (layer_param.has_mean_file()) { return true; }697if (layer_param.has_crop_size()) { return true; }698if (layer_param.has_mirror()) { return true; }699}700}701return false;702}703704#define CONVERT_LAYER_TRANSFORM_PARAM(TYPE, Name, param_name) \705do { \706if (net_param->layers(i).type() == V1LayerParameter_LayerType_##TYPE) { \707Name##Parameter* layer_param = \708net_param->mutable_layers(i)->mutable_##param_name##_param(); \709TransformationParameter* transform_param = \710net_param->mutable_layers(i)->mutable_transform_param(); \711if (layer_param->has_scale()) { \712transform_param->set_scale(layer_param->scale()); \713layer_param->clear_scale(); \714} \715if (layer_param->has_mean_file()) { \716transform_param->set_mean_file(layer_param->mean_file()); \717layer_param->clear_mean_file(); \718} \719if (layer_param->has_crop_size()) { \720transform_param->set_crop_size(layer_param->crop_size()); \721layer_param->clear_crop_size(); \722} \723if (layer_param->has_mirror()) { \724transform_param->set_mirror(layer_param->mirror()); \725layer_param->clear_mirror(); \726} \727} \728} while (0)729730void UpgradeNetDataTransformation(NetParameter* net_param) {731for (int i = 0; i < net_param->layers_size(); ++i) {732CONVERT_LAYER_TRANSFORM_PARAM(DATA, Data, data);733CONVERT_LAYER_TRANSFORM_PARAM(IMAGE_DATA, ImageData, image_data);734CONVERT_LAYER_TRANSFORM_PARAM(WINDOW_DATA, WindowData, window_data);735}736}737738bool UpgradeNetAsNeeded(const string& param_file, NetParameter* param) {739bool success = true;740if (NetNeedsV0ToV1Upgrade(*param)) {741// NetParameter was specified using the old style (V0LayerParameter); try to742// upgrade it.743LOG(ERROR) << "Attempting to upgrade input file specified using deprecated "744<< "V0LayerParameter: " << param_file;745NetParameter original_param(*param);746if (!UpgradeV0Net(original_param, param)) {747success = false;748LOG(ERROR) << "Warning: had one or more problems upgrading "749<< "V0NetParameter to NetParameter (see above); continuing anyway.";750} else {751LOG(INFO) << "Successfully upgraded file specified using deprecated "752<< "V0LayerParameter";753}754LOG(ERROR) << "Note that future Caffe releases will not support "755<< "V0NetParameter; use ./build/tools/upgrade_net_proto_text for "756<< "prototxt and ./build/tools/upgrade_net_proto_binary for model "757<< "weights upgrade this and any other net protos to the new format.";758}759// NetParameter uses old style data transformation fields; try to upgrade it.760if (NetNeedsDataUpgrade(*param)) {761LOG(ERROR) << "Attempting to upgrade input file specified using deprecated "762<< "transformation parameters: " << param_file;763UpgradeNetDataTransformation(param);764LOG(INFO) << "Successfully upgraded file specified using deprecated "765<< "data transformation parameters.";766LOG(ERROR) << "Note that future Caffe releases will only support "767<< "transform_param messages for transformation fields.";768}769if (NetNeedsV1ToV2Upgrade(*param)) {770LOG(ERROR) << "Attempting to upgrade input file specified using deprecated "771<< "V1LayerParameter: " << param_file;772if (!UpgradeV1Net(param)) {773success = false;774LOG(ERROR) << "Warning: had one or more problems upgrading "775<< "V1LayerParameter (see above); continuing anyway.";776} else {777LOG(INFO) << "Successfully upgraded file specified using deprecated "778<< "V1LayerParameter";779}780}781// NetParameter uses old style batch norm layers; try to upgrade it.782if (NetNeedsBatchNormUpgrade(*param)) {783LOG(INFO) << "Attempting to upgrade batch norm layers using deprecated "784<< "params: " << param_file;785UpgradeNetBatchNorm(param);786LOG(INFO) << "Successfully upgraded batch norm layers using deprecated "787<< "params.";788}789return success;790}791792bool UpgradeV1Net(NetParameter* net_param) {793// V1LayerParameter layers -> LayerParameter layer794CV_Assert(net_param != NULL);795bool is_fully_compatible = true;796if (net_param->layer_size() > 0) {797LOG(ERROR) << "Input NetParameter to be upgraded already specifies 'layer' "798<< "fields; these will be ignored for the upgrade.";799is_fully_compatible = false;800}801net_param->clear_layer();802for (int i = 0; i < net_param->layers_size(); ++i) {803if (!UpgradeV1LayerParameter(net_param->mutable_layers(i),804net_param->add_layer())) {805LOG(ERROR) << "Upgrade of input layer " << i << " failed.";806is_fully_compatible = false;807}808}809net_param->clear_layers();810return is_fully_compatible;811}812813bool NetNeedsBatchNormUpgrade(const NetParameter& net_param) {814for (int i = 0; i < net_param.layer_size(); ++i) {815// Check if BatchNorm layers declare three parameters, as required by816// the previous BatchNorm layer definition.817if (net_param.layer(i).type() == "BatchNorm"818&& net_param.layer(i).param_size() == 3) {819return true;820}821}822return false;823}824825void UpgradeNetBatchNorm(NetParameter* net_param) {826for (int i = 0; i < net_param->layer_size(); ++i) {827// Check if BatchNorm layers declare three parameters, as required by828// the previous BatchNorm layer definition.829if (net_param->layer(i).type() == "BatchNorm"830&& net_param->layer(i).param_size() == 3) {831net_param->mutable_layer(i)->clear_param();832}833}834}835836bool UpgradeV1LayerParameter(V1LayerParameter* v1_layer_param_,837LayerParameter* layer_param) {838CV_Assert(v1_layer_param_ != NULL);839const V1LayerParameter& v1_layer_param = *v1_layer_param_;840layer_param->Clear();841bool is_fully_compatible = true;842for (int i = 0; i < v1_layer_param.bottom_size(); ++i) {843layer_param->add_bottom(v1_layer_param.bottom(i));844}845for (int i = 0; i < v1_layer_param.top_size(); ++i) {846layer_param->add_top(v1_layer_param.top(i));847}848if (v1_layer_param.has_name()) {849layer_param->set_name(v1_layer_param.name());850}851for (int i = 0; i < v1_layer_param.include_size(); ++i) {852layer_param->add_include()->CopyFrom(v1_layer_param.include(i));853}854for (int i = 0; i < v1_layer_param.exclude_size(); ++i) {855layer_param->add_exclude()->CopyFrom(v1_layer_param.exclude(i));856}857if (v1_layer_param.has_type()) {858layer_param->set_type(UpgradeV1LayerType(v1_layer_param.type()));859}860layer_param->mutable_blobs()->Swap(v1_layer_param_->mutable_blobs());861for (int i = 0; i < v1_layer_param.param_size(); ++i) {862while (layer_param->param_size() <= i) { layer_param->add_param(); }863layer_param->mutable_param(i)->set_name(v1_layer_param.param(i));864}865ParamSpec_DimCheckMode mode;866for (int i = 0; i < v1_layer_param.blob_share_mode_size(); ++i) {867while (layer_param->param_size() <= i) { layer_param->add_param(); }868switch (v1_layer_param.blob_share_mode(i)) {869case V1LayerParameter_DimCheckMode_STRICT:870mode = ParamSpec_DimCheckMode_STRICT;871break;872case V1LayerParameter_DimCheckMode_PERMISSIVE:873mode = ParamSpec_DimCheckMode_PERMISSIVE;874break;875default:876LOG(FATAL) << "Unknown blob_share_mode: "877<< v1_layer_param.blob_share_mode(i);878break;879}880layer_param->mutable_param(i)->set_share_mode(mode);881}882for (int i = 0; i < v1_layer_param.blobs_lr_size(); ++i) {883while (layer_param->param_size() <= i) { layer_param->add_param(); }884layer_param->mutable_param(i)->set_lr_mult(v1_layer_param.blobs_lr(i));885}886for (int i = 0; i < v1_layer_param.weight_decay_size(); ++i) {887while (layer_param->param_size() <= i) { layer_param->add_param(); }888layer_param->mutable_param(i)->set_decay_mult(889v1_layer_param.weight_decay(i));890}891for (int i = 0; i < v1_layer_param.loss_weight_size(); ++i) {892layer_param->add_loss_weight(v1_layer_param.loss_weight(i));893}894if (v1_layer_param.has_accuracy_param()) {895layer_param->mutable_accuracy_param()->CopyFrom(896v1_layer_param.accuracy_param());897}898if (v1_layer_param.has_argmax_param()) {899layer_param->mutable_argmax_param()->CopyFrom(900v1_layer_param.argmax_param());901}902if (v1_layer_param.has_concat_param()) {903layer_param->mutable_concat_param()->CopyFrom(904v1_layer_param.concat_param());905}906if (v1_layer_param.has_contrastive_loss_param()) {907layer_param->mutable_contrastive_loss_param()->CopyFrom(908v1_layer_param.contrastive_loss_param());909}910if (v1_layer_param.has_convolution_param()) {911layer_param->mutable_convolution_param()->CopyFrom(912v1_layer_param.convolution_param());913}914if (v1_layer_param.has_data_param()) {915layer_param->mutable_data_param()->CopyFrom(916v1_layer_param.data_param());917}918if (v1_layer_param.has_dropout_param()) {919layer_param->mutable_dropout_param()->CopyFrom(920v1_layer_param.dropout_param());921}922if (v1_layer_param.has_dummy_data_param()) {923layer_param->mutable_dummy_data_param()->CopyFrom(924v1_layer_param.dummy_data_param());925}926if (v1_layer_param.has_eltwise_param()) {927layer_param->mutable_eltwise_param()->CopyFrom(928v1_layer_param.eltwise_param());929}930if (v1_layer_param.has_exp_param()) {931layer_param->mutable_exp_param()->CopyFrom(932v1_layer_param.exp_param());933}934if (v1_layer_param.has_hdf5_data_param()) {935layer_param->mutable_hdf5_data_param()->CopyFrom(936v1_layer_param.hdf5_data_param());937}938if (v1_layer_param.has_hdf5_output_param()) {939layer_param->mutable_hdf5_output_param()->CopyFrom(940v1_layer_param.hdf5_output_param());941}942if (v1_layer_param.has_hinge_loss_param()) {943layer_param->mutable_hinge_loss_param()->CopyFrom(944v1_layer_param.hinge_loss_param());945}946if (v1_layer_param.has_image_data_param()) {947layer_param->mutable_image_data_param()->CopyFrom(948v1_layer_param.image_data_param());949}950if (v1_layer_param.has_infogain_loss_param()) {951layer_param->mutable_infogain_loss_param()->CopyFrom(952v1_layer_param.infogain_loss_param());953}954if (v1_layer_param.has_inner_product_param()) {955layer_param->mutable_inner_product_param()->CopyFrom(956v1_layer_param.inner_product_param());957}958if (v1_layer_param.has_lrn_param()) {959layer_param->mutable_lrn_param()->CopyFrom(960v1_layer_param.lrn_param());961}962if (v1_layer_param.has_memory_data_param()) {963layer_param->mutable_memory_data_param()->CopyFrom(964v1_layer_param.memory_data_param());965}966if (v1_layer_param.has_mvn_param()) {967layer_param->mutable_mvn_param()->CopyFrom(968v1_layer_param.mvn_param());969}970if (v1_layer_param.has_pooling_param()) {971layer_param->mutable_pooling_param()->CopyFrom(972v1_layer_param.pooling_param());973}974if (v1_layer_param.has_power_param()) {975layer_param->mutable_power_param()->CopyFrom(976v1_layer_param.power_param());977}978if (v1_layer_param.has_relu_param()) {979layer_param->mutable_relu_param()->CopyFrom(980v1_layer_param.relu_param());981}982if (v1_layer_param.has_sigmoid_param()) {983layer_param->mutable_sigmoid_param()->CopyFrom(984v1_layer_param.sigmoid_param());985}986if (v1_layer_param.has_softmax_param()) {987layer_param->mutable_softmax_param()->CopyFrom(988v1_layer_param.softmax_param());989}990if (v1_layer_param.has_slice_param()) {991layer_param->mutable_slice_param()->CopyFrom(992v1_layer_param.slice_param());993}994if (v1_layer_param.has_tanh_param()) {995layer_param->mutable_tanh_param()->CopyFrom(996v1_layer_param.tanh_param());997}998if (v1_layer_param.has_threshold_param()) {999layer_param->mutable_threshold_param()->CopyFrom(1000v1_layer_param.threshold_param());1001}1002if (v1_layer_param.has_window_data_param()) {1003layer_param->mutable_window_data_param()->CopyFrom(1004v1_layer_param.window_data_param());1005}1006if (v1_layer_param.has_transform_param()) {1007layer_param->mutable_transform_param()->CopyFrom(1008v1_layer_param.transform_param());1009}1010if (v1_layer_param.has_loss_param()) {1011layer_param->mutable_loss_param()->CopyFrom(1012v1_layer_param.loss_param());1013}1014if (v1_layer_param.has_layer()) {1015LOG(ERROR) << "Input NetParameter has V0 layer -- ignoring.";1016is_fully_compatible = false;1017}1018return is_fully_compatible;1019}10201021const char* UpgradeV1LayerType(const V1LayerParameter_LayerType type) {1022switch (type) {1023case V1LayerParameter_LayerType_NONE:1024return "";1025case V1LayerParameter_LayerType_ABSVAL:1026return "AbsVal";1027case V1LayerParameter_LayerType_ACCURACY:1028return "Accuracy";1029case V1LayerParameter_LayerType_ARGMAX:1030return "ArgMax";1031case V1LayerParameter_LayerType_BNLL:1032return "BNLL";1033case V1LayerParameter_LayerType_CONCAT:1034return "Concat";1035case V1LayerParameter_LayerType_CONTRASTIVE_LOSS:1036return "ContrastiveLoss";1037case V1LayerParameter_LayerType_CONVOLUTION:1038return "Convolution";1039case V1LayerParameter_LayerType_DECONVOLUTION:1040return "Deconvolution";1041case V1LayerParameter_LayerType_DATA:1042return "Data";1043case V1LayerParameter_LayerType_DROPOUT:1044return "Dropout";1045case V1LayerParameter_LayerType_DUMMY_DATA:1046return "DummyData";1047case V1LayerParameter_LayerType_EUCLIDEAN_LOSS:1048return "EuclideanLoss";1049case V1LayerParameter_LayerType_ELTWISE:1050return "Eltwise";1051case V1LayerParameter_LayerType_EXP:1052return "Exp";1053case V1LayerParameter_LayerType_FLATTEN:1054return "Flatten";1055case V1LayerParameter_LayerType_HDF5_DATA:1056return "HDF5Data";1057case V1LayerParameter_LayerType_HDF5_OUTPUT:1058return "HDF5Output";1059case V1LayerParameter_LayerType_HINGE_LOSS:1060return "HingeLoss";1061case V1LayerParameter_LayerType_IM2COL:1062return "Im2col";1063case V1LayerParameter_LayerType_IMAGE_DATA:1064return "ImageData";1065case V1LayerParameter_LayerType_INFOGAIN_LOSS:1066return "InfogainLoss";1067case V1LayerParameter_LayerType_INNER_PRODUCT:1068return "InnerProduct";1069case V1LayerParameter_LayerType_LRN:1070return "LRN";1071case V1LayerParameter_LayerType_MEMORY_DATA:1072return "MemoryData";1073case V1LayerParameter_LayerType_MULTINOMIAL_LOGISTIC_LOSS:1074return "MultinomialLogisticLoss";1075case V1LayerParameter_LayerType_MVN:1076return "MVN";1077case V1LayerParameter_LayerType_POOLING:1078return "Pooling";1079case V1LayerParameter_LayerType_POWER:1080return "Power";1081case V1LayerParameter_LayerType_RELU:1082return "ReLU";1083case V1LayerParameter_LayerType_SIGMOID:1084return "Sigmoid";1085case V1LayerParameter_LayerType_SIGMOID_CROSS_ENTROPY_LOSS:1086return "SigmoidCrossEntropyLoss";1087case V1LayerParameter_LayerType_SILENCE:1088return "Silence";1089case V1LayerParameter_LayerType_SOFTMAX:1090return "Softmax";1091case V1LayerParameter_LayerType_SOFTMAX_LOSS:1092return "SoftmaxWithLoss";1093case V1LayerParameter_LayerType_SPLIT:1094return "Split";1095case V1LayerParameter_LayerType_SLICE:1096return "Slice";1097case V1LayerParameter_LayerType_TANH:1098return "TanH";1099case V1LayerParameter_LayerType_WINDOW_DATA:1100return "WindowData";1101case V1LayerParameter_LayerType_THRESHOLD:1102return "Threshold";1103default:1104LOG(FATAL) << "Unknown V1LayerParameter layer type: " << type;1105return "";1106}1107}11081109const int kProtoReadBytesLimit = INT_MAX; // Max size of 2 GB minus 1 byte.11101111bool ReadProtoFromBinary(ZeroCopyInputStream* input, Message *proto) {1112CodedInputStream coded_input(input);1113coded_input.SetTotalBytesLimit(kProtoReadBytesLimit, 536870912);11141115return proto->ParseFromCodedStream(&coded_input);1116}11171118bool ReadProtoFromTextFile(const char* filename, Message* proto) {1119std::ifstream fs(filename, std::ifstream::in);1120CHECK(fs.is_open()) << "Can't open \"" << filename << "\"";1121IstreamInputStream input(&fs);1122#ifndef OPENCV_DNN_EXTERNAL_PROTOBUF1123return google::protobuf::TextFormat::Parser(true).Parse(&input, proto);1124#else1125return google::protobuf::TextFormat::Parser().Parse(&input, proto);1126#endif1127}11281129bool ReadProtoFromBinaryFile(const char* filename, Message* proto) {1130std::ifstream fs(filename, std::ifstream::in | std::ifstream::binary);1131CHECK(fs.is_open()) << "Can't open \"" << filename << "\"";1132IstreamInputStream raw_input(&fs);11331134return ReadProtoFromBinary(&raw_input, proto);1135}11361137bool ReadProtoFromTextBuffer(const char* data, size_t len, Message* proto) {1138ArrayInputStream input(data, len);1139return google::protobuf::TextFormat::Parse(&input, proto);1140}114111421143bool ReadProtoFromBinaryBuffer(const char* data, size_t len, Message* proto) {1144ArrayInputStream raw_input(data, len);1145return ReadProtoFromBinary(&raw_input, proto);1146}11471148void ReadNetParamsFromTextFileOrDie(const char* param_file,1149NetParameter* param) {1150CHECK(ReadProtoFromTextFile(param_file, param))1151<< "Failed to parse NetParameter file: " << param_file;1152UpgradeNetAsNeeded(param_file, param);1153}11541155void ReadNetParamsFromTextBufferOrDie(const char* data, size_t len,1156NetParameter* param) {1157CHECK(ReadProtoFromTextBuffer(data, len, param))1158<< "Failed to parse NetParameter buffer";1159UpgradeNetAsNeeded("memory buffer", param);1160}11611162void ReadNetParamsFromBinaryFileOrDie(const char* param_file,1163NetParameter* param) {1164CHECK(ReadProtoFromBinaryFile(param_file, param))1165<< "Failed to parse NetParameter file: " << param_file;1166UpgradeNetAsNeeded(param_file, param);1167}11681169void ReadNetParamsFromBinaryBufferOrDie(const char* data, size_t len,1170NetParameter* param) {1171CHECK(ReadProtoFromBinaryBuffer(data, len, param))1172<< "Failed to parse NetParameter buffer";1173UpgradeNetAsNeeded("memory buffer", param);1174}11751176}1177}1178#endif117911801181