1

以下は、事前に訓練されたモデルを訓練するために使用されるtrain.Prototxtファイルです。caffeとpycaffeによって報告された精度は異なります

name: "TempWLDNET" 
    layer { 
     name: "data" 
     type: "ImageData" 
     top: "data" 
     top: "label" 
     include { 
     phase: TRAIN 
     } 
     transform_param { 
     mirror: true 
     crop_size: 224 
     mean_file: "mean.binaryproto" 
     } 
     image_data_param { 
     source: "train.txt" 
     batch_size: 25 
     new_height: 256 
     new_width: 256 
     } 
    } 
    layer { 
     name: "data" 
     type: "ImageData" 
     top: "data" 
     top: "label" 
     include { 
     phase: TEST 
     } 
     transform_param { 
     mirror: false 
     crop_size: 224 
     mean_file: "painmean.binaryproto" 
     } 
     image_data_param { 
     source: "test.txt" 
     batch_size: 25 
     new_height: 256 
     new_width: 256 
     } 
    } 
    layer { 
     name: "conv1" 
     type: "Convolution" 
     bottom: "data" 
     top: "conv1" 
     param { 
     lr_mult: 1 
     decay_mult: 1 
     } 
     param { 
     lr_mult: 2 
     decay_mult: 0 
     } 
     convolution_param { 
     num_output: 96 
     kernel_size: 7 
     stride: 2 
     weight_filler { 
      type: "gaussian" 
      std: 0.01 
     } 
     bias_filler { 
      type: "constant" 
      value: 0 
     } 
     } 
    } 
    layer { 
     name: "relu1" 
     type: "ReLU" 
     bottom: "conv1" 
     top: "conv1" 
    } 
    layer { 
     name: "norm1" 
     type: "LRN" 
     bottom: "conv1" 
     top: "norm1" 
     lrn_param { 
     local_size: 5 
     alpha: 0.0005 
     beta: 0.75 
     } 
    } 
    layer { 
     name: "pool1" 
     type: "Pooling" 
     bottom: "norm1" 
     top: "pool1" 
     pooling_param { 
     pool: MAX 
     kernel_size: 3 
     stride: 3 
     } 
    } 
    layer { 
     name: "conv2" 
     type: "Convolution" 
     bottom: "pool1" 
     top: "conv2" 
     param { 
     lr_mult: 1 
     decay_mult: 1 
     } 
     param { 
     lr_mult: 2 
     decay_mult: 0 
     } 
     convolution_param { 
     num_output: 256 
     pad: 2 
     kernel_size: 5 
     weight_filler { 
      type: "gaussian" 
      std: 0.01 
     } 
     bias_filler { 
      type: "constant" 
      value: 1 
     } 
     } 
    } 
    layer { 
     name: "relu2" 
     type: "ReLU" 
     bottom: "conv2" 
     top: "conv2" 
    } 
    layer { 
     name: "pool2" 
     type: "Pooling" 
     bottom: "conv2" 
     top: "pool2" 
     pooling_param { 
     pool: MAX 
     kernel_size: 2 
     stride: 2 
     } 
    } 
    layer { 
     name: "conv3" 
     type: "Convolution" 
     bottom: "pool2" 
     top: "conv3" 
     param { 
     lr_mult: 1 
     decay_mult: 1 
     } 
     param { 
     lr_mult: 2 
     decay_mult: 0 
     } 
     convolution_param { 
     num_output: 512 
     pad: 1 
     kernel_size: 3 
     weight_filler { 
      type: "gaussian" 
      std: 0.01 
     } 
     bias_filler { 
      type: "constant" 
      value: 0 
     } 
     } 
    } 
    layer { 
     name: "relu3" 
     type: "ReLU" 
     bottom: "conv3" 
     top: "conv3" 
    } 
    layer { 
     name: "conv4" 
     type: "Convolution" 
     bottom: "conv3" 
     top: "conv4" 
     param { 
     lr_mult: 1 
     decay_mult: 1 
     } 
     param { 
     lr_mult: 2 
     decay_mult: 0 
     } 
     convolution_param { 
     num_output: 512 
     pad: 1 
     kernel_size: 3 
     weight_filler { 
      type: "gaussian" 
      std: 0.01 
     } 
     bias_filler { 
      type: "constant" 
      value: 1 
     } 
     } 
    } 
    layer { 
     name: "relu4" 
     type: "ReLU" 
     bottom: "conv4" 
     top: "conv4" 
    } 
    layer { 
     name: "conv5" 
     type: "Convolution" 
     bottom: "conv4" 
     top: "conv5" 
     param { 
     lr_mult: 1 
     decay_mult: 1 
     } 
     param { 
     lr_mult: 2 
     decay_mult: 0 
     } 
     convolution_param { 
     num_output: 512 
     pad: 1 
     kernel_size: 3 
     weight_filler { 
      type: "gaussian" 
      std: 0.01 
     } 
     bias_filler { 
      type: "constant" 
      value: 0 
     } 
     } 
    } 
    layer { 
     name: "relu5" 
     type: "ReLU" 
     bottom: "conv5" 
     top: "conv5" 
    } 
    layer { 
     name: "pool5" 
     type: "Pooling" 
     bottom: "conv5" 
     top: "pool5" 
     pooling_param { 
     pool: MAX 
     kernel_size: 3 
     stride: 3 
     } 
    } 
    layer { 
     name: "fc6" 
     type: "InnerProduct" 
     bottom: "pool5" 
     top: "fc6" 
     param { 
     lr_mult: 1 
     decay_mult: 1 
     } 
     param { 
     lr_mult: 2 
     decay_mult: 0 
     } 
     inner_product_param { 
     num_output: 4048 
     weight_filler { 
      type: "gaussian" 
      std: 0.005 
     } 
     bias_filler { 
      type: "constant" 
      value: 1 
     } 
     } 
    } 
    layer { 
     name: "relu6" 
     type: "ReLU" 
     bottom: "fc6" 
     top: "fc6" 
    } 
    layer { 
     name: "drop6" 
     type: "Dropout" 
     bottom: "fc6" 
     top: "fc6" 
     dropout_param { 
     dropout_ratio: 0.5 
     } 
    } 
    layer { 
     name: "fc7" 
     type: "InnerProduct" 
     bottom: "fc6" 
     top: "fc7" 
     # Note that lr_mult can be set to 0 to disable any fine-tuning of this, and any other, layer 
     param { 
     lr_mult: 1 
     decay_mult: 1 
     } 
     param { 
     lr_mult: 2 
     decay_mult: 0 
     } 
     inner_product_param { 
     num_output: 4048 
     weight_filler { 
      type: "gaussian" 
      std: 0.005 
     } 
     bias_filler { 
      type: "constant" 
      value: 1 
     } 
     } 
    } 
    layer { 
     name: "relu7" 
     type: "ReLU" 
     bottom: "fc7" 
     top: "fc7" 
    } 
    layer { 
     name: "drop7" 
     type: "Dropout" 
     bottom: "fc7" 
     top: "fc7" 
     dropout_param { 
     dropout_ratio: 0.5 
     } 
    } 
    layer { 
     name: "fc8_temp" 
     type: "InnerProduct" 
     bottom: "fc7" 
     top: "fc8_temp" 
     # lr_mult is set to higher than for other layers, because this layer is starting from random while the others are already trained 
     param { 
     lr_mult: 10 
     decay_mult: 1 
     } 
     param { 
     lr_mult: 20 
     decay_mult: 0 
     } 
     inner_product_param { 
     num_output: 16 
     weight_filler { 
      type: "gaussian" 
      std: 0.01 
     } 
     bias_filler { 
      type: "constant" 
      value: 0 
     } 
     } 
    } 
    layer { 
     name: "accuracy" 
     type: "Accuracy" 
     bottom: "fc8_temp" 
     bottom: "label" 
     top: "accuracy" 
     include { 
     phase: TEST 
     } 
    } 
    layer { 
     name: "loss" 
     type: "SoftmaxWithLoss" 
     bottom: "fc8_temp" 
     bottom: "label" 
     top: "loss" 
    } 

