Skip to content

Commit

Permalink
Merge 80fc023 into dbbcdcb
Browse files Browse the repository at this point in the history
  • Loading branch information
jonasrauber committed Oct 2, 2017
2 parents dbbcdcb + 80fc023 commit df88d67
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 9 deletions.
22 changes: 17 additions & 5 deletions foolbox/distances.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,26 @@ class MeanSquaredDistance(Distance):

def _calculate(self):
min_, max_ = self._bounds
diff = (self.other - self.reference) / (max_ - min_)
value = np.mean(np.square(diff))
n = np.prod(self.reference.shape)
gradient = 1 / n * 2 * diff / (max_ - min_)
f = n * (max_ - min_)**2

diff = self.other - self.reference
value = np.vdot(diff, diff) / f

# calculate the gradient only when needed
self._g_diff = diff
self._g_f = f
gradient = None
return value, gradient

@property
def gradient(self):
if self._gradient is None:
self._gradient = self._g_diff / (self._g_f / 2)
return self._gradient

def __str__(self):
return 'rel. MSE = {:.5f} %'.format(self._value * 100)
return 'normalized MSE = {:.5f} %'.format(self._value * 100)


MSE = MeanSquaredDistance
Expand All @@ -148,4 +160,4 @@ def _calculate(self):
return value, gradient

def __str__(self):
return 'rel. MAE = {:.5f} %'.format(self._value * 100)
return 'normalized MAE = {:.5f} %'.format(self._value * 100)
21 changes: 17 additions & 4 deletions foolbox/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,27 @@ def channel_axis(self):
return self._channel_axis

def _process_input(self, input_):
result = (input_ - self._preprocessing[0]) / self._preprocessing[1]
result = result.astype(input_.dtype, copy=False)
psub, pdiv = self._preprocessing
psub = np.asarray(psub, dtype=input_.dtype)
pdiv = np.asarray(pdiv, dtype=input_.dtype)
result = input_
if np.any(psub != 0):
result = input_ - psub # creates a copy
if np.any(pdiv != 1):
if np.any(psub != 0): # already copied
result /= pdiv # in-place
else:
result = result / pdiv # creates a copy
assert result.dtype == input_.dtype
return result

def _process_gradient(self, gradient):
result = gradient / self._preprocessing[1]
result = result.astype(gradient.dtype, copy=False)
_, pdiv = self._preprocessing
pdiv = np.asarray(pdiv, dtype=gradient.dtype)
if np.any(pdiv != 1):
result = gradient / pdiv
else:
result = gradient
assert result.dtype == gradient.dtype
return result

Expand Down
10 changes: 10 additions & 0 deletions foolbox/tests/test_models_keras.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,14 @@ def test_keras_model_preprocess():
bounds=bounds,
predicts='logits')

preprocessing = (0, np.random.uniform(size=(5, 5, channels)) + 1)

model4 = KerasModel(
Model(inputs=inputs, outputs=logits),
bounds=bounds,
predicts='logits',
preprocessing=preprocessing)

np.random.seed(22)
test_images = np.random.rand(2, 5, 5, channels).astype(np.float32)
test_images_copy = test_images.copy()
Expand All @@ -148,6 +156,8 @@ def test_keras_model_preprocess():
p3 - p3.max(),
decimal=5)

model4.batch_predictions(test_images)


def test_keras_model_gradients():
num_classes = 1000
Expand Down

0 comments on commit df88d67

Please sign in to comment.