jonathan-lys commited on
Commit
fa9a216
·
verified ·
1 Parent(s): 039950f

Rollback the add_time_patch method

Browse files
Files changed (1) hide show
  1. modeling_reve.py +69 -7
modeling_reve.py CHANGED
@@ -217,16 +217,36 @@ class Learnable4DPE(nn.Module):
217
 
218
 
219
  class FourierEmb4D(nn.Module):
220
- def __init__(self, dimension: int, freqs: int, increment_time=0.1, margin: float = 0.4):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  super().__init__()
222
  self.dimension = dimension
223
  self.freqs = freqs
224
  self.increment_time = increment_time
225
  self.margin = margin
226
 
227
- def forward(self, positions_):
228
  positions = positions_.clone()
229
- positions[..., -1] *= self.increment_time
230
  input_shape = positions.shape
231
  batch_dims = list(input_shape[:-1])
232
 
@@ -241,26 +261,68 @@ class FourierEmb4D(nn.Module):
241
  p_z = 2 * math.pi * freqs_z / width
242
  p_w = 2 * math.pi * freqs_w / width
243
  positions = positions[..., None, None, None, None, :]
244
- loc = positions[..., 0] * p_x + positions[..., 1] * p_y + positions[..., 2] * p_z + positions[..., 3] * p_w
 
 
 
 
 
245
  batch_dims.append(-1)
246
  loc = loc.view(batch_dims)
247
 
248
  half_dim = self.dimension // 2
249
  current_dim = loc.shape[-1]
250
-
251
- # FIX: Safe slicing logic
252
  if current_dim != half_dim:
253
  if current_dim > half_dim:
254
  loc = loc[..., :half_dim]
255
  else:
256
  raise ValueError(
257
  f"Input dimension ({current_dim}) is too small for target "
258
- f"embedding dimension ({self.dimension}). Expected at least {half_dim}.",
259
  )
260
 
261
  emb = torch.cat([torch.cos(loc), torch.sin(loc)], dim=-1)
262
  return emb
263
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
 
265
  def patch_embedding(embed_dim, patch_size):
266
  to_patch_embedding = nn.Sequential(nn.Linear(patch_size, embed_dim))
 
217
 
218
 
219
  class FourierEmb4D(nn.Module):
220
+ """
221
+ Fourier positional embedding for 4D positions (x, y, z, t).
222
+ This version allows for a reduced number of frequencies (n_freqs),
223
+ and ensures the output embedding has the specified dimension.
224
+
225
+ Parameters
226
+ ----------
227
+ dimension : int
228
+ The dimension of the output embedding. Must be an even number.
229
+ freqs : int
230
+ The number of frequencies to use for the Fourier embedding.
231
+ increment_time : float, optional
232
+ The time increment to scale the time dimension. Default is 0.1.
233
+ margin : float, optional
234
+ The margin to add to the position coordinates to avoid boundary issues. Default is 0.4.
235
+
236
+ """
237
+
238
+ def __init__(
239
+ self, dimension: int, freqs: int, increment_time=0.1, margin: float = 0.4
240
+ ):
241
  super().__init__()
242
  self.dimension = dimension
243
  self.freqs = freqs
244
  self.increment_time = increment_time
245
  self.margin = margin
246
 
247
+ def forward(self, positions_: torch.Tensor) -> torch.Tensor:
248
  positions = positions_.clone()
249
+ positions[:, :, -1] *= self.increment_time
250
  input_shape = positions.shape
251
  batch_dims = list(input_shape[:-1])
252
 
 
261
  p_z = 2 * math.pi * freqs_z / width
262
  p_w = 2 * math.pi * freqs_w / width
263
  positions = positions[..., None, None, None, None, :]
264
+ loc = (
265
+ positions[..., 0] * p_x
266
+ + positions[..., 1] * p_y
267
+ + positions[..., 2] * p_z
268
+ + positions[..., 3] * p_w
269
+ )
270
  batch_dims.append(-1)
271
  loc = loc.view(batch_dims)
272
 
273
  half_dim = self.dimension // 2
274
  current_dim = loc.shape[-1]
 
 
275
  if current_dim != half_dim:
276
  if current_dim > half_dim:
277
  loc = loc[..., :half_dim]
278
  else:
279
  raise ValueError(
280
  f"Input dimension ({current_dim}) is too small for target "
281
+ f"embedding dimension ({self.dimension}). Expected at least {half_dim}."
282
  )
283
 
284
  emb = torch.cat([torch.cos(loc), torch.sin(loc)], dim=-1)
285
  return emb
286
 
287
+ @classmethod
288
+ def add_time_patch(cls, pos: torch.Tensor, num_patches: int) -> torch.Tensor:
289
+ """
290
+ Expand the position tensor by adding a time dimension, handling batched data.
291
+
292
+ Parameters
293
+ ----------
294
+ pos : torch.Tensor
295
+ Input tensor of shape (B, C, 3), where B is the batch size,
296
+ C is the number of channels, and 3 represents x, y, z.
297
+ num_patches : int
298
+ The number of time patches.
299
+
300
+ Returns
301
+ -------
302
+ torch.Tensor
303
+ Output tensor of shape (B, C * num_patches, 4), where each position is repeated with each time value.
304
+ """
305
+ batch, nchans, _ = pos.shape
306
+ # Repeat each position for each time step
307
+ pos_repeated = pos.unsqueeze(2).repeat(
308
+ 1, 1, num_patches, 1
309
+ ) # Shape: (batch, nchans, num_patches, 3)
310
+ # Generate time values with the specified increment
311
+ time_values = torch.arange(
312
+ 0, num_patches, 1, device=pos.device
313
+ ).float() # Shape: (num_patches,)
314
+ time_values = time_values.view(1, 1, num_patches, 1).expand(
315
+ batch, nchans, num_patches, 1
316
+ ) # (batch, nchans, num_patches, 1)
317
+ # Concatenate the repeated positions with the time values along the last dimension
318
+ pos_with_time = torch.cat(
319
+ (pos_repeated, time_values), dim=-1
320
+ ) # Shape: (batch, nchans, num_patches, 4)
321
+ # Reshape to (batch, nchans * num_patches, 4)
322
+ pos_with_time = pos_with_time.view(batch, nchans * num_patches, 4)
323
+
324
+ return pos_with_time
325
+
326
 
327
  def patch_embedding(embed_dim, patch_size):
328
  to_patch_embedding = nn.Sequential(nn.Linear(patch_size, embed_dim))