-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
LODet_v1.0
- Loading branch information
Showing
119 changed files
with
15,913 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
# coding=utf-8 | ||
|
||
PROJECT_PATH = "./" | ||
DATA_PATH = "/mnt/Datasets/DIOR/" | ||
|
||
|
||
DATA = {"CLASSES":['airplane','airport','baseballfield','basketballcourt','bridge','chimney', | ||
'dam','Expressway-Service-area','Expressway-toll-station','golffield','groundtrackfield','harbor', | ||
'overpass','ship','stadium','storagetank','tenniscourt','trainstation','vehicle','windmill'], | ||
"NUM":20} | ||
''' | ||
MODEL = { | ||
"ANCHORS":[[(1.494992296, 1.772419808), (2.550184278, 5.105188103), (4.511253175, 2.041398611)], # Anchors for small obj | ||
[(3.852394468, 3.413543783), (3.827394513, 9.012606993), (7.569651633, 7.192874667)], # Anchors for medium obj | ||
[(5.269568089, 8.068825014), (10.13079538, 3.44005408), (10.41848982, 10.60006263)]], # Anchors for big obj | ||
"STRIDES":[8, 16, 32], | ||
"ANCHORS_PER_SCLAE":3 | ||
}#544 | ||
''' | ||
MODEL = { | ||
"ANCHORS":[[(3.18524223, 1.57625129), (1.95394566,4.29178376), (6.65929852, 2.8841753)], # Anchors for small obj | ||
[(1.9038, 4.42035), (6.712, 3.29255), (6.645, 12.7675)], # Anchors for medium obj | ||
[(5.513875, 14.38123), (11.66746, 4.2333), (15.70345, 11.94367)]], # Anchors for big obj | ||
"STRIDES":[8, 16, 32], | ||
"ANCHORS_PER_SCLAE":3 | ||
}#800 | ||
|
||
MAX_LABEL = 500 | ||
SHOW_HEATMAP = False | ||
SCALE_FACTOR=2.0 | ||
|
||
TRAIN = { | ||
"EVAL_TYPE":'VOC', #['VOC', 'COCO'] | ||
"TRAIN_IMG_SIZE":800, | ||
"TRAIN_IMG_NUM":11759,#11759, | ||
"AUGMENT":True, | ||
"MULTI_SCALE_TRAIN":True, | ||
"MULTI_TRAIN_RANGE":[12,25,1], | ||
"BATCH_SIZE":10, | ||
"IOU_THRESHOLD_LOSS":0.5, | ||
"EPOCHS":121, | ||
"NUMBER_WORKERS":16, | ||
"MOMENTUM":0.9, | ||
"WEIGHT_DECAY":0.0005, | ||
"LR_INIT":1.5e-4, | ||
"LR_END":1e-6, | ||
"WARMUP_EPOCHS":5, | ||
"IOU_TYPE":'CIOU' #['GIOU','CIOU'] | ||
} | ||
|
||
TEST = { | ||
"EVAL_TYPE":'VOC', #['VOC', 'COCO', 'BOTH'] | ||
"EVAL_JSON":'test.json', | ||
"EVAL_NAME":'test', | ||
"NUM_VIS_IMG":0, | ||
"TEST_IMG_SIZE":800, | ||
"BATCH_SIZE":1, | ||
"NUMBER_WORKERS":4, | ||
"CONF_THRESH":0.05, | ||
"NMS_THRESH":0.45, | ||
"NMS_METHODS":'NMS', #['NMS', 'SOFT_NMS', 'NMS_DIOU', #'NMS_DIOU_SCALE'] | ||
"MULTI_SCALE_TEST":False, | ||
"MULTI_TEST_RANGE":[320,640,96], | ||
"FLIP_TEST":False | ||
} | ||
|
||
|
||
''' | ||
DOTA_cfg | ||
DATA = {"CLASSES": ['plane', | ||
'baseball-diamond', | ||
'bridge', | ||
'ground-track-field', | ||
'small-vehicle', | ||
'large-vehicle', | ||
'ship', | ||
'tennis-court', | ||
'basketball-court', | ||
'storage-tank', 'soccer-ball-field', 'roundabout', 'harbor', 'swimming-pool', 'helicopter'], | ||
"NUM": 15} | ||
MODEL = {"ANCHORS":[[(1.625, 2.656), ( 3.652, 3.981), (4.493, 1.797)], | ||
[(4.358,3.123), (2.000, 4.558), (6.077, 6.688)], | ||
[(2.443, 7.848), (6.237, 4.750), (9.784, 10.291)]] ,# Anchors for big obj 608 | ||
"STRIDES":[8, 16, 32], | ||
"ANCHORS_PER_SCLAE":3 | ||
}#544 | ||
MODEL = {"ANCHORS":[[(2.80340246, 2.87380792), (4.23121697, 6.44043634), (7.38428433, 3.82613533)], | ||
[(4.2460819, 4.349495965), (4.42917327, 10.59395029), (8.24772929, 6.224761455)], | ||
[(6.02687863, 5.92446062), (7.178407523, 10.86361071), (15.30253702, 12.62863728)]] ,# Anchors for big obj 608 | ||
"STRIDES":[8, 16, 32], | ||
"ANCHORS_PER_SCLAE":3 | ||
}#800 | ||
''' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
import json | ||
import tempfile | ||
import matplotlib.pyplot as plt | ||
from torch.autograd import Variable | ||
from torch.utils.data import DataLoader | ||
from pycocotools.cocoeval import COCOeval | ||
import time | ||
from tqdm import tqdm | ||
from dataload.cocodataset import * | ||
from eval.evaluator import Evaluator | ||
from utils.utils_coco import * | ||
from utils.visualize import * | ||
|
||
current_milli_time = lambda: int(round(time.time() * 1000)) | ||
|
||
class COCOEvaluator(): | ||
""" | ||
COCO AP Evaluation class. | ||
All the data in the val2017 dataset are processed \ | ||
and evaluated by COCO API. | ||
""" | ||
def __init__(self, data_dir, img_size, confthre, nmsthre): | ||
""" | ||
Args: | ||
model_type (str): model name specified in config file | ||
data_dir (str): dataset root directory | ||
img_size (int): image size after preprocess. images are resized \ | ||
to squares whose shape is (img_size, img_size). | ||
confthre (float): | ||
confidence threshold ranging from 0 to 1, \ | ||
which is defined in the config file. | ||
nmsthre (float): | ||
IoU threshold of non-max supression ranging from 0 to 1. | ||
""" | ||
self.classes = cfg.DATA["CLASSES"] | ||
self.val_data_path = cfg.DATA_PATH | ||
self.pred_result_path = os.path.join(cfg.PROJECT_PATH, 'prediction') | ||
self.__visual_imgs = cfg.TEST["NUM_VIS_IMG"] | ||
|
||
augmentation = {'LRFLIP': False, 'JITTER': 0, 'RANDOM_PLACING': False, | ||
'HUE': 0, 'SATURATION': 0, 'EXPOSURE': 0, 'RANDOM_DISTORT': False} | ||
|
||
self.dataset = COCODataset(data_dir=data_dir, | ||
img_size=img_size, | ||
augmentation=augmentation, | ||
json_file=cfg.TEST["EVAL_JSON"], | ||
name=cfg.TEST["EVAL_NAME"]) | ||
self.dataloader = DataLoader(self.dataset, batch_size=cfg.TEST["BATCH_SIZE"], shuffle=False, | ||
pin_memory=True, num_workers=cfg.TEST["NUMBER_WORKERS"]) | ||
self.img_size = img_size | ||
self.confthre = confthre | ||
self.nmsthre = nmsthre | ||
self.inference_time = 0. | ||
def evaluate(self, model): | ||
""" | ||
COCO average precision (AP) Evaluation. Iterate inference on the test dataset | ||
and the results are evaluated by COCO API. | ||
Args: | ||
model : model object | ||
Returns: | ||
ap50_95 (float) : calculated COCO AP for IoU=50:95 | ||
ap50 (float) : calculated COCO AP for IoU=50 | ||
""" | ||
model.eval() | ||
cuda = torch.cuda.is_available() | ||
Tensor = torch.cuda.FloatTensor if cuda else torch.FloatTensor | ||
ids = [] | ||
data_dict = [] | ||
dataiterator = iter(self.dataloader) | ||
#print(" Val datasets number is : {}".format(len(self.dataloader))) | ||
for i in tqdm(range(len(self.dataloader))): | ||
#while True: | ||
#try: | ||
img, _, info_img, id_, img_path = next(dataiterator) # load a batch | ||
#except StopIteration: | ||
#break | ||
info_img = [float(info.numpy()) for info in info_img] | ||
id_ = int(id_) | ||
ids.append(id_) | ||
with torch.no_grad(): | ||
img = Variable(img.type(Tensor)) | ||
start_time = current_milli_time() | ||
_,outputs = model(img) | ||
self.inference_time += (current_milli_time() - start_time) | ||
outputs=outputs.unsqueeze(0) | ||
outputs = postprocess( | ||
outputs, cfg.DATA["NUM"], self.confthre, self.nmsthre) | ||
if outputs[0] is None: | ||
continue | ||
outputs = outputs[0].cpu().data | ||
|
||
for output in outputs: | ||
x1 = float(output[0]) | ||
y1 = float(output[1]) | ||
x2 = float(output[2]) | ||
y2 = float(output[3]) | ||
label = self.dataset.class_ids[int(output[6])] | ||
box = box2label((y1, x1, y2, x2), info_img) | ||
bbox = [box[1], box[0], box[3] - box[1], box[2] - box[0]] | ||
score = float(output[4].data.item() * output[5].data.item()) # object score * class score | ||
A = {"image_id": id_, "category_id": label, "bbox": bbox, | ||
"score": score, "segmentation": []} # COCO json format | ||
data_dict.append(A) | ||
|
||
if self.__visual_imgs and i <= self.__visual_imgs: | ||
imgshow = cv2.imread(img_path[0]) | ||
bboxes_prd = Evaluator(model).get_bbox(imgshow, cfg.TEST["MULTI_SCALE_TEST"], cfg.TEST["FLIP_TEST"]) | ||
if bboxes_prd.shape[0] != 0: | ||
boxes = bboxes_prd[..., :4] | ||
class_inds = bboxes_prd[..., 5].astype(np.int32) | ||
scores = bboxes_prd[..., 4] | ||
visualize_boxes(image=imgshow, boxes=boxes, labels=class_inds, probs=scores, class_labels=self.classes) | ||
path = os.path.join(self.pred_result_path, "imgs/{}.jpg".format(i)) | ||
cv2.imwrite(path, imgshow) | ||
|
||
|
||
annType = ['segm', 'bbox', 'keypoints'] | ||
self.inference_time = 1.0 * self.inference_time / len(self.dataloader) | ||
# Evaluate the Dt (detection) json comparing with the ground truth | ||
if len(data_dict) > 0: | ||
cocoGt = self.dataset.coco | ||
_, tmp = tempfile.mkstemp() | ||
json.dump(data_dict, open(tmp, 'w')) | ||
cocoDt = cocoGt.loadRes(tmp) | ||
cocoEval = COCOeval(self.dataset.coco, cocoDt, annType[1]) | ||
cocoEval.params.imgIds = ids | ||
cocoEval.evaluate() | ||
cocoEval.accumulate() | ||
cocoEval.summarize() | ||
|
||
''' | ||
# ----------pltshow------------- # | ||
# precision[t,:,k,a,m] PR curves recall-precision value | ||
# T:IoU thresh.5-.95, gap=0.05, t[0]=0.5,t[1]=0.55,t[2]=0.6,t[3]=0.65,t[4]=0.7,t[5]=0.75 ……,t[9]=0.95 | ||
# R:101 recall thresh,0-101 | ||
# K:class k[0] = person,k[1] = bycicle,.....COCO | ||
# A:area, a[0]=all,a[1]=small,a[2]=medium,a[3]=large | ||
# M:Maxdet m[0]=1,m[1]=10,m[2]=100 | ||
#C75: PR at IoU=.75 (AP at strict IoU), area under curve corresponds to APIoU=.75 metric. | ||
#C50: PR at IoU=.50 (AP at PASCAL IoU), area under curve corresponds to APIoU=.50 metric. | ||
#Loc: PR at IoU=.10 (localization errors ignored, but not duplicate detections). All remaining settings use IoU=.1. | ||
#Sim: PR after supercategory false positives (fps) are removed. Specifically, any matches to objects with a different class label but that belong to the same supercategory don't count as either a fp (or tp). Sim is computed by setting all objects in the same supercategory to have the same class label as the class in question and setting their ignore flag to 1. Note that person is a singleton supercategory so its Sim result is identical to Loc. | ||
#Oth: PR after all class confusions are removed. Similar to Sim, except now if a detection matches any other object it is no longer a fp (or tp). Oth is computed by setting all other objects to have the same class label as the class in question and setting their ignore flag to 1. | ||
#BG: PR after all background (and class confusion) fps are removed. For a single category, BG is a step function that is 1 until max recall is reached then drops to 0 (the curve is smoother after averaging across categories). | ||
#FN: PR after all remaining errors are removed (trivially AP=1). | ||
pr_array1 = cocoEval.eval['precision'][0, :, 0, 0, 2] | ||
pr_array2 = cocoEval.eval['precision'][5, :, 0, 0, 2] | ||
#pr_array3 = cocoEval.eval['precision'][6, :, 0, 0, 2] | ||
#pr_array4 = cocoEval.eval['precision'][9, :, 0, 0, 2] | ||
x = np.arange(0.0, 1.01, 0.01) | ||
# x_1 = np.arange(0, 1.01, 0.111) | ||
plt.xlabel('IoU') | ||
plt.ylabel('precision') | ||
plt.xlim(0, 1.0) | ||
plt.ylim(0, 1.01) | ||
plt.grid(True) | ||
plt.plot(x, pr_array1, color='blue', linewidth = '3', label='IoU=0.5') | ||
plt.plot(x, pr_array2, color='green', linewidth = '3', label='IoU=0.75') | ||
plt.title("P-R curves catid=person maxDet=100") | ||
plt.legend(loc="lower left") | ||
plt.savefig("../prediction/APs.png", dpi=600) | ||
# plt.show()''' | ||
return cocoEval.stats[0], cocoEval.stats[1], self.inference_time | ||
else: | ||
return 0, 0, 0 |
Oops, something went wrong.