ftramer/ensemble-adv-training

Tool for loss surfaces?

akskuchi opened this issue · 7 comments

Hello,
Could you disclose the tool you used for visualizing the loss surfaces of models in the publication?

Got it, thank you!
Also, in this expression:
image

how do you pick the gradient from modelB that is in the orthogonal adversarial direction to g of modelA_adv? or am I missing something basic?

The gradient of modelB actually happens to be roughly orthogonal to that of modelA_adv so we don't have to do anything special here.

Oh, that's interesting. So what I tried was:

  • pre-train modelA_adv
  • pre-train modelB
  • generate x_star (notations from your publication) samples (using g and g_orthogonal, with the same epsilon=0.3), like this:
modelA_adv(x)
g = x.grad
modelB(x)
g_orthogonal = x.grad

x_star[i] = x + epsilon * (_g + _g_orthogonal)
  • run all x_star through modelA_adv and collect losses

Now, maybe for some trivial reason, I am stuck on how to plot the loss surfaces?
interpolate eps1 and eps2 between 0.0 - 0.3 and tri-surface plot them? or am I completely lost?

Yes, the typical workflow would look something like this (I haven't tested this specific code so there might be some small bugs):

import numpy as np
from mpl_toolkits.mplot3d import axes3d, Axes3D
from matplotlib import cm

# bounds for the x and y axis
x1, x2, y1, y2 = [0.0, 0.3, 0.0, 0.3]

# step size
h_x = (x2 - x1) / 100.0
h_y = (y2 - y1) / 100.0

# create a grid (of size 100x100) of (x,y) coordinates 
xx, yy = np.meshgrid(np.arange(x1, x2, h_x), np.arange(y1, x2, h_y))

perturbs = xx.reshape((-1, 1)) * g.reshape((1, -1)) + yy.reshape((-1, 1)) * g_ortho.reshape((1, -1))

X_perturbs[i] = X[i] + perturbs.reshape((-1, X.shape[1], X.shape[2], X.shape[3]))

# evaluate the model on X_perturbs[i]
losses = ...

fig = plt.figure(figsize=(10, 8))
ax = Axes3D(fig, rect=[0.0, 0.0, 0.9, 1.0])
surf = ax.plot_surface(xx, yy, np.asarray(losses).reshape(xx.shape), cmap=cm.coolwarm,
                       linewidth=0, antialiased=False)
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()

Thank you for clarifying. I tried it:

print(f'min loss: {min(losses)}, max loss: {max(losses)}')
fig = plt.figure(figsize=(10, 8))
ax = Axes3D(fig, rect=[0.0, 0.0, 0.9, 1.0])
surf = ax.plot_surface(xx, yy, np.asarray(losses).reshape(xx.shape),
                       cmap=cm.coolwarm, linewidth=0, antialiased=False)
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()

which results in:
min loss: 0.0, max loss: 4.505677223205566

image

From the colorbar, I see that the losses need to be normalized or moved to some other scale, but for some reason, it does not give the landscape (like in the publication) :/

I get the idea behind and will look further for any mistakes I'm doing.
Thanks a lot for all the explanation.