2016-07-02 23 views
1

我最近試圖讓我的訓練模型之一的混淆矩陣,看看它是多麼的精確。我下載了這個腳本並且餵了我的模型。 令我驚訝的是,腳本計算的準確度與Caffe報告非常不同。Caffe的報告準確性是否可靠?

我已經使用this script計算混淆矩陣,然而,這報告的準確度爲好,問題是這個腳本報告的準確性方式不同的是,一個由Caffe報道!
例如Caffe報告CIFAR10的準確率可以說爲92.34%,而當將模型輸入到腳本以計算混淆矩陣及其準確性時,結果就是例如86.5%。

以下哪精度的一個是正確的,並且可以在論文中報告或其他文件的結果如here相比?

我也看到了一些奇怪的東西,我訓練了兩個相同的模型,只有一個區別,即一個使用了xavier,另一個使用了msra進行初始化。
第一個報告的準確性爲94.25,其他報告爲94.26。當這些模型被饋送到我上面鏈接的腳本時,用於混淆矩陣計算。他們的準確率分別爲89.2%和87.4%!
這是正常的嗎?這是什麼原因? MSRA?

我真的不知道caffe報道的精度是否真實值得信賴。如果有人能夠澄清這個問題,我會很感激。

P.N: 腳本中的精度計算公式爲(complete script):

for i, image, label in reader: 
     image_caffe = image.reshape(1, *image.shape) 
     out = net.forward_all(data=np.asarray([ image_caffe ])) 
     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: i=%s, expected %i but predicted %i" \ 
        % (i, label, plabel)) 

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

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

恕我直言,這是正常和正確的。正確預測的數量除以數據集中實例的總數。

回答

1

我找到了原因。 Caffe生成的準確性與所涉腳本生成的精度之間不匹配的原因完全是因爲均值減法,這是在caffe中完成的,而不是在腳本中完成的。 This是腳本的修改版本,它考慮到了這一點,並希望一切都很好。

# Author: Axel Angel, copyright 2015, license GPLv3. 
# added mean subtraction so that, the accuracy can be reported accurately just like caffe when doing a mean subtraction 
# Seyyed Hossein Hasan Pour 
# [email protected] 
# 7/3/2016 

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

def flat_shape(x): 
    "Returns x without singleton dimension, eg: (1,28,28) -> (28,28)" 
    return x.reshape(filter(lambda s: s > 1, x.shape)) 

def lmdb_reader(fpath): 
    import lmdb 
    lmdb_env = lmdb.open(fpath) 
    lmdb_txn = lmdb_env.begin() 
    lmdb_cursor = lmdb_txn.cursor() 

    for key, value in lmdb_cursor: 
     datum = caffe.proto.caffe_pb2.Datum() 
     datum.ParseFromString(value) 
     label = int(datum.label) 
     image = caffe.io.datum_to_array(datum).astype(np.uint8) 
     yield (key, flat_shape(image), label) 

def leveldb_reader(fpath): 
    import leveldb 
    db = leveldb.LevelDB(fpath) 

    for key, value in db.RangeIter(): 
     datum = caffe.proto.caffe_pb2.Datum() 
     datum.ParseFromString(value) 
     label = int(datum.label) 
     image = caffe.io.datum_to_array(datum).astype(np.uint8) 
     yield (key, flat_shape(image), label) 

def npz_reader(fpath): 
    npz = np.load(fpath) 

    xs = npz['arr_0'] 
    ls = npz['arr_1'] 

    for i, (x, l) in enumerate(np.array([ xs, ls ]).T): 
     yield (i, x, l) 

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('--mean', type=str, required=True) 
    group = parser.add_mutually_exclusive_group(required=True) 
    group.add_argument('--lmdb', type=str, default=None) 
    group.add_argument('--leveldb', type=str, default=None) 
    group.add_argument('--npz', type=str, default=None) 
    args = parser.parse_args() 

# Extract mean from the mean image file 
    mean_blobproto_new = caffe.proto.caffe_pb2.BlobProto() 
    f = open(args.mean, 'rb') 
    mean_blobproto_new.ParseFromString(f.read()) 
    mean_image = caffe.io.blobproto_to_array(mean_blobproto_new) 
    f.close() 

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

    # CNN reconstruction and loading the trained weights 
    net = caffe.Net(args.proto, args.model, caffe.TEST) 
    caffe.set_mode_cpu() 
    print "args", vars(args) 
    if args.lmdb != None: 
     reader = lmdb_reader(args.lmdb) 
    if args.leveldb != None: 
     reader = leveldb_reader(args.leveldb) 
    if args.npz != None: 
     reader = npz_reader(args.npz) 

    for i, image, label in reader: 
     image_caffe = image.reshape(1, *image.shape) 
     out = net.forward_all(data=np.asarray([ image_caffe ])- mean_image) 
     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: i=%s, expected %i but predicted %i" \ 
        % (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)])