• Home
  • Help
  • Register
  • Login
  • Home
  • Members
  • Help
  • Search

How does the He initialization method work

#1
06-27-2025, 09:23 AM
So, you ever notice how when you slap together a deep neural net, the thing just refuses to learn properly right from the start? I mean, those weights start off all wrong, and bam, your gradients either fizzle out to nothing or blow up like fireworks. That's where He initialization comes in, something I picked up messing around with ReLU activations back in my early projects. You know, it keeps the signal flowing nicely through all those layers without dying off or spiking wildly. And honestly, once you get it, you'll wonder why you ever bothered with the old ways.

Let me walk you through it like we're chatting over coffee. Picture this: you're building a network, and each layer multiplies the input by some weights. If those weights are too big, the outputs explode as you go deeper. Too small, and everything shrinks to zero. I tried uniform random numbers once, like between -1 and 1, and my net trained like a snail. But He fixes that by scaling things just right for nonlinearities like ReLU. You see, ReLU zeros out half the stuff, so you need to compensate by making the variance a bit larger upfront.

Here's the gist. He init draws weights from a normal distribution, mean zero, and variance set to two over the number of input units to that layer. Or sometimes uniform between negative and positive sqrt of six over that fan-in number. I lean toward the normal one myself; it feels smoother in practice. Why two, though? Because ReLU kills the negative parts, so the output variance halves compared to linear activations. To keep the forward pass variance around one, you double it in the init. Makes sense, right? You can tweak it for other activations, but for ReLU, this keeps things balanced.

And don't forget the backward pass. Gradients flow back the same way, so you want variance preserved there too. He thinks about both directions, unlike some older methods that only worry about forward. I remember tweaking a conv net for images, and without this, the deeper layers barely budged during training. You slap He on, and suddenly, every layer contributes. It's like giving your net a steady heartbeat instead of erratic pulses.

Now, fan-in means the number of neurons feeding into the current one, right? For a fully connected layer, that's the previous layer's size. In conv layers, it's the kernel size times channels times whatever. I always calculate it carefully; mess that up, and you're back to square one. You might hear about fan-out too, which is the output side. Some folks average them or pick based on the pass, but He sticks to fan-in for simplicity. Works great for most feedforward stuff I throw at it.

But wait, how does it play with batch norm or other tricks? I use it all the time with those, and it still shines. Batch norm stabilizes things, but good init gets you converging faster from the get-go. You know, in my last experiment with a ResNet variant, He init shaved off epochs like nothing else. Without it, even with norm, the early gradients wobbled too much. So yeah, layer it on top of your architecture choices.

Or think about Xavier init, the one before He. That came from Glorot, aimed at sigmoids and tanh, where variance is one over fan-in plus fan-out or something. It assumes symmetric activations that keep full variance. But ReLU chops that in half, so Xavier makes things too small, and gradients vanish quicker in deep nets. I switched to He when I went all-ReLU, and boom, training stabilized. You should try comparing them on a simple MLP; the difference jumps out after a few runs.

Hmmm, let's get into why the math shakes out that way. Suppose your input has variance one. Weights initialized with variance sigma squared. For linear, output variance is fan-in times sigma squared. To keep it one, sigma squared equals one over fan-in. But ReLU squares the variance for the positive part and zeros the negative, so effective variance drops to half. Thus, you set sigma squared to two over fan-in to counteract. I derived it once on a napkin during a hackathon; felt like a lightbulb moment. You can do the same for backward: gradients multiply by the same weights, so it holds.

And for uniform distribution? Instead of normal, you sample from minus sqrt of six over fan-in to plus that. Why six? Because for uniform between -a and a, variance is a squared over three. Set that to two over fan-in, solve for a, get sqrt six over fan-in. I flip between normal and uniform depending on the framework; PyTorch defaults to something like that. But normal feels less prone to outliers in my experience. You pick what vibes with your data.

Now, in practice, how do you apply it? Most libraries have it built-in, like torch.nn.init.kaiming_normal_ or whatever. You call it on your weight tensors after defining the layer. I always do it right after model creation, before any training loop. For recurrent nets, it's trickier because of the time dimension, but He adapts by considering the input size properly. You know, LSTMs benefit too, though they have their own gates messing with flows.

