(tensor, mean=0.0, std=1.0, a=-2.0, b=2.0)
| 254 | |
| 255 | # The trunc_normal_ implemention is referenced from https://github.com/pytorch/pytorch/blob/master/torch/nn/init.py#L22 |
| 256 | def trunc_normal_(tensor, mean=0.0, std=1.0, a=-2.0, b=2.0): |
| 257 | # Method based on https://people.sc.fsu.edu/~jburkardt/presentations/truncated_normal.pdf |
| 258 | def norm_cdf(x): |
| 259 | # Computes standard normal cumulative distribution function |
| 260 | return (1.0 + math.erf(x / math.sqrt(2.0))) / 2.0 |
| 261 | |
| 262 | if (mean < a - 2 * std) or (mean > b + 2 * std): |
| 263 | warnings.warn( |
| 264 | "mean is more than 2 std from [a, b] in nn.init.trunc_normal_. " |
| 265 | "The distribution of values may be incorrect.", |
| 266 | stacklevel=2, |
| 267 | ) |
| 268 | |
| 269 | with flow.no_grad(): |
| 270 | # Values are generated by using a truncated uniform distribution and |
| 271 | # then using the inverse CDF for the normal distribution. |
| 272 | # Get upper and lower cdf values |
| 273 | l = norm_cdf((a - mean) / std) |
| 274 | u = norm_cdf((b - mean) / std) |
| 275 | |
| 276 | # Uniformly fill tensor with values from [l, u], then translate to |
| 277 | # [2l-1, 2u-1]. |
| 278 | tensor.uniform_(2 * l - 1, 2 * u - 1) |
| 279 | |
| 280 | # Use inverse cdf transform for normal distribution to get truncated |
| 281 | # standard normal |
| 282 | tensor.erfinv_() |
| 283 | |
| 284 | # Transform to proper mean, std |
| 285 | tensor.mul_(std * math.sqrt(2.0)) |
| 286 | tensor.add_(mean) |
| 287 | |
| 288 | # Clamp to ensure it's in the proper range |
| 289 | tensor.clamp_(min=a, max=b) |
| 290 | return tensor |
| 291 | |
| 292 | |
| 293 | def constant_(tensor, val): |
no test coverage detected