|
@@ -8,7 +8,6 @@ from chainercv.transforms import resize
|
|
|
from chainercv.transforms import scale
|
|
|
from collections import OrderedDict
|
|
|
from collections.abc import Iterable
|
|
|
-from os.path import isfile
|
|
|
|
|
|
|
|
|
from cvmodelz.models.meta_info import ModelInfo
|
|
@@ -32,15 +31,22 @@ def _assign_batch_norm(name, link, beta, avg_mean, avg_var):
|
|
|
_assign(name, link.avg_var, avg_var)
|
|
|
|
|
|
|
|
|
-class InceptionV3(PretrainedModelMixin, chainer.Chain):
|
|
|
+
|
|
|
+"""
|
|
|
+We need this to "extract" pretrained_model argument,
|
|
|
+otherwise it would be passed to the constructor of the
|
|
|
+chainer.Chain class, where it raises an error
|
|
|
+"""
|
|
|
+class InceptionV3Layers(chainer.Chain):
|
|
|
+
|
|
|
|
|
|
def __init__(self, pretrained_model=None, aux_logits=False, *args, **kwargs):
|
|
|
self.aux_logits = aux_logits
|
|
|
pooling = PoolingType.G_AVG.value()
|
|
|
- super(InceptionV3, self).__init__(*args, pooling=pooling, **kwargs)
|
|
|
+ super(InceptionV3Layers, self).__init__(*args, pooling=pooling, **kwargs)
|
|
|
+
|
|
|
|
|
|
- if pretrained_model is not None and isfile(pretrained_model):
|
|
|
- self.load(pretrained_model, strict=True)
|
|
|
+class InceptionV3(PretrainedModelMixin, InceptionV3Layers):
|
|
|
|
|
|
def init_model_info(self):
|
|
|
self.meta = ModelInfo(
|
|
@@ -55,6 +61,12 @@ class InceptionV3(PretrainedModelMixin, chainer.Chain):
|
|
|
classifier_layers=["fc"],
|
|
|
)
|
|
|
|
|
|
+ @property
|
|
|
+ def functions(self):
|
|
|
+ super(InceptionV3, self).functions
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
def forward(self, x, layer_name='fc'):
|
|
|
aux_logit = None
|
|
|
for key, funcs in self.functions.items():
|
|
@@ -98,15 +110,15 @@ class InceptionV3(PretrainedModelMixin, chainer.Chain):
|
|
|
return self.pool(x)
|
|
|
|
|
|
|
|
|
- def load(self, weights, *args, **kwargs):
|
|
|
+ def load(self, weights, *args, **kwargs) -> None:
|
|
|
if isinstance(weights, str) and weights.endswith(".h5"):
|
|
|
- self._load_from_keras(weights)
|
|
|
+ return self._load_from_keras(weights)
|
|
|
elif isinstance(weights, str) and weights.endswith(".ckpt.npz"):
|
|
|
- self._load_from_ckpt_weights(weights)
|
|
|
- else:
|
|
|
- return super(InceptionV3, self).load(weights, *args, **kwargs)
|
|
|
+ return self._load_from_ckpt_weights(weights)
|
|
|
|
|
|
- def init_extra_layers(self, n_classes):
|
|
|
+ return super(InceptionV3, self).load(weights, *args, **kwargs)
|
|
|
+
|
|
|
+ def init_extra_layers(self, n_classes) -> None:
|
|
|
# input 3 x 299 x 299
|
|
|
self.head = blocks.InceptionHead()
|
|
|
# output 192 x 35 x 35
|
|
@@ -152,7 +164,9 @@ class InceptionV3(PretrainedModelMixin, chainer.Chain):
|
|
|
# input 2048 x 8 x 8
|
|
|
# global average pooling
|
|
|
# output 2048 x 1 x 1
|
|
|
- self.fc = L.Linear(2048, n_classes)
|
|
|
+
|
|
|
+ # the final fc layer is initilized by PretrainedModelMixin
|
|
|
+ super(InceptionV3, self).init_extra_layers(n_classes)
|
|
|
|
|
|
def loss(self, pred, gt, loss_func=F.softmax_cross_entropy, alpha=0.4):
|
|
|
if isinstance(pred, tuple):
|
|
@@ -233,4 +247,3 @@ class InceptionV3(PretrainedModelMixin, chainer.Chain):
|
|
|
_assign_batch_norm(name, link, beta, avg_mean, avg_var)
|
|
|
else:
|
|
|
raise ValueError("Unkown link type: {}!".format(type(link)))
|
|
|
-
|