But what if your net has skip connections or residuals? He still works wonders there. In fact, those architectures rely on stable init to propagate gradients across skips. I built a wide residual net once, and without careful init, the shortcuts overwhelmed everything. He kept it even. You can even adjust the constant if your activation differs, like for Leaky ReLU, it's two over one minus leak squared or something. But stick to defaults first; overthinking kills momentum.

Or consider pretrained models. When you fine-tune, do you reinitialize? Sometimes yes, for new layers. I add a classifier on top of a frozen backbone and He-init the new weights to match the scale. Prevents mismatch shocks. You ever run into domain shifts? Good init helps adaptation without retraining everything.

And let's talk edge cases. Super deep nets, like over 100 layers. He prevents explosion better than random, but you might need orthogonal init for even more stability. I pushed a net to 200 layers once, pure curiosity, and He got me halfway before I added extras. For sparse nets, it scales down variance accordingly. You know, sparsity changes fan-in effectively.

Hmmm, or batch sizes. Small batches amplify noise, so solid init cuts variance in loss early on. I train on GPUs with tiny batches for speed, and He keeps things from diverging randomly. Without it, you'd babysit learning rates forever.

But yeah, the beauty is its simplicity. No need for fancy heuristics per layer. Just set once, train away. I teach this to juniors now, and they light up when results improve overnight. You will too, next time your model stalls.

Now, extending to other domains. In GANs, He init on the generator keeps modes from collapsing early. I tinkered with StyleGAN, and proper init smoothed the latent space mappings. For discriminators, it helps gradients not vanish on real fakes. You know how unstable those are; init saves headaches.

Or reinforcement learning nets. Policy and value functions benefit from He to handle high-dimensional states. I used it in a DQN clone, and exploration stabilized faster. Without, Q-values exploded on rewards.

And vision transformers? Those attention layers act like big fan-ins. He init on the projections keeps self-attention from diluting signals. I fine-tuned ViT on custom data, and it converged clean.

But wait, does it work for all optimizers? Yeah, pairs great with Adam or SGD. Adam's adaptive steps shine more with balanced gradients. I stick to SGD with momentum for big models; He makes it reliable.

Or custom activations. If you brew your own nonlinearity, compute the variance factor based on its output stats. He provides the framework; you adapt. I once made a swish variant and adjusted to 1. something over fan-in. Felt empowering.

Hmmm, and testing it out. Build a toy net, train with and without. Plot the activations per layer; they should hover around zero mean, unit variance. I do that diagnostic often. You spot issues quick.

Now, in code-wait, no need to write it, but imagine: after model = Net(), then for each module, init.apply(he_normal). Done. Frameworks handle the fan-in calc. Saves time.

But pitfalls? Forgetting to init biases; set them to zero usually. Or mixing inits across layers; consistency matters. I learned that the hard way on a mismatched net.

And scaling to huge models. In distributed training, He keeps sync across devices. I ran on clusters, and it held.

Or low-precision floats. He works, but watch for underflow in tiny variances. Bump the scale if needed.

Yeah, that's the core of it. He initialization just ensures your net starts with a fair shot, signals propagating without drama. I swear by it now.

Oh, and speaking of reliable setups that keep things running smooth without constant tweaks, check out BackupChain-it's that top-tier, go-to backup tool tailored for self-hosted setups, private clouds, and online storage, perfect for small businesses handling Windows Server, Hyper-V clusters, Windows 11 rigs, and everyday PCs, all without forcing you into endless subscriptions, and we really appreciate them backing this space so we can drop knowledge like this for free.

ron74
Offline
Joined: Feb 2019
« Next Oldest | Next Newest »

Users browsing this thread: 1 Guest(s)



  • Subscribe to this thread
Forum Jump:

Café Papa Café Papa Forum Software IT v
« Previous 1 … 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 … 106 Next »
How does the He initialization method work

© by Savas Papadopoulos. The information provided here is for entertainment purposes only. Contact. Hosting provided by FastNeuron.

Linear Mode
Threaded Mode