diff --git a/README.md b/README.md
index 753e60c..b0fedec 100644
--- a/README.md
+++ b/README.md
@@ -1,16 +1,40 @@
# reid_baseline
reid baseline model for exploring softmax and triplet hard loss's influence.
-## Configuration
+## Architecture
+
+### softmax
+
+### triplet
+
+### softmax + triplet
+
### Classification
-resnet lr: 0.1
-classifier lr: 0.01
+
+
+
+
### Triplet Hard
-lr: 2e-4
+
+
+
+
### Classification + Triplet Hard
-lr: 2e-4
-exponetional decay at 150
\ No newline at end of file
+
+
+
+
+
+## Results
+
+| loss | rank1 | map |
+| --- | --| ---|
+| triplet hard | 89.9% | 76.8% |
+| softmax | 87% | 65% |
+|triplet + softmax | 89.7% | 76.2% |
+
+
diff --git a/config.py b/config.py
index 8882d2c..ebc3999 100644
--- a/config.py
+++ b/config.py
@@ -21,12 +21,12 @@ class DefaultConfig(object):
width = 192
# optimization options
- optim = 'SGD'
- max_epoch = 100
+ optim = 'Adam'
+ max_epoch = 60
train_batch = 128
test_batch = 128
lr = 0.1
- step_size = 60
+ step_size = 40
gamma = 0.1
weight_decay = 5e-4
momentum = 0.9
diff --git a/main_reid.py b/main_reid.py
index d9bed12..4a669e5 100644
--- a/main_reid.py
+++ b/main_reid.py
@@ -92,7 +92,8 @@ def train_classification(**kwargs):
# get optimizer
optimizer = torch.optim.SGD(
- model.optim_policy(), lr=args.lr, weight_decay=args.weight_decay, momentum=args.momentum
+ model.optim_policy(), lr=args.lr, weight_decay=args.weight_decay,
+ momentum=args.momentum, nesterov=True
)
def adjust_lr(optimizer, ep, decay_ep, gamma):
diff --git a/models/resnet_reid.py b/models/resnet_reid.py
index 4b6f58f..f9774c4 100644
--- a/models/resnet_reid.py
+++ b/models/resnet_reid.py
@@ -15,10 +15,10 @@ from torch import nn
from .resnet import ResNet
-def weights_init(m):
+def weights_init_kaiming(m):
classname = m.__class__.__name__
if classname.find('Linear') != -1:
- nn.init.normal_(m.weight, std=0.001)
+ nn.init.kaiming_normal_(m.weight, a=0, mode='fan_out')
nn.init.constant_(m.bias, 0.0)
elif classname.find('Conv') != -1:
nn.init.kaiming_normal_(m.weight, a=0, mode='fan_in')
@@ -30,6 +30,13 @@ def weights_init(m):
nn.init.constant_(m.bias, 0.0)
+def weights_init_classifier(m):
+ classname = m.__class__.__name__
+ if classname.find('Linear') != -1:
+ nn.init.normal_(m.weight, std=0.001)
+ nn.init.constant_(m.bias, 0.0)
+
+
class ResNetBuilder(nn.Module):
in_planes = 2048
@@ -37,20 +44,25 @@ class ResNetBuilder(nn.Module):
super().__init__()
self.base = ResNet(last_stride)
self.base.load_param(model_path)
- self.bottleneck = nn.Sequential(
- nn.BatchNorm2d(self.in_planes),
- nn.ReLU(True)
- )
+
self.num_classes = num_classes
if num_classes is not None:
- self.classifier = nn.Linear(self.in_planes, num_classes)
+ self.bottleneck = nn.Sequential(
+ nn.Linear(self.in_planes, 512),
+ nn.BatchNorm1d(512),
+ nn.LeakyReLU(0.1),
+ nn.Dropout(p=0.5)
+ )
+ self.bottleneck.apply(weights_init_kaiming)
+ self.classifier = nn.Linear(512, self.num_classes)
+ self.classifier.apply(weights_init_classifier)
def forward(self, x):
feat = self.base(x)
- feat = self.bottleneck(feat)
global_feat = F.avg_pool2d(feat, feat.shape[2:]) # (b, 2048, 1, 1)
global_feat = global_feat.view(global_feat.shape[0], -1)
if self.training and self.num_classes is not None:
+ global_feat = self.bottleneck(global_feat)
cls_score = self.classifier(global_feat)
return cls_score, global_feat
else:
@@ -58,10 +70,12 @@ class ResNetBuilder(nn.Module):
def optim_policy(self):
base_param_group = self.base.parameters()
- clf_param_group = self.classifier.parameters()
+ other_param_group = list()
+ other_param_group.extend(list(self.bottleneck.parameters()))
+ other_param_group.extend(list(self.classifier.parameters()))
return [
{'params': base_param_group, 'lr_multi': 0.1},
- {'params': clf_param_group}
+ {'params': other_param_group}
]