上記のprototxtファイルを使用すると、トレーニング終了時のテストセットで報告された精度は92%です。詳細については、How to evaluate the accuracy and loss of a trained model is good or not in caffe?

を参照してください。私はモデルのスナップショットを13000回の反復で使用し、以下のPythonスクリプトを使用して、混同行列を作成しようとしました。報告される精度は74%です。

#!/usr/bin/python 
    # -*- coding: utf-8 -*- 

    import sys 
    import caffe 
    import numpy as np 
    import argparse 
    from collections import defaultdict 

    TRAIN_DATA_ROOT='/Images/test/' 

    if __name__ == "__main__": 
      parser = argparse.ArgumentParser() 
      parser.add_argument('--proto', type=str, required=True) 
      parser.add_argument('--model', type=str, required=True) 
      parser.add_argument('--meanfile', type=str, required=True) 
      parser.add_argument('--labelfile', type=str, required=True) 
      args = parser.parse_args() 

      proto_data = open(args.meanfile, 'rb').read() 
      a = caffe.io.caffe_pb2.BlobProto.FromString(proto_data) 
      mean = caffe.io.blobproto_to_array(a)[0] 


      caffe.set_mode_gpu() 

      count = 0 
      correct = 0 
      matrix = defaultdict(int) # (real,pred) -> int 
      labels_set = set() 

      net = caffe.Net(args.proto, args.model, caffe.TEST) 
      # load input and configure preprocessing  
      transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape}) 
      transformer.set_mean('data', mean) 
      transformer.set_transpose('data', (2,0,1)) 
      transformer.set_channel_swap('data', (2,1,0)) 
      transformer.set_raw_scale('data', 1) 


      #note we can change the batch size on-the-fly 
      #since we classify only one image, we change batch size from 10 to 1 
      net.blobs['data'].reshape(1,3,224,224) 

      #load the image in the data layer 
      f = open(args.labelfile, "r") 
      for line in f.readlines(): 
        parts = line.split() 
        example_image = parts[0] 
        label = int(parts[1]) 
        im = caffe.io.load_image(TRAIN_DATA_ROOT + example_image) 
        print(im.shape) 
        net.blobs['data'].data[...] = transformer.preprocess('data', im) 
        out = net.forward() 
        plabel = int(out['prob'][0].argmax(axis=0)) 
        count += 1 
        iscorrect = label == plabel 
        correct += (1 if iscorrect else 0) 
        matrix[(label, plabel)] += 1 
        labels_set.update([label, plabel]) 
        if not iscorrect: 
          print("\rError: expected %i but predicted %i" \ 
             % (label, plabel)) 

        sys.stdout.write("\rAccuracy: %.1f%%" % (100.*correct/count)) 
        sys.stdout.flush() 

      print(", %i/%i corrects" % (correct, count)) 

      print ("") 
      print ("Confusion matrix:") 
      print ("(r , p) | count") 
      for l in labels_set: 
        for pl in labels_set: 
          print ("(%i , %i) | %i" % (l, pl, matrix[(l,pl)])) 

