diff --git a/configs/gaitbase/gaitbase_da_casiab.yaml b/configs/gaitbase/gaitbase_da_casiab.yaml new file mode 100644 index 0000000..559d4f6 --- /dev/null +++ b/configs/gaitbase/gaitbase_da_casiab.yaml @@ -0,0 +1,108 @@ +data_cfg: + dataset_name: CASIA-B + dataset_root: your_path + dataset_partition: ./datasets/CASIA-B/CASIA-B.json + num_workers: 1 + remove_no_gallery: false # Remove probe if no gallery for it + test_dataset_name: CASIA-B + +evaluator_cfg: + enable_float16: true + restore_ckpt_strict: true + restore_hint: 0 + save_name: GaitBase_DA + #eval_func: GREW_submission + sampler: + batch_shuffle: false + batch_size: 16 + sample_type: all_ordered # all indicates whole sequence used to test, while ordered means input sequence by its natural order; Other options: fixed_unordered + frames_all_limit: 720 # limit the number of sampled frames to prevent out of memory + metric: euc # cos + transform: + - type: BaseSilCuttingTransform + +loss_cfg: + - loss_term_weight: 1.0 + margin: 0.2 + type: TripletLoss + log_prefix: triplet + - loss_term_weight: 1.0 + scale: 16 + type: CrossEntropyLoss + log_prefix: softmax + log_accuracy: true + +model_cfg: + model: Baseline + backbone_cfg: + type: ResNet9 + block: BasicBlock + channels: # Layers configuration for automatically model construction + - 64 + - 128 + - 256 + - 512 + layers: + - 1 + - 1 + - 1 + - 1 + strides: + - 1 + - 2 + - 2 + - 1 + maxpool: false + SeparateFCs: + in_channels: 512 + out_channels: 256 + parts_num: 16 + SeparateBNNecks: + class_num: 74 + in_channels: 256 + parts_num: 16 + bin_num: + - 16 + +optimizer_cfg: + lr: 0.1 + momentum: 0.9 + solver: SGD + weight_decay: 0.0005 + +scheduler_cfg: + gamma: 0.1 + milestones: # Learning Rate Reduction at each milestones + - 20000 + - 40000 + - 50000 + scheduler: MultiStepLR +trainer_cfg: + enable_float16: true # half_percesion float for memory reduction and speedup + fix_BN: false + with_test: false + log_iter: 100 + restore_ckpt_strict: true + restore_hint: 0 + save_iter: 60000 + save_name: GaitBase_DA + sync_BN: true + total_iter: 60000 + sampler: + batch_shuffle: true + batch_size: + - 8 # TripletSampler, batch_size[0] indicates Number of Identity + - 16 # batch_size[1] indicates Samples sequqnce for each Identity + frames_num_fixed: 30 # fixed frames number for training + frames_num_max: 40 # max frames number for unfixed training + frames_num_min: 20 # min frames number for unfixed traing + sample_type: fixed_unordered # fixed control input frames number, unordered for controlling order of input tensor; Other options: unfixed_ordered or all_ordered + type: TripletSampler + transform: + - type: Compose + trf_cfg: + - type: BaseSilCuttingTransform + - type: RandomRotate + prob: 0.3 + - type: RandomErasing + prob: 0.3 diff --git a/configs/gaitbase/gaitbase_da_gait3d.yaml b/configs/gaitbase/gaitbase_da_gait3d.yaml new file mode 100644 index 0000000..79b2dc0 --- /dev/null +++ b/configs/gaitbase/gaitbase_da_gait3d.yaml @@ -0,0 +1,110 @@ +data_cfg: + dataset_name: Gait3D + dataset_root: your_path + dataset_partition: ./datasets/Gait3D/Gait3D.json + num_workers: 1 + remove_no_gallery: false # Remove probe if no gallery for it + test_dataset_name: Gait3D + +evaluator_cfg: + enable_float16: true + restore_ckpt_strict: true + restore_hint: 60000 + save_name: GaitBase_DA + eval_func: evaluate_Gait3D + sampler: + batch_shuffle: false + batch_size: 16 + sample_type: all_ordered # all indicates whole sequence used to test, while ordered means input sequence by its natural order; Other options: fixed_unordered + frames_all_limit: 720 # limit the number of sampled frames to prevent out of memory + metric: euc # cos + transform: + - type: BaseSilTransform + +loss_cfg: + - loss_term_weight: 1.0 + margin: 0.2 + type: TripletLoss + log_prefix: triplet + - loss_term_weight: 1.0 + scale: 16 + type: CrossEntropyLoss + log_prefix: softmax + log_accuracy: true + +model_cfg: + model: Baseline + backbone_cfg: + type: ResNet9 + block: BasicBlock + channels: # Layers configuration for automatically model construction + - 64 + - 128 + - 256 + - 512 + layers: + - 1 + - 1 + - 1 + - 1 + strides: + - 1 + - 2 + - 2 + - 1 + maxpool: false + SeparateFCs: + in_channels: 512 + out_channels: 256 + parts_num: 16 + SeparateBNNecks: + class_num: 3000 + in_channels: 256 + parts_num: 16 + bin_num: + - 16 + +optimizer_cfg: + lr: 0.1 + momentum: 0.9 + solver: SGD + weight_decay: 0.0005 + +scheduler_cfg: + gamma: 0.1 + milestones: # Learning Rate Reduction at each milestones + - 20000 + - 40000 + - 50000 + scheduler: MultiStepLR +trainer_cfg: + enable_float16: true # half_percesion float for memory reduction and speedup + fix_BN: false + with_test: true + log_iter: 100 + restore_ckpt_strict: true + restore_hint: 0 + save_iter: 20000 + save_name: GaitBase_DA + sync_BN: true + total_iter: 60000 + sampler: + batch_shuffle: true + batch_size: + - 32 # TripletSampler, batch_size[0] indicates Number of Identity + - 4 # batch_size[1] indicates Samples sequqnce for each Identity + frames_num_fixed: 30 # fixed frames number for training + frames_num_max: 50 # max frames number for unfixed training + frames_num_min: 10 # min frames number for unfixed traing + sample_type: unfixed_unordered # fixed control input frames number, unordered for controlling order of input tensor; Other options: unfixed_ordered or all_ordered + type: TripletSampler + transform: + - type: Compose + trf_cfg: + - type: RandomPerspective + prob: 0.2 + - type: BaseSilTransform + - type: RandomHorizontalFlip + prob: 0.2 + - type: RandomRotate + prob: 0.2 diff --git a/configs/gaitbase/gaitbase_da_grew.yaml b/configs/gaitbase/gaitbase_da_grew.yaml new file mode 100644 index 0000000..bef5282 --- /dev/null +++ b/configs/gaitbase/gaitbase_da_grew.yaml @@ -0,0 +1,108 @@ +data_cfg: + dataset_name: GREW + dataset_root: your_path + dataset_partition: ./datasets/GREW/GREW.json + num_workers: 1 + remove_no_gallery: false # Remove probe if no gallery for it + test_dataset_name: GREW + +evaluator_cfg: + enable_float16: true + restore_ckpt_strict: true + restore_hint: 180000 + save_name: GaitBase_DA + eval_func: GREW_submission + sampler: + batch_shuffle: false + batch_size: 16 + sample_type: all_ordered # all indicates whole sequence used to test, while ordered means input sequence by its natural order; Other options: fixed_unordered + frames_all_limit: 720 # limit the number of sampled frames to prevent out of memory + metric: euc # cos + transform: + - type: BaseSilCuttingTransform + +loss_cfg: + - loss_term_weight: 1.0 + margin: 0.2 + type: TripletLoss + log_prefix: triplet + - loss_term_weight: 1.0 + scale: 16 + type: CrossEntropyLoss + log_prefix: softmax + log_accuracy: true +model_cfg: + model: Baseline + backbone_cfg: + type: ResNet9 + block: BasicBlock + channels: # Layers configuration for automatically model construction + - 64 + - 128 + - 256 + - 512 + layers: + - 1 + - 1 + - 1 + - 1 + strides: + - 1 + - 2 + - 2 + - 1 + maxpool: false + SeparateFCs: + in_channels: 512 + out_channels: 256 + parts_num: 16 + SeparateBNNecks: + class_num: 20000 + in_channels: 256 + parts_num: 16 + bin_num: + - 16 +optimizer_cfg: + lr: 0.1 + momentum: 0.9 + solver: SGD + weight_decay: 0.0005 + +scheduler_cfg: + gamma: 0.1 + milestones: # Learning Rate Reduction at each milestones + - 80000 + - 120000 + - 150000 + scheduler: MultiStepLR +trainer_cfg: + enable_float16: true # half_percesion float for memory reduction and speedup + fix_BN: false + with_test: false + log_iter: 100 + restore_ckpt_strict: true + restore_hint: 0 + save_iter: 60000 + save_name: GaitBase_DA + sync_BN: true + total_iter: 180000 + sampler: + batch_shuffle: true + batch_size: + - 32 # TripletSampler, batch_size[0] indicates Number of Identity + - 4 # batch_size[1] indicates Samples sequqnce for each Identity + frames_num_fixed: 30 # fixed frames number for training + frames_num_max: 40 # max frames number for unfixed training + frames_num_min: 20 # min frames number for unfixed traing + sample_type: unfixed_unordered # fixed control input frames number, unordered for controlling order of input tensor; Other options: unfixed_ordered or all_ordered + type: TripletSampler + transform: + - type: Compose + trf_cfg: + - type: RandomPerspective + prob: 0.2 + - type: BaseSilCuttingTransform + - type: RandomHorizontalFlip + prob: 0.2 + - type: RandomRotate + prob: 0.2 diff --git a/configs/gaitbase/gaitbase_oumvlp.yaml b/configs/gaitbase/gaitbase_oumvlp.yaml new file mode 100644 index 0000000..dab56c0 --- /dev/null +++ b/configs/gaitbase/gaitbase_oumvlp.yaml @@ -0,0 +1,103 @@ +data_cfg: + dataset_name: OUMVLP + dataset_root: your_path + dataset_partition: ./datasets/OUMVLP/OUMVLP.json + num_workers: 1 + remove_no_gallery: false # Remove probe if no gallery for it + test_dataset_name: OUMVLP + +evaluator_cfg: + enable_float16: true + restore_ckpt_strict: true + restore_hint: 120000 + save_name: GaitBase + #eval_func: GREW_submission + sampler: + batch_shuffle: false + batch_size: 16 + sample_type: all_ordered # all indicates whole sequence used to test, while ordered means input sequence by its natural order; +Other options: fixed_unordered + frames_all_limit: 720 # limit the number of sampled frames to prevent out of memory + metric: euc # cos + transform: + - type: BaseSilCuttingTransform + +loss_cfg: + - loss_term_weight: 1.0 + margin: 0.2 + type: TripletLoss + log_prefix: triplet + - loss_term_weight: 1.0 + scale: 16 + type: CrossEntropyLoss + log_prefix: softmax + log_accuracy: true + +model_cfg: + model: Baseline + backbone_cfg: + type: ResNet9 + block: BasicBlock + channels: # Layers configuration for automatically model construction + - 64 + - 128 + - 256 + - 512 + layers: + - 1 + - 1 + - 1 + - 1 + strides: + - 1 + - 2 + - 2 + - 1 + maxpool: false + SeparateFCs: + in_channels: 512 + out_channels: 256 + parts_num: 16 + SeparateBNNecks: + class_num: 5153 + in_channels: 256 + parts_num: 16 + bin_num: + - 16 + +optimizer_cfg: + lr: 0.1 + momentum: 0.9 + solver: SGD + weight_decay: 0.0005 + +scheduler_cfg: + gamma: 0.1 + milestones: # Learning Rate Reduction at each milestones + - 60000 + - 80000 + - 100000 + scheduler: MultiStepLR +trainer_cfg: + enable_float16: true # half_percesion float for memory reduction and speedup + fix_BN: false + with_test: false + log_iter: 100 + restore_ckpt_strict: true + restore_hint: 0 + save_iter: 60000 + save_name: GaitBase + sync_BN: true + total_iter: 120000 + sampler: + batch_shuffle: true + batch_size: + - 32 # TripletSampler, batch_size[0] indicates Number of Identity + - 8 # batch_size[1] indicates Samples sequqnce for each Identity + frames_num_fixed: 30 # fixed frames number for training + frames_num_max: 40 # max frames number for unfixed training + frames_num_min: 20 # min frames number for unfixed traing + sample_type: fixed_unordered # fixed control input frames number, unordered for controlling order of input tensor; Other options: unfixed_ordered or all_ordered + type: TripletSampler + transform: + - type: BaseSilCuttingTransform diff --git a/configs/gaitedge/README.md b/configs/gaitedge/README.md index 496297b..9620abf 100644 --- a/configs/gaitedge/README.md +++ b/configs/gaitedge/README.md @@ -8,7 +8,7 @@ Gait is one of the most promising biometrics to identify individuals at a long d ## CASIA-B* Since the silhouettes of CASIA-B were obtained by the outdated background subtraction, there exists much noise caused by the background and clothes of subjects. Hence, we re-annotate the -silhouettes of CASIA-B and denote it as CASIA-B*. You can visit [this link](http://www.cbsr.ia.ac.cn/english/Gait%20Databases.asp) to apply for CASIA-B*. More details about CASIA-B* can be found in [this link](../../datasets/CASIA-B*/README.md). +silhouettes of CASIA-B and denote it as CASIA-B*. You can visit [this link](http://www.cbsr.ia.ac.cn/english/Gait%20Databases.asp) to apply for CASIA-B*. More details about CASIA-B* can be found in [this link](../../datasets/CASIA-B/README.md). ## Performance | Model | NM | BG | CL | TTG-200 (cross-domain) | Configuration | diff --git a/configs/gaitedge/phase1_rec.yaml b/configs/gaitedge/phase1_rec.yaml index 3eabbc6..73b6edd 100644 --- a/configs/gaitedge/phase1_rec.yaml +++ b/configs/gaitedge/phase1_rec.yaml @@ -3,7 +3,7 @@ data_cfg: dataset_name: CASIA-B* dataset_root: your_path data_in_use: [true, false, false, false] - dataset_partition: ./datasets/CASIA-B*/CASIA-B*.json + dataset_partition: ./datasets/CASIA-B/CASIA-B.json num_workers: 1 remove_no_gallery: false test_dataset_name: CASIA-B diff --git a/configs/gaitedge/phase1_seg.yaml b/configs/gaitedge/phase1_seg.yaml index db93aae..967f142 100644 --- a/configs/gaitedge/phase1_seg.yaml +++ b/configs/gaitedge/phase1_seg.yaml @@ -3,7 +3,7 @@ data_cfg: dataset_name: CASIA-B* dataset_root: your_path data_in_use: [false, false, true, true] - dataset_partition: ./datasets/CASIA-B*/CASIA-B*.json + dataset_partition: ./datasets/CASIA-B/CASIA-B.json num_workers: 1 remove_no_gallery: false test_dataset_name: CASIA-B diff --git a/configs/gaitedge/phase2_e2e.yaml b/configs/gaitedge/phase2_e2e.yaml index 6fea2c9..56fb91f 100644 --- a/configs/gaitedge/phase2_e2e.yaml +++ b/configs/gaitedge/phase2_e2e.yaml @@ -2,7 +2,7 @@ data_cfg: dataset_name: CASIA-B* dataset_root: your_path data_in_use: [false, true, true, true] - dataset_partition: ./datasets/CASIA-B*/CASIA-B*.json + dataset_partition: ./datasets/CASIA-B/CASIA-B.json num_workers: 1 remove_no_gallery: false # Remove probe if no gallery for it test_dataset_name: CASIA-B diff --git a/configs/gaitedge/phase2_gaitedge.yaml b/configs/gaitedge/phase2_gaitedge.yaml index efc5fe9..cfc3074 100644 --- a/configs/gaitedge/phase2_gaitedge.yaml +++ b/configs/gaitedge/phase2_gaitedge.yaml @@ -2,7 +2,7 @@ data_cfg: dataset_name: CASIA-B* dataset_root: your_path data_in_use: [false, true, true, true] - dataset_partition: ./datasets/CASIA-B*/CASIA-B*.json + dataset_partition: ./datasets/CASIA-B/CASIA-B.json num_workers: 1 remove_no_gallery: false # Remove probe if no gallery for it test_dataset_name: CASIA-B diff --git a/datasets/CASIA-B*/CASIA-B*.json b/datasets/CASIA-B*/CASIA-B*.json deleted file mode 100644 index a4daee6..0000000 --- a/datasets/CASIA-B*/CASIA-B*.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "TRAIN_SET": [ - "001", - "002", - "003", - "004", - "005", - "006", - "007", - "008", - "009", - "010", - "011", - "012", - "013", - "014", - "015", - "016", - "017", - "018", - "019", - "020", - "021", - "022", - "023", - "024", - "025", - "026", - "027", - "028", - "029", - "030", - "031", - "032", - "033", - "034", - "035", - "036", - "037", - "038", - "039", - "040", - "041", - "042", - "043", - "044", - "045", - "046", - "047", - "048", - "049", - "050", - "051", - "052", - "053", - "054", - "055", - "056", - "057", - "058", - "059", - "060", - "061", - "062", - "063", - "064", - "065", - "066", - "067", - "068", - "069", - "070", - "071", - "072", - "073", - "074" - ], - "TEST_SET": [ - "075", - "076", - "077", - "078", - "079", - "080", - "081", - "082", - "083", - "084", - "085", - "086", - "087", - "088", - "089", - "090", - "091", - "092", - "093", - "094", - "095", - "096", - "097", - "098", - "099", - "100", - "101", - "102", - "103", - "104", - "105", - "106", - "107", - "108", - "109", - "110", - "111", - "112", - "113", - "114", - "115", - "116", - "117", - "118", - "119", - "120", - "121", - "122", - "123", - "124" - ] -} \ No newline at end of file diff --git a/datasets/CASIA-B*/README.md b/datasets/CASIA-B*/README.md deleted file mode 100644 index 172470c..0000000 --- a/datasets/CASIA-B*/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# CASIA-B\* -## Introduction -CASIA-B\* is a re-segmented version of CASIA-B processed by Liang et al. The extra import of CASIA-B* owes to the background subtraction algorithm that CASIA-B uses for generating the silhouette data tends to produce much noise and is outdated for real-world applications nowadays. We use the up-to-date pretreatment strategy to re-segment the raw videos, i.e., the deep pedestrian track and segmentation algorithms. As a result, CASIA-B\* consists of the cropped RGB images, binary silhouettes, the height-width ratio of the obtained bounding boxes and the aligned silhouettes. Please refer to [GaitEdge](../../configs/gaitedge/README.md) for more details. If you need this sub-set, please apply with the instruction mentioned in [http://www.cbsr.ia.ac.cn/english/Gait%20Databases.asp]. In the Email Subject, please mark the specific dataset you need, i.e., Dataset B*. - -## Data structure -``` -casiab-128-end2end/ - 001 (subject) - bg-01 (type) - 000 (view) - 000-aligned-sils.pkl (aligned sils, nx64x44) - 000-ratios.pkl (aspect ratio of bounding boxes, n) - 000-rgbs.pkl (cropped RGB images, nx3x128x128) - 000-sils.pkl (binary silhouettes, nx128x128) - ...... - ...... - ...... -``` - -## How to use -By default, it loads all file directory information like other datasets before training starts. If you need to use some of these data separately, such as `aligned-sils`, then you can use the `data_in_use` parameter in `data_cfg` lexicographically, *i.e.* `data_in_use: [true, false, false, false]`. diff --git a/datasets/CASIA-B/README.md b/datasets/CASIA-B/README.md index c317ae4..319efdf 100644 --- a/datasets/CASIA-B/README.md +++ b/datasets/CASIA-B/README.md @@ -24,4 +24,26 @@ Download URL: http://www.cbsr.ia.ac.cn/GaitDatasetB-silh.zip ...... ...... ...... - ``` \ No newline at end of file + ``` + +# CASIA-B\* +## Introduction +CASIA-B\* is a re-segmented version of CASIA-B processed by Liang et al. The extra import of CASIA-B* owes to the background subtraction algorithm that CASIA-B uses for generating the silhouette data tends to produce much noise and is outdated for real-world applications nowadays. We use the up-to-date pretreatment strategy to re-segment the raw videos, i.e., the deep pedestrian track and segmentation algorithms. As a result, CASIA-B\* consists of the cropped RGB images, binary silhouettes, the height-width ratio of the obtained bounding boxes and the aligned silhouettes. Please refer to [GaitEdge](../../configs/gaitedge/README.md) for more details. If you need this sub-set, please apply with the instruction mentioned in [http://www.cbsr.ia.ac.cn/english/Gait%20Databases.asp]. In the Email Subject, please mark the specific dataset you need, i.e., Dataset B*. + +## Data structure +``` +casiab-128-end2end/ + 001 (subject) + bg-01 (type) + 000 (view) + 000-aligned-sils.pkl (aligned sils, nx64x44) + 000-ratios.pkl (aspect ratio of bounding boxes, n) + 000-rgbs.pkl (cropped RGB images, nx3x128x128) + 000-sils.pkl (binary silhouettes, nx128x128) + ...... + ...... + ...... +``` + +## How to use +By default, it loads all file directory information like other datasets before training starts. If you need to use some of these data separately, such as `aligned-sils`, then you can use the `data_in_use` parameter in `data_cfg` lexicographically, *i.e.* `data_in_use: [true, false, false, false]`. diff --git a/opengait/data/transform.py b/opengait/data/transform.py index 376e19a..8d57f73 100644 --- a/opengait/data/transform.py +++ b/opengait/data/transform.py @@ -1,6 +1,9 @@ -from data import transform as base_transform import numpy as np - +import random +import torchvision.transforms as T +import cv2 +import math +from data import transform as base_transform from utils import is_list, is_dict, get_valid_args @@ -49,6 +52,139 @@ class BaseRgbTransform(): return (x - self.mean) / self.std +# **************** Data Agumentation **************** + + +class RandomHorizontalFlip(object): + def __init__(self, prob=0.5): + self.prob = prob + + def __call__(self, seq): + if random.uniform(0, 1) >= self.prob: + return seq + else: + return seq[:, :, ::-1] + + +class RandomErasing(object): + def __init__(self, prob=0.5, sl=0.05, sh=0.2, r1=0.3, per_frame=False): + self.prob = prob + self.sl = sl + self.sh = sh + self.r1 = r1 + self.per_frame = per_frame + + def __call__(self, seq): + if not self.per_frame: + if random.uniform(0, 1) >= self.prob: + return seq + else: + for _ in range(100): + seq_size = seq.shape + area = seq_size[1] * seq_size[2] + + target_area = random.uniform(self.sl, self.sh) * area + aspect_ratio = random.uniform(self.r1, 1 / self.r1) + + h = int(round(math.sqrt(target_area * aspect_ratio))) + w = int(round(math.sqrt(target_area / aspect_ratio))) + + if w < seq_size[2] and h < seq_size[1]: + x1 = random.randint(0, seq_size[1] - h) + y1 = random.randint(0, seq_size[2] - w) + seq[:, x1:x1+h, y1:y1+w] = 0. + return seq + return seq + else: + self.per_frame = False + frame_num = seq.shape[0] + ret = [self.__call__(seq[k][np.newaxis, ...]) + for k in range(frame_num)] + self.per_frame = True + return np.concatenate(ret, 0) + + +class RandomRotate(object): + def __init__(self, prob=0.5, degree=10): + self.prob = prob + self.degree = degree + + def __call__(self, seq): + if random.uniform(0, 1) >= self.prob: + return seq + else: + _, dh, dw = seq.shape + # rotation + degree = random.uniform(-self.degree, self.degree) + M1 = cv2.getRotationMatrix2D((dh // 2, dw // 2), degree, 1) + # affine + seq = [cv2.warpAffine(_[0, ...], M1, (dw, dh)) + for _ in np.split(seq, seq.shape[0], axis=0)] + seq = np.concatenate([np.array(_)[np.newaxis, ...] + for _ in seq], 0) + return seq + + +class RandomPerspective(object): + def __init__(self, prob=0.5): + self.prob = prob + + def __call__(self, seq): + if random.uniform(0, 1) >= self.prob: + return seq + else: + _, h, w = seq.shape + cutting = int(w // 44) * 10 + x_left = list(range(0, cutting)) + x_right = list(range(w - cutting, w)) + TL = (random.choice(x_left), 0) + TR = (random.choice(x_right), 0) + BL = (random.choice(x_left), h) + BR = (random.choice(x_right), h) + srcPoints = np.float32([TL, TR, BR, BL]) + canvasPoints = np.float32([[0, 0], [w, 0], [w, h], [0, h]]) + perspectiveMatrix = cv2.getPerspectiveTransform( + np.array(srcPoints), np.array(canvasPoints)) + seq = [cv2.warpPerspective(_[0, ...], perspectiveMatrix, (w, h)) + for _ in np.split(seq, seq.shape[0], axis=0)] + seq = np.concatenate([np.array(_)[np.newaxis, ...] + for _ in seq], 0) + return seq + + +class RandomAffine(object): + def __init__(self, prob=0.5, degree=10): + self.prob = prob + self.degree = degree + + def __call__(self, seq): + if random.uniform(0, 1) >= self.prob: + return seq + else: + _, dh, dw = seq.shape + # rotation + max_shift = int(dh // 64 * 10) + shift_range = list(range(0, max_shift)) + pts1 = np.float32([[random.choice(shift_range), random.choice(shift_range)], [ + dh-random.choice(shift_range), random.choice(shift_range)], [random.choice(shift_range), dw-random.choice(shift_range)]]) + pts2 = np.float32([[random.choice(shift_range), random.choice(shift_range)], [ + dh-random.choice(shift_range), random.choice(shift_range)], [random.choice(shift_range), dw-random.choice(shift_range)]]) + M1 = cv2.getAffineTransform(pts1, pts2) + # affine + seq = [cv2.warpAffine(_[0, ...], M1, (dw, dh)) + for _ in np.split(seq, seq.shape[0], axis=0)] + seq = np.concatenate([np.array(_)[np.newaxis, ...] + for _ in seq], 0) + return seq + +# ****************************************** + +def Compose(trf_cfg): + assert is_list(trf_cfg) + transform = T.Compose([get_transform(cfg) for cfg in trf_cfg]) + return transform + + def get_transform(trf_cfg=None): if is_dict(trf_cfg): transform = getattr(base_transform, trf_cfg['type']) diff --git a/opengait/evaluation/evaluator.py b/opengait/evaluation/evaluator.py index 1454e5f..251f707 100644 --- a/opengait/evaluation/evaluator.py +++ b/opengait/evaluation/evaluator.py @@ -231,7 +231,7 @@ def evaluate_segmentation(data, dataset): return {"scalar/test_accuracy/mIOU": miou} -def evaluate_Gait3D(data, conf, metric='euc'): +def evaluate_Gait3D(data, dataset, metric='euc'): msg_mgr = get_msg_mgr() features, labels, cams, time_seqs = data['embeddings'], data['labels'], data['types'], data['views'] diff --git a/opengait/modeling/backbones/resnet.py b/opengait/modeling/backbones/resnet.py new file mode 100644 index 0000000..db20191 --- /dev/null +++ b/opengait/modeling/backbones/resnet.py @@ -0,0 +1,58 @@ +from torch.nn import functional as F +import torch.nn as nn +from torchvision.models.resnet import BasicBlock, Bottleneck, ResNet +from ..modules import BasicConv2d + + +block_map = {'BasicBlock': BasicBlock, + 'Bottleneck': Bottleneck} + + +class ResNet9(ResNet): + def __init__(self, block, channels=[32, 64, 128, 256], in_channel=1, layers=[1, 2, 2, 1], strides=[1, 2, 2, 1], maxpool=True): + if block in block_map.keys(): + block = block_map[block] + else: + raise ValueError( + "Error type for -block-Cfg-, supported: 'BasicBlock' or 'Bottleneck'.") + self.maxpool_flag = maxpool + super(ResNet9, self).__init__(block, layers) + + # Not used # + self.fc = None + ############ + self.inplanes = channels[0] + self.bn1 = nn.BatchNorm2d(self.inplanes) + + self.conv1 = BasicConv2d(in_channel, self.inplanes, 3, 1, 1) + + self.layer1 = self._make_layer( + block, channels[0], layers[0], stride=strides[0], dilate=False) + + self.layer2 = self._make_layer( + block, channels[1], layers[1], stride=strides[1], dilate=False) + self.layer3 = self._make_layer( + block, channels[2], layers[2], stride=strides[2], dilate=False) + self.layer4 = self._make_layer( + block, channels[3], layers[3], stride=strides[3], dilate=False) + + def _make_layer(self, block, planes, blocks, stride=1, dilate=False): + if blocks >= 1: + layer = super()._make_layer(block, planes, blocks, stride=stride, dilate=dilate) + else: + def layer(x): return x + return layer + + def forward(self, x): + x = self.conv1(x) + x = self.bn1(x) + x = self.relu(x) + if self.maxpool_flag: + x = self.maxpool(x) + + x = self.layer1(x) + x = self.layer2(x) + x = self.layer3(x) + x = self.layer4(x) + return x + diff --git a/opengait/modeling/base_model.py b/opengait/modeling/base_model.py index dff0b39..311da48 100644 --- a/opengait/modeling/base_model.py +++ b/opengait/modeling/base_model.py @@ -427,7 +427,8 @@ class BaseModel(MetaModel, nn.Module): model.train() if model.cfgs['trainer_cfg']['fix_BN']: model.fix_BN() - model.msg_mgr.write_to_tensorboard(result_dict) + if result_dict: + model.msg_mgr.write_to_tensorboard(result_dict) model.msg_mgr.reset_time() if model.iteration >= model.engine_cfg['total_iter']: break