diff --git a/implementations.py b/implementations.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e56919120763b0ea7cc6700b81b48935db633b8f 100644 --- a/implementations.py +++ b/implementations.py @@ -0,0 +1,124 @@ +import numpy as np +### HELPERS : added by quartztz +def compute_loss_mse(y, tx, w): + e = (y - tx @ w) + N = tx.shape[0] + return 1/(2*N) * (e @ e) + +def compute_gradient_mse(y, tx, w): + """ + Computes the gradient of the MSE loss function. + Args: + y: ground truth (N, ) + tx: data (N, D) + w: weights (D, ) + Returns: + grad: gradient of the loss function (D, ) + """ + e = y - tx @ w + N = tx.shape[0] + return -1/N * (tx.T @ e) + +def compute_gradient_mse_stoch(y, tx, w): + """ + Computes the gradient of the MSE loss function. + Args: + y: ground truth (N, ) + tx: data (N, D) + w: weights (D, ) + Returns: + grad: gradient of the loss function (D, ) + """ + e = y - tx @ w + N = tx.shape[0] + return -1/N * (tx.T * e) + +def softmax(tx, w): + return np.exp(tx @ w) / np.sum(np.exp(tx @ w)) + +def compute_loss_logistic(y, tx, w): + return -np.sum(y.T @ np.log(softmax(tx, w))) + +def compute_gradient_logistic(y, tx, w): + return tx.T @ (softmax(tx, w) - y) + +def mean_squared_error_gd(y, tx, initial_w, max_iters, gamma): + # performs the gradient descent on ground data tx, y. + # computes the step w <- w - gamma * grad, where grad is the gradient computed + # from the given data using the mean squared loss function. + w = initial_w + for _ in range(max_iters): + grad = compute_gradient_mse(y, tx, w) + w = w - gamma * grad + loss = compute_loss_mse(y, tx, w) + return w, loss + +def mean_squared_error_sgd(y, tx, initial_w, max_iters, gamma): + ''' + Performs the stochastic gradient descent on ground data tx, y. + Args: + y: ground truth (N, ) + tx: data (N, D) + initial_w: initial weights (D, ) + max_iters: maximum number of iterations (int) + gamma: learning rate (scalar) + Returns: + w: weights (D, ) + loss: loss (scalar) + ''' + w = initial_w + for _ in range(max_iters): + idx = np.random.randint(len(y)) + m_y = y[idx] + m_tx = tx[idx] + grad = compute_gradient_mse_stoch(m_y, m_tx, w) + w = w - gamma * grad + loss = compute_loss_mse(y, tx, w) + return w, loss + +def least_squares(y, tx): + a = tx.T @ tx + b = tx.T @ y + w = np.linalg.solve(a, b) + loss = compute_loss_mse(y, tx, w) + return w, loss + +def ridge_regression(y, tx, lambda_): + ''' + Performs ridge regression on the given data. + Args: + y: ground truth (N, ) + tx: data (N, D) + lambda_: regularization parameter (scalar) + Returns: + w: weights (D, ) + loss: loss (scalar) + ''' + N, d = tx.shape[0], tx.shape[1] + a = tx.T @ tx + 2 * N * lambda_ * np.eye(d) + b = tx.T @ y + w = np.linalg.solve(a, b) + loss = compute_loss_mse(y, tx, w) + return w, loss + +def logistic_regression(y, tx, initial_w, max_iters, gamma): + # performs the logistic regression on ground data tx, y. + # computes the step w <- w - gamma * grad, where grad is the gradient computed + # from the given data using the logistic loss function. + w = initial_w + for _ in range(max_iters): + grad = compute_gradient_logistic(y, tx, w) + w = w - gamma * grad + loss = compute_loss_logistic(y, tx, w) + return w, loss + +def reg_logistic_regression(y, tx, lambda_, initial_w, max_iters, gamma): + # performs the regularized logistic regression on ground data tx, y. + # computes the step w <- w - gamma * grad, where grad is the gradient computed + # from the given data using the regularized logistic loss function. + w = initial_w + for _ in range(max_iters): + grad = compute_gradient_logistic(y, tx, w) + 2 * lambda_ * w + w = w - gamma * grad + loss = compute_loss_logistic(y, tx, w) + return w, loss \ No newline at end of file