私はdeploy.protxtを使用しています

name: "CaffeNet" 
    input: "data" 
    input_shape { 
     dim: 1 
     dim: 3 
     dim: 224 
     dim: 224 
    } 
    layers { 
     name: "conv1" 
     type: CONVOLUTION 
     bottom: "data" 
     top: "conv1" 

     blobs_lr: 1 
     weight_decay: 1 

     blobs_lr: 2 
     weight_decay: 0 


     convolution_param { 
     num_output: 96 
     kernel_size: 7 
     stride: 2 
     weight_filler { 
      type: "gaussian" 
      std: 0.01 
     } 
     bias_filler { 
      type: "constant" 
      value: 0 
     } 
     } 
    } 
    layers { 
     name: "relu1" 
     type: RELU 
     bottom: "conv1" 
     top: "conv1" 
    } 
    layers { 
     name: "norm1" 
     type: LRN 
     bottom: "conv1" 
     top: "norm1" 
     lrn_param { 
     local_size: 5 
     alpha: 0.0005 
     beta: 0.75 
     } 
    } 
    layers { 
     name: "pool1" 
     type: POOLING 
     bottom: "norm1" 
     top: "pool1" 
     pooling_param { 
     pool: MAX 
     kernel_size: 3 
     stride: 3 
     } 
    } 
    layers { 
     name: "conv2" 
     type: CONVOLUTION 
     bottom: "pool1" 
     top: "conv2" 

     blobs_lr: 1 
     weight_decay: 1 


     blobs_lr: 2 
     weight_decay: 0 

     convolution_param { 
     num_output: 256 
     pad: 2 
     kernel_size: 5 
     weight_filler { 
      type: "gaussian" 
      std: 0.01 
     } 
     bias_filler { 
      type: "constant" 
      value: 1 
     } 
     } 
    } 
    layers { 
     name: "relu2" 
     type: RELU 
     bottom: "conv2" 
     top: "conv2" 
    } 
    layers { 
     name: "pool2" 
     type: POOLING 
     bottom: "conv2" 
     top: "pool2" 
     pooling_param { 
     pool: MAX 
     kernel_size: 2 
     stride: 2 
     } 
    } 
    layers { 
     name: "conv3" 
     type: CONVOLUTION 
     bottom: "pool2" 
     top: "conv3" 

     blobs_lr: 1 
     weight_decay: 1 

     blobs_lr: 2 
     weight_decay: 0 

     convolution_param { 
     num_output: 512 
     pad: 1 
     kernel_size: 3 
     weight_filler { 
      type: "gaussian" 
      std: 0.01 
     } 
     bias_filler { 
      type: "constant" 
      value: 0 
     } 
     } 
    } 
    layers { 
     name: "relu3" 
     type: RELU 
     bottom: "conv3" 
     top: "conv3" 
    } 
    layers { 
     name: "conv4" 
     type: CONVOLUTION 
     bottom: "conv3" 
     top: "conv4" 

     blobs_lr: 1 
     weight_decay: 1 


     blobs_lr: 2 
     weight_decay: 0 

     convolution_param { 
     num_output: 512 
     pad: 1 
     kernel_size: 3 
     weight_filler { 
      type: "gaussian" 
      std: 0.01 
     } 
     bias_filler { 
      type: "constant" 
      value: 1 
     } 
     } 
    } 
    layers { 
     name: "relu4" 
     type: RELU 
     bottom: "conv4" 
     top: "conv4" 
    } 
    layers { 
     name: "conv5" 
     type: CONVOLUTION 
     bottom: "conv4" 
     top: "conv5" 

     blobs_lr: 1 
     weight_decay: 1 


     blobs_lr: 2 
     weight_decay: 0 

     convolution_param { 
     num_output: 512 
     pad: 1 
     kernel_size: 3 
     weight_filler { 
      type: "gaussian" 
      std: 0.01 
     } 
     bias_filler { 
      type: "constant" 
      value: 0 
     } 
     } 
    } 
    layers { 
     name: "relu5" 
     type: RELU 
     bottom: "conv5" 
     top: "conv5" 
    } 
    layers { 
     name: "pool5" 
     type: POOLING 
     bottom: "conv5" 
     top: "pool5" 
     pooling_param { 
     pool: MAX 
     kernel_size: 3 
     stride: 3 
     } 
    } 
    layers { 
     name: "fc6" 
     type: INNER_PRODUCT 
     bottom: "pool5" 
     top: "fc6" 

     blobs_lr: 1 
     weight_decay: 1 

     blobs_lr: 2 
     weight_decay: 0 

     inner_product_param { 
     num_output: 4048 
     weight_filler { 
      type: "gaussian" 
      std: 0.005 
     } 
     bias_filler { 
      type: "constant" 
      value: 1 
     } 
     } 
    } 
    layers { 
     name: "relu6" 
     type: RELU 
     bottom: "fc6" 
     top: "fc6" 
    } 
    layers { 
     name: "drop6" 
     type: DROPOUT 
     bottom: "fc6" 
     top: "fc6" 
     dropout_param { 
     dropout_ratio: 0.5 
     } 
    } 
    layers { 
     name: "fc7" 
     type: INNER_PRODUCT 
     bottom: "fc6" 
     top: "fc7" 
     # Note that blobs_lr can be set to 0 to disable any fine-tuning of this, and any other, layers 

     blobs_lr: 1 
     weight_decay: 1 

     blobs_lr: 2 
     weight_decay: 0 

     inner_product_param { 
     num_output: 4048 
     weight_filler { 
      type: "gaussian" 
      std: 0.005 
     } 
     bias_filler { 
      type: "constant" 
      value: 1 
     } 
     } 
    } 
    layers { 
     name: "relu7" 
     type: RELU 
     bottom: "fc7" 
     top: "fc7" 
    } 
    layers { 
     name: "drop7" 
     type: DROPOUT 
     bottom: "fc7" 
     top: "fc7" 
     dropout_param { 
     dropout_ratio: 0.5 
     } 
    } 
    layers { 
     name: "fc8_temp" 
     type: INNER_PRODUCT 
     bottom: "fc7" 
     top: "fc8_temp" 
     # blobs_lr is set to higher than for other layers, because this layers is starting from random while the others are already trained 
     blobs_lr: 10 
     weight_decay: 1 

     blobs_lr: 20 
     weight_decay: 0 

     inner_product_param { 
     num_output: 16 
     weight_filler { 
      type: "gaussian" 
      std: 0.01 
     } 
     bias_filler { 
      type: "constant" 
      value: 0 
     } 
     } 
    } 
    layers { 
     name: "prob" 
     type: SOFTMAX 
     bottom: "fc8_temp" 
     top: "prob" 
    } 

