Jelajahi Sumber

added MeanModelClassifier as an example of a SeparateModelClassifier and added tests for creating it

Dimitri Korsch 4 tahun lalu
induk
melakukan
0b0d41f0ba

+ 2 - 0
cvmodelz/classifiers/__init__.py

@@ -1,8 +1,10 @@
 from cvmodelz.classifiers.base import Classifier
+from cvmodelz.classifiers.separate_model_classifier import MeanModelClassifier
 from cvmodelz.classifiers.separate_model_classifier import SeparateModelClassifier
 
 
 __all__ = [
 	"Classifier",
+	"MeanModelClassifier",
 	"SeparateModelClassifier",
 ]

+ 1 - 1
cvmodelz/classifiers/base.py

@@ -3,8 +3,8 @@ import chainer
 
 from chainer import functions as F
 from chainer.serializers import npz
-from typing import Dict
 from typing import Callable
+from typing import Dict
 
 from cvmodelz.models.base import BaseModel
 

+ 41 - 1
cvmodelz/classifiers/separate_model_classifier.py

@@ -1,10 +1,12 @@
 import abc
 import chainer
 
+from chainer import functions as F
 from typing import Callable
+from typing import Dict
 
-from cvmodelz.models.base import BaseModel
 from cvmodelz.classifiers.base import Classifier
+from cvmodelz.models.base import BaseModel
 
 
 
@@ -61,3 +63,41 @@ class SeparateModelClassifier(Classifier):
 		super(SeparateModelClassifier, self).enable_only_head()
 		self.separate_model.disable_update()
 		self.separate_model.fc.enable_update()
+
+
+class MeanModelClassifier(SeparateModelClassifier):
+
+	def evaluations(self, pred0: chainer.Variable, pred1: chainer.Variable, y: chainer.Variable) -> Dict[str, chainer.Variable]:
+		accu0 = self.model.accuracy(pred0, y)
+		accu1 = self.separate_model.accuracy(pred1, y)
+
+		mean_pred = (F.softmax(pred0) + F.softmax(pred1)) / 2
+
+		accu = self.model.accuracy(mean_pred, y)
+
+		return dict(
+			accu0=accu0,
+			accu1=accu1,
+			accuracy=accu,
+		)
+
+	def forward(self, X: chainer.Variable, y: chainer.Variable) -> chainer.Variable:
+
+		pred0 = self.model(X, layer_name=self.layer_name)
+		pred1 = self.separate_model(X, layer_name=self.layer_name)
+
+		loss0, loss1 = self.loss(pred0, y), self.loss(pred1, y)
+		loss = (loss0 + loss1) / 2
+
+		evaluations = self.evaluations(pred0, pred1, y)
+
+		self.report(
+			loss0=loss0,
+			loss1=loss1,
+			loss=loss,
+			**evaluations
+		)
+		return loss
+
+
+

+ 13 - 0
tests/classifier_tests/creation.py

@@ -3,6 +3,7 @@ import test_utils
 import unittest
 
 from cvmodelz.classifiers import Classifier
+from cvmodelz.classifiers import MeanModelClassifier
 from cvmodelz.models import ModelFactory
 
 class ClassifierCreationTests(unittest.TestCase):
@@ -28,10 +29,22 @@ class ClassifierCreationTests(unittest.TestCase):
 		self.assertEqual(loss.ndim, 0)
 		self.assertEqual(loss.shape, ())
 
+class MeanModelClassifierCreationTests(ClassifierCreationTests):
+
+	def new_clf(self, key, **kwargs):
+		model = ModelFactory.new(key, pretrained_model=None)
+		return model, MeanModelClassifier(model, **kwargs)
+
 
 
 test_utils.add_tests(ClassifierCreationTests.creation,
 	model_list=ModelFactory.get_models(["cvmodelz", "chainercv2"]))
 
+test_utils.add_tests(MeanModelClassifierCreationTests.creation,
+	model_list=ModelFactory.get_models(["cvmodelz", "chainercv2"]))
+
 test_utils.add_tests(ClassifierCreationTests.loss_computation,
 	model_list=ModelFactory.get_models(["cvmodelz", "chainercv2"]))
+
+test_utils.add_tests(MeanModelClassifierCreationTests.loss_computation,
+	model_list=ModelFactory.get_models(["cvmodelz", "chainercv2"]))

+ 1 - 1
tests/main.py

@@ -13,5 +13,5 @@ sys.path.insert(0, str(cwd.parent))
 from model_tests import *
 from classifier_tests import *
 
-with chainer.using_config("train", False):
+with chainer.using_config("train", False), chainer.no_backprop_mode():
 	unittest.main()