Comparison is moved to : https://datastoriesweb.wordpress.com/2018/03/11/iterative-method-for-unconstrained-optimization/
Tag gradient descent
Negative sampling in word2vec
In the precious post we talked about skipgram model.
https://datastoriesweb.wordpress.com/2018/01/31/word2vec-and-skip-gram-model/
Now let’s say we have 1000 words and 300 hidden units, we shall have 300,000 wights in both hidden and output unit, which are two many parameters.
Output label during training is one hot vector with 999 zeros and single 1. We randomly select 5 zeros and update weight for six words only. (5 zeros and single 1). The more frequent word is the highr the probability of it getting selected. Google paper has mentioned some emperical formula for this. This is know as negative sampling.
Above was for output layer. In hidden layer weights are updated only for input words. (Irrespective if it is negative sampling or not)
Reference:
http://mccormickml.com/2017/01/11/word2vec-tutorial-part-2-negative-sampling/
Derivation of backpropogation
Quick Summary:

Detailed Derivation:
Even if you look at gradient descent below, error is multiplied by previous value. When input is higher it’s contribution to error is higher and will needs to change more.

import numpy as np# 1. Activation and Loss Functionsdef relu(x): return np.maximum(0, x)def relu_derivative(x): return (x > 0).astype(float)def softmax_and_cross_entropy_loss(logits, y_true): """ Computes stable softmax and categorical cross-entropy loss together. logits: (batch_size, num_classes) y_true: (batch_size, num_classes) - One-hot encoded labels """ # Log-Sum-Exp trick for numerical stability shifted_logits = logits - np.max(logits, axis=1, keepdims=True) exps = np.exp(shifted_logits) softmax_probs = exps / np.sum(exps, axis=1, keepdims=True) # Compute Cross-Entropy Loss batch_size = logits.shape[0] # Add a tiny epsilon to prevent log(0) loss = -np.sum(y_true * np.log(softmax_probs + 1e-15)) / batch_size # The gradient of loss with respect to logits simplifies beautifully to: (probs - target) d_logits = (softmax_probs - y_true) / batch_size return loss, d_logits# 2. Network Initializationnp.random.seed(42) # For reproducible resultsinput_dim = 3 # e.g., 3 featureshidden_dim = 4 # 4 neurons in the hidden layeroutput_dim = 2 # 2 classes (Binary/Multiclass)# Xavier/Glorot Initialization for weightsW1 = np.random.randn(input_dim, hidden_dim) * np.sqrt(2.0 / input_dim)b1 = np.zeros((1, hidden_dim))W2 = np.random.randn(hidden_dim, output_dim) * np.sqrt(2.0 / hidden_dim)b2 = np.zeros((1, output_dim))# Dummy Training Data (Batch of 2 samples)X = np.array([[0.5, -0.2, 0.1], [0.1, 0.8, -0.5]])# One-hot encoded true targetsY = np.array([[1.0, 0.0], # Class 0 is correct [0.0, 1.0]]) # Class 1 is correctlearning_rate = 0.1# 3. Training Iteration (Forward & Backward Pass)for epoch in range(3): # --- FORWARD PASS --- # Hidden Layer z1 = np.dot(X, W1) + b1 a1 = relu(z1) # Output Layer (Generates Raw Logits) logits = np.dot(a1, W2) + b2 # Compute Loss and the gradient at the final layer loss, d_logits = softmax_and_cross_entropy_loss(logits, Y) # --- BACKWARD PASS (Backpropagation) --- # Gradients for Output Layer weights and biases dW2 = np.dot(a1.T, d_logits) db2 = np.sum(d_logits, axis=0, keepdims=True) # Gradient flowing back into the hidden layer da1 = np.dot(d_logits, W2.T) dz1 = da1 * relu_derivative(z1) # Backprop through ReLU # Gradients for Hidden Layer weights and biases dW1 = np.dot(X.T, dz1) db1 = np.sum(dz1, axis=0, keepdims=True) # --- GRADIENT DESCENT --- W2 -= learning_rate * dW2 b2 -= learning_rate * db2 W1 -= learning_rate * dW1 b1 -= learning_rate * db1 print(f"Epoch {epoch+1} - Loss: {loss:.4f} | Raw Logits Sample 1: {logits[0]}")