スクリプトを実行するために使用するコマンドは、私が使用しているときの精度に差があるのはなぜ私の疑問がある

python confusion.py --proto deploy.prototxt --model models/model_iter_13000.caffemodel --meanfile mean.binaryproto --labelfile NamesTest.txt 

です同じモデルと同じテストセット。何か間違っているのですか?前もって感謝します。

答えて

1

ご確認ステップ(TEST相)とあなたが実行しているPythonコードの間に違いがあります。

  1. あなたは異なるを使用している電車やテスト用のファイルを意味する(!):phase: TRAINのためのあなたはmean_file: "mean.binaryproto"を使用し、phase: TESTの場合はmean_file: "painmean.binaryproto"を使用しています。あなたのPythonの評価コードは検証ではなく、トレーニングの平均ファイルを使用します。
    列車/検証用に異なる設定を行うことをお勧めします。

  2. 入力画像にnew_height: 256copr_size: 224があります。この設定は、コーヒーがの尺度のそれを256x256に、次にの穀物の中心からサイズ224x224に読み取ることを意味します。あなたのpythonコードはscaleクロッピングなしで224x224への入力にしか見えません。異なる入力でネットにフィードします。

  3. トレーニングプロトタイプとdeploy prototxtの相違点がないことを確認してください。

+0

お返事ありがとうございます。 mean.binaryprotoとpainmean.binaryprotoは同じファイルです。それを256x256にスケーリングした後にそれを切り取る方法を知ることができますか? – Venky

+0

@Venky classifier.pyの例 – Shai

+0

@ Shai、最近私はcaffeを学び始めました。 input_shape {dim:1 dim:3dim:224dim:224}とは何を意味するのでしょうか? 256x256への入力をどのようにスケーリングし、それを224x224に切り捨てるのか教えてください。私はコードの変更を意味します。以下のコードが実際にはnet.blobs ['data']。data [...]と混同しています。 ] = transformer.preprocess( 'data'、im)およびnet.blobs ['data']。reshape(1,3,224,224) – Venky

関連する問題