使用不同的 caffe 类(98.65 vs 98.1 vs 98.20)获得不同的准确度
Getting different accuracies using different caffe classes(98.65 vs 98.1 vs 98.20)
当我使用 Caffe 的命令行界面训练然后测试我的模型时,我得到例如98.65%
而当我自己编写代码(如下所示)来计算同一预训练模型的准确性时,我得到例如 98.1%
使用 Caffe.Net
.
一切都很简单,我不知道是什么导致了这个问题。
我也尝试使用 Caffe.Classifier
及其 predict
方法,但得到了另一个较低的准确性(即 98.20%
!)
这是我写的代码片段:
import sys
import caffe
import numpy as np
import lmdb
import argparse
from collections import defaultdict
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt
import itertools
from sklearn.metrics import roc_curve, auc
import random
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--proto', help='path to the network prototxt file(deploy)', type=str, required=True)
parser.add_argument('--model', help='path to your caffemodel file', type=str, required=True)
parser.add_argument('--mean', help='path to the mean file(.binaryproto)', type=str, required=True)
#group = parser.add_mutually_exclusive_group(required=True)
parser.add_argument('--db_type', help='lmdb or leveldb', type=str, required=True)
parser.add_argument('--db_path', help='path to your lmdb/leveldb dataset', type=str, required=True)
args = parser.parse_args()
predicted_lables=[]
true_labels = []
misclassified =[]
class_names = ['unsafe','safe']
count=0
correct = 0
batch=[]
plabe_ls=[]
batch_size = 50
cropx = 224
cropy = 224
i = 0
multi_crop = False
use_caffe_classifier = True
caffe.set_mode_gpu()
# 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()
net = caffe.Classifier(args.proto, args.model,
mean = mean_image[0].mean(1).mean(1),
image_dims = (224, 224))
net1 = caffe.Net(args.proto, args.model, caffe.TEST)
net1.blobs['data'].reshape(batch_size, 3,224, 224)
data_blob_shape = net1.blobs['data'].data.shape
#check and see if its lmdb or leveldb
if(args.db_type.lower() == 'lmdb'):
lmdb_env = lmdb.open(args.db_path)
lmdb_txn = lmdb_env.begin()
lmdb_cursor = lmdb_txn.cursor()
for key, value in lmdb_cursor:
count += 1
datum = caffe.proto.caffe_pb2.Datum()
datum.ParseFromString(value)
label = int(datum.label)
image = caffe.io.datum_to_array(datum).astype(np.float32)
#key,image,label
#buffer n image
if(count % 5000 == 0):
print('{0} samples processed so far'.format(count))
if(i < batch_size):
i+=1
inf= key,image,label
batch.append(inf)
#print(key)
if(i >= batch_size):
#process n image
ims=[]
for x in range(len(batch)):
img = batch[x][1]
#img has c,w,h shape! its already gone through transpose and channel swap when it was being saved into lmdb!
#Method III : use center crop just like caffe does in test time
if (use_caffe_classifier != True):
#center crop
c,w,h = img.shape
startx = h//2 - cropx//2
starty = w//2 - cropy//2
img = img[:, startx:startx + cropx, starty:starty + cropy]
#transpose the image so we can subtract from mean
img = img.transpose(2,1,0)
img -= mean_image[0].mean(1).mean(1)
#transpose back to the original state
img = img.transpose(2,1,0)
ims.append(img)
else:
ims.append(img.transpose(2,1,0))
if (use_caffe_classifier != True):
net1.blobs['data'].data[...] = ims[:]
out_1 = net1.forward()
plabe_ls = out_1['pred']
else:
out_1 = net.predict(np.asarray(ims), oversample=multi_crop)
plabe_ls = out_1
plbl = np.asarray(plabe_ls)
plbl = plbl.argmax(axis=1)
for j in range(len(batch)):
if (plbl[j] == batch[j][2]):
correct+=1
else:
misclassified.append(batch[j][0])
predicted_lables.append(plbl[j])
true_labels.append(batch[j][2])
batch.clear()
i = 0
sys.stdout.write("\rAccuracy: %.2f%%" % (100.*correct/count))
sys.stdout.flush()
print(", %i/%i corrects" % (correct, count))
是什么导致了这种准确性差异?
更多信息:
我在 windows.
上使用 Python3.5
我从 lmdb
数据集中读取图像。
图像 256x256
和中心裁剪尺寸 224x224
.
它在 GoogleNet
.
上进行了微调
为了使 Caffe.predict
正常工作,我必须更改 classify.py
在训练中,我只使用 Caffes
默认值,例如训练时的随机裁剪和测试时的中心裁剪。
改动:
将第 35 行更改为:
self.transformer.set_transpose(in_, (2, 1, 0))
并将第 99 行改为:
predictions = predictions.reshape((len(predictions) // 10, 10, -1))
1) 首先,您需要将 classify.py
: self.transformer.set_transpose(in_, (2, 1, 0))
的第 35 行(32?)恢复为原来的状态
self.transformer.set_transpose(in_, (2, 0, 1))
。因此它期望 HWC 并在内部转换为 CHW 以进行下游处理。
2) 运行 你的分类器分支。你很可能会得到不好的结果。请检查这个。如果是这样,则意味着图像数据库不是您评论的 CWH,而是 CHW。确认后,将分类器分支更改为:ims.append(img.transpose(2,1,0))
变为 ims.append(img.transpose(1,2,0))
。重新测试您的分类器分支。结果应为 98.2%
(转到步骤 3)或 98.65%
(尝试步骤 4)。
3) 如果您在第 3 步中的结果是 98.2%
,还请撤消对 classify.py
的第二次更改。从理论上讲,由于您的图像甚至 height/width 所以 //
和 /
应该没有区别。如果确实不同或崩溃,则说明您的图像数据库存在严重问题——您对图像大小的假设不正确。你需要检查这些。它们可能相差一个像素左右,这可以解释准确性上的细微差异。
4) 如果您在步骤 3 中的结果是 98.65%
,那么您需要对代码的 Caffe.Net
分支进行更改。数据库图像是 CHW,因此您需要进行第一次转置:img = img.transpose(1,2,0)
和均值减法后的第二次转置 img = img.transpose(2,0,1)
。然后 运行 你的 Caffe.Net
分支。如果你仍然像以前一样得到 98.1%
,你应该检查你的网络是否正确执行了均值减法。
在步骤 (2) 和 (4) 中,可能会得到更差的结果,这意味着问题可能是您训练的网络的均值减法与您在 Python 代码中的期望值不同。检查这个。
关于 98.2%
的 caffe.Classifier
:
如果您查看 lines 78 - 80,中心裁剪是沿着 crop_dims
完成的,而不是 img_dims
。如果您进一步查看 caffe.Classifier
构造函数的第 42 行,就会发现 crop_dims
永远不会由用户确定。它由 Net 输入 blob 的大小决定。最后,如果您查看第 70 行,img_dims
用于在中心裁剪之前 调整图像大小 。所以你的设置发生了什么:a)图像首先 resized 到 224 x 224,然后无用地将中心裁剪到 224 x 224(我假设这是你的网络的 HxW ).你显然会得到比 98.65%
更差的结果。你需要做的是改变img_dims = (256, 256)
。这会阻止调整大小。作物将自动从您的网络中拾取,您应该得到您的 98.65%
。
当我使用 Caffe 的命令行界面训练然后测试我的模型时,我得到例如98.65%
而当我自己编写代码(如下所示)来计算同一预训练模型的准确性时,我得到例如 98.1%
使用 Caffe.Net
.
一切都很简单,我不知道是什么导致了这个问题。
我也尝试使用 Caffe.Classifier
及其 predict
方法,但得到了另一个较低的准确性(即 98.20%
!)
这是我写的代码片段:
import sys
import caffe
import numpy as np
import lmdb
import argparse
from collections import defaultdict
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt
import itertools
from sklearn.metrics import roc_curve, auc
import random
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--proto', help='path to the network prototxt file(deploy)', type=str, required=True)
parser.add_argument('--model', help='path to your caffemodel file', type=str, required=True)
parser.add_argument('--mean', help='path to the mean file(.binaryproto)', type=str, required=True)
#group = parser.add_mutually_exclusive_group(required=True)
parser.add_argument('--db_type', help='lmdb or leveldb', type=str, required=True)
parser.add_argument('--db_path', help='path to your lmdb/leveldb dataset', type=str, required=True)
args = parser.parse_args()
predicted_lables=[]
true_labels = []
misclassified =[]
class_names = ['unsafe','safe']
count=0
correct = 0
batch=[]
plabe_ls=[]
batch_size = 50
cropx = 224
cropy = 224
i = 0
multi_crop = False
use_caffe_classifier = True
caffe.set_mode_gpu()
# 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()
net = caffe.Classifier(args.proto, args.model,
mean = mean_image[0].mean(1).mean(1),
image_dims = (224, 224))
net1 = caffe.Net(args.proto, args.model, caffe.TEST)
net1.blobs['data'].reshape(batch_size, 3,224, 224)
data_blob_shape = net1.blobs['data'].data.shape
#check and see if its lmdb or leveldb
if(args.db_type.lower() == 'lmdb'):
lmdb_env = lmdb.open(args.db_path)
lmdb_txn = lmdb_env.begin()
lmdb_cursor = lmdb_txn.cursor()
for key, value in lmdb_cursor:
count += 1
datum = caffe.proto.caffe_pb2.Datum()
datum.ParseFromString(value)
label = int(datum.label)
image = caffe.io.datum_to_array(datum).astype(np.float32)
#key,image,label
#buffer n image
if(count % 5000 == 0):
print('{0} samples processed so far'.format(count))
if(i < batch_size):
i+=1
inf= key,image,label
batch.append(inf)
#print(key)
if(i >= batch_size):
#process n image
ims=[]
for x in range(len(batch)):
img = batch[x][1]
#img has c,w,h shape! its already gone through transpose and channel swap when it was being saved into lmdb!
#Method III : use center crop just like caffe does in test time
if (use_caffe_classifier != True):
#center crop
c,w,h = img.shape
startx = h//2 - cropx//2
starty = w//2 - cropy//2
img = img[:, startx:startx + cropx, starty:starty + cropy]
#transpose the image so we can subtract from mean
img = img.transpose(2,1,0)
img -= mean_image[0].mean(1).mean(1)
#transpose back to the original state
img = img.transpose(2,1,0)
ims.append(img)
else:
ims.append(img.transpose(2,1,0))
if (use_caffe_classifier != True):
net1.blobs['data'].data[...] = ims[:]
out_1 = net1.forward()
plabe_ls = out_1['pred']
else:
out_1 = net.predict(np.asarray(ims), oversample=multi_crop)
plabe_ls = out_1
plbl = np.asarray(plabe_ls)
plbl = plbl.argmax(axis=1)
for j in range(len(batch)):
if (plbl[j] == batch[j][2]):
correct+=1
else:
misclassified.append(batch[j][0])
predicted_lables.append(plbl[j])
true_labels.append(batch[j][2])
batch.clear()
i = 0
sys.stdout.write("\rAccuracy: %.2f%%" % (100.*correct/count))
sys.stdout.flush()
print(", %i/%i corrects" % (correct, count))
是什么导致了这种准确性差异?
更多信息:
我在 windows.
上使用 Python3.5
我从 lmdb
数据集中读取图像。
图像 256x256
和中心裁剪尺寸 224x224
.
它在 GoogleNet
.
上进行了微调
为了使 Caffe.predict
正常工作,我必须更改 classify.py
在训练中,我只使用 Caffes
默认值,例如训练时的随机裁剪和测试时的中心裁剪。
改动:
将第 35 行更改为:
self.transformer.set_transpose(in_, (2, 1, 0))
并将第 99 行改为:
predictions = predictions.reshape((len(predictions) // 10, 10, -1))
1) 首先,您需要将 classify.py
: self.transformer.set_transpose(in_, (2, 1, 0))
的第 35 行(32?)恢复为原来的状态
self.transformer.set_transpose(in_, (2, 0, 1))
。因此它期望 HWC 并在内部转换为 CHW 以进行下游处理。
2) 运行 你的分类器分支。你很可能会得到不好的结果。请检查这个。如果是这样,则意味着图像数据库不是您评论的 CWH,而是 CHW。确认后,将分类器分支更改为:ims.append(img.transpose(2,1,0))
变为 ims.append(img.transpose(1,2,0))
。重新测试您的分类器分支。结果应为 98.2%
(转到步骤 3)或 98.65%
(尝试步骤 4)。
3) 如果您在第 3 步中的结果是 98.2%
,还请撤消对 classify.py
的第二次更改。从理论上讲,由于您的图像甚至 height/width 所以 //
和 /
应该没有区别。如果确实不同或崩溃,则说明您的图像数据库存在严重问题——您对图像大小的假设不正确。你需要检查这些。它们可能相差一个像素左右,这可以解释准确性上的细微差异。
4) 如果您在步骤 3 中的结果是 98.65%
,那么您需要对代码的 Caffe.Net
分支进行更改。数据库图像是 CHW,因此您需要进行第一次转置:img = img.transpose(1,2,0)
和均值减法后的第二次转置 img = img.transpose(2,0,1)
。然后 运行 你的 Caffe.Net
分支。如果你仍然像以前一样得到 98.1%
,你应该检查你的网络是否正确执行了均值减法。
在步骤 (2) 和 (4) 中,可能会得到更差的结果,这意味着问题可能是您训练的网络的均值减法与您在 Python 代码中的期望值不同。检查这个。
关于 98.2%
的 caffe.Classifier
:
如果您查看 lines 78 - 80,中心裁剪是沿着 crop_dims
完成的,而不是 img_dims
。如果您进一步查看 caffe.Classifier
构造函数的第 42 行,就会发现 crop_dims
永远不会由用户确定。它由 Net 输入 blob 的大小决定。最后,如果您查看第 70 行,img_dims
用于在中心裁剪之前 调整图像大小 。所以你的设置发生了什么:a)图像首先 resized 到 224 x 224,然后无用地将中心裁剪到 224 x 224(我假设这是你的网络的 HxW ).你显然会得到比 98.65%
更差的结果。你需要做的是改变img_dims = (256, 256)
。这会阻止调整大小。作物将自动从您的网络中拾取,您应该得到您的 98.65%
。