Spaces:
Sleeping
Sleeping
Download src/plot2eq/data_utils/augmentation.py from YauheniShe/Plot2Eq: direct link, hf CLI and curl.
- Browser
- Download file 4.01 kB
-
https://huggingface.co/spaces/YauheniShe/Plot2Eq/resolve/main/src/plot2eq/data_utils/augmentation.py
- Command line
-
hf download hf://spaces/YauheniShe/Plot2Eq/src/plot2eq/data_utils/augmentation.py
-
curl -L -o augmentation.py https://huggingface.co/spaces/YauheniShe/Plot2Eq/resolve/main/src/plot2eq/data_utils/augmentation.py
4.01 kB
| import torch | |
| import torch.nn.functional as F | |
| class HandDrawnAugmentation: | |
| def __init__(self, max_drift_scale=0.05, max_wobble_scale=0.01, p=0.8): | |
| """ | |
| :param max_drift_scale: Максимальное плавное искажение | |
| :param max_wobble_scale: Максимальные мелкие неровности | |
| :param p: Вероятность применения аугментации (иногда полезно видеть идеальные данные) | |
| """ | |
| self.max_drift_scale = max_drift_scale | |
| self.max_wobble_scale = max_wobble_scale | |
| self.p = p | |
| def __call__(self, points: torch.Tensor) -> torch.Tensor: | |
| if torch.rand(1).item() > self.p: | |
| return points | |
| y = points[0:1, :].clone() | |
| mask = points[1:2, :].clone() | |
| seq_len = y.size(1) | |
| device = y.device | |
| min_strength = 0.5 | |
| drift_strength = ( | |
| torch.empty(1, device=device).uniform_(min_strength, 1.0).item() | |
| ) | |
| wobble_strength = ( | |
| torch.empty(1, device=device).uniform_(min_strength, 1.0).item() | |
| ) | |
| current_drift = self.max_drift_scale * drift_strength | |
| current_wobble = self.max_wobble_scale * wobble_strength | |
| drift_freq = torch.randint(2, 6, (1,)).item() | |
| wobble_freq = torch.randint(10, 30, (1,)).item() | |
| low_freq_noise = torch.randn(1, 1, 1, drift_freq, device=device) # type: ignore | |
| drift = F.interpolate( | |
| low_freq_noise, size=(1, seq_len), mode="bicubic", align_corners=True | |
| ).view(1, seq_len) | |
| mid_freq_noise = torch.randn(1, 1, 1, wobble_freq, device=device) # type: ignore | |
| wobble = F.interpolate( | |
| mid_freq_noise, size=(1, seq_len), mode="bicubic", align_corners=True | |
| ).view(1, seq_len) | |
| total_distortion = (drift * current_drift) + (wobble * current_wobble) | |
| y = y + total_distortion * mask | |
| x_freq = torch.randint(5, 15, (1,)).item() | |
| x_noise = torch.randn(1, 1, 1, x_freq, device=device) # type: ignore | |
| x_drift = F.interpolate( | |
| x_noise, size=(1, seq_len), mode="bicubic", align_corners=True | |
| ).view(seq_len) | |
| envelope = F.interpolate( | |
| torch.rand(1, 1, 1, 3, device=device), | |
| size=(1, seq_len), | |
| mode="bicubic", | |
| align_corners=True, | |
| ).view(seq_len) | |
| x_drift = x_drift * envelope | |
| x_shift_amplitude = torch.rand(1, device=device).item() * 3.0 + 1.0 | |
| new_indices = ( | |
| torch.arange(seq_len, device=device).float() + x_drift * x_shift_amplitude | |
| ) | |
| new_indices = torch.clamp(new_indices, 0, seq_len - 1) | |
| idx_floor = new_indices.long() | |
| idx_ceil = torch.clamp(idx_floor + 1, 0, seq_len - 1) | |
| weight = new_indices - idx_floor.float() | |
| mask_floor = mask[:, idx_floor] | |
| mask_ceil = mask[:, idx_ceil] | |
| valid_transition = mask_floor * mask_ceil | |
| idx_nearest = torch.round(new_indices).long() | |
| y_nearest = y[:, idx_nearest] | |
| y_interp = y[:, idx_floor] * (1.0 - weight) + y[:, idx_ceil] * weight | |
| y = torch.where(valid_transition == 1.0, y_interp, y_nearest) | |
| mask = mask[:, idx_nearest] | |
| if torch.rand(1).item() > 0.5: | |
| shear_factor = (torch.rand(1, device=device) - 0.5) * 0.1 | |
| tiling = torch.linspace(-1, 1, seq_len, device=device) * shear_factor | |
| y = y + tiling * mask | |
| y_valid_mask = mask.bool().squeeze(0) | |
| if y_valid_mask.any(): | |
| y_valid_points = y[0, y_valid_mask] | |
| min_val = torch.min(y_valid_points) | |
| max_val = torch.max(y_valid_points) | |
| if max_val > min_val: | |
| y[0, y_valid_mask] = (y[0, y_valid_mask] - min_val) / ( | |
| max_val - min_val | |
| ) | |
| else: | |
| y[0, y_valid_mask] = 0.5 | |
| return torch.cat((y, mask), dim=0) | |