Skip to content

Commit

Permalink
Update sphere.py -- add pooling and max_pooling (#1596)
Browse files Browse the repository at this point in the history
* Update sphere.py

* Update sphere.py

fix signature of pooling and max_pooling

* Update sphere.py

fix style

* Update sphere.py

remove torch dependency

* Update sphere.py

* Update sphere.py

* Update sphere.py

black formatting

* Update sphere.py

* Update sphere.py

- black 
- change standard avg pooling size

* Update sphere.py

* Update sphere.py

* Update sphere.py

fix black

* Update sphere.py

* Update sphere.py

* Update sphere.py

* Update sphere.py
  • Loading branch information
mzameshina authored Feb 20, 2024
1 parent 31235c5 commit 75abae1
Showing 1 changed file with 61 additions and 1 deletion.
62 changes: 61 additions & 1 deletion nevergrad/common/sphere.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,64 @@ def antithetic_order_and_sign(n, shape, axis=-1, conv=None):
return antithetic_order(n, shape, axis, also_sym=True)


# Please avoid using NumPy-to-PyTorch tensor transformations for actual image generation,
# as they may impact computational efficiency.
# For instance, replace `manual_avg_pool3d` with `torch.nn.AvgPool3d()`.
def manual_avg_pool3d(arr, kernel_size):
output_shape = (
arr.shape[0] // kernel_size[0],
arr.shape[1] // kernel_size[1],
arr.shape[2] // kernel_size[2],
)
result = np.zeros(output_shape)
for z in range(output_shape[0]):
for y in range(output_shape[1]):
for x in range(output_shape[2]):
result[z, y, x] = np.mean(
arr[
z * kernel_size[0] : (z + 1) * kernel_size[0],
y * kernel_size[1] : (y + 1) * kernel_size[1],
x * kernel_size[2] : (x + 1) * kernel_size[2],
]
)
return result


def max_pooling(n, shape, budget=default_budget, conv=None):
# Avg pooling standard size should be (1, s/8, s/8)
pooling = tuple([max(1, s // 8) for s in shape])

if conv != None:
pooling = (1, *conv)

old_latents = []
x = []
for i in range(n):
latents = np.random.randn(*shape)
latents_pooling = manual_avg_pool3d(latents, pooling)
if old_latents:
dist = min([np.linalg.norm(latents_pooling - old) for old in old_latents])
max_dist = dist
t0 = time.time()
while (time.time() - t0) < 0.01 * budget / n:
latents_new = np.random.randn(*shape)
latents_pooling_new = manual_avg_pool3d(latents_new, pooling)
dist_new = min([np.linalg.norm(latents_pooling_new - old) for old in old_latents])
if dist_new > max_dist:
latents = latents_new
max_dist = dist_new
latents_pooling = latents_pooling_new
x.append(latents)
old_latents.append(latents_pooling)
x = np.stack(x)
x = normalize(x)
return x


def max_without_pooling(n, shape, budget=default_budget, conv=[1, 1]):
return max_pooling(n, shape, budget, conv)


def greedy_dispersion(n, shape, budget=default_budget, conv=None):
x = normalize([np.random.randn(*shape)])
for i in range(n - 1):
Expand Down Expand Up @@ -826,6 +884,8 @@ def metric_pack_big_conv(x, budget=default_budget):
"Riesz_blursum_lowconv_loworder",
"Riesz_blursum_lowconv_midorder",
"Riesz_blursum_lowconv_highorder",
"max_pooling",
"max_without_pooling",
]
list_metrics = [
"metric_half",
Expand Down Expand Up @@ -1185,7 +1245,7 @@ def quasi_randomize(pointset, method=None):
shape = [int(i) for i in list(pointset[0].shape)]
norms = [np.linalg.norm(pointset[i]) for i in range(n)]
if method is None or method == "none":
method = "dispersion_with_big_conv" if (len(shape) > 1 and shape[0] > 1) else "covering"
method = "max_pooling" if (len(shape) > 1 and shape[0] > 1) else "covering"
# if method == "none":
# if len(shape) > 1 and shape[0] > 5:
# x = dispersion(n, shape, conv=[int(s * 24 / 64) for s in list(shape)[:-1]])
Expand Down

0 comments on commit 75abae1

Please sign in to comment.