AdarshKorada/Gradient_Descent_Visualizer
0
1# Import required libraries2import numpy as np3import matplotlib.pyplot as plt4import streamlit as st5import sympy as sp6 7# Pre-defined functions and their derivatives8def square(x): 9 return x**210 11def derivative_square(x):12 return 2*x13 14def cube(x): 15 return x**316 17def derivative_cube(x):18 return 3 * x**219 20def sin(x):21 return np.sin(x)22 23def derivative_sin(x):24 return np.cos(x)25 26def inverse(x):27 return 1/x28 29def derivative_inverse(x):30 return - (1 / x **2)31 32def poly(x):33 return x + 2 * (x**2) + (0.4) * x**334 35def derivative_poly(x):36 return 1 + 4 * x + 1.2 * x**237 38# Function to calculate the derivative using SymPy39def calculate_derivative(func_str):40 x = sp.symbols('x')41 try:42 # Parse the function string into a sympy expression43 func = sp.sympify(func_str)44 # Calculate the derivative45 derivative = sp.diff(func, x) 46 func_lambdified = sp.lambdify(x, func, "numpy")47 derivative_lambdified = sp.lambdify(x, derivative, "numpy")48 return func_lambdified, derivative_lambdified49 except sp.SympifyError:50 st.error("Invalid function input. Please enter a valid mathematical expression.")51 return None, None52 53# Title54st.title('Gradient Descent Visualizer')55st.sidebar.title("It's your turn..")56 57# User input58function = st.sidebar.selectbox('Pre Defined Functions', ['Square', 'Cube', 'Polynomial', 'sin', '1/x', 'None'])59starting_point = st.sidebar.number_input('Starting Point', value=5, step=1)60learning_rate = st.sidebar.number_input('Learning Rate', value=0.1, step=0.01)61 62# Define the selected function and its derivative63if function == 'Square':64 func = square65 derivative_func = derivative_square66elif function == 'Cube':67 func = cube68 derivative_func = derivative_cube69elif function == 'Polynomial':70 func = poly71 derivative_func = derivative_poly72elif function == 'sin':73 func = sin74 derivative_func = derivative_sin75elif function == '1/x':76 func = inverse77 derivative_func = derivative_inverse78elif function == 'None':79 user_func = st.sidebar.text_input("Enter a function (in terms of x): ")80 func, derivative_func = calculate_derivative(user_func)81 if func is None:82 st.stop()83 84# Check if the starting point has changed85if 'last_starting_point' not in st.session_state or st.session_state.last_starting_point != starting_point:86 st.session_state.path = [starting_point]87 st.session_state.iteration = 0 88 st.session_state.last_starting_point = starting_point 89 90# Perform one iteration of gradient descent91if st.sidebar.button('Next Iteration'):92 current_point = st.session_state.path[-1]93 new_point = current_point - learning_rate * derivative_func(current_point)94 st.session_state.path.append(new_point)95 st.session_state.iteration += 1 96 97# Create an array of values for plotting98x_values = np.linspace(-10, 10, 500)99y_values = func(x_values)100 101# Dynamic scaling based on the function's range102y_min, y_max = np.min(y_values), np.max(y_values)103y_padding = (y_max - y_min) * 0.1104 105# Plot the function and the path of points106plt.figure(figsize=(8, 6))107plt.plot(x_values, y_values, label=function, color='blue')108plt.scatter(st.session_state.path, [func(x) for x in st.session_state.path], color='red', zorder=5)109 110# Calculate and plot the tangent line111current_point = st.session_state.path[-1]112slope = derivative_func(current_point)113y_tangent = slope * (x_values - current_point) + func(current_point)114plt.plot(x_values, y_tangent, '--', color='red')115 116# Set plot limits dynamically117plt.xlim([-10, 10])118plt.ylim([y_min - y_padding, y_max + y_padding])119 120# Display the iteration number121plt.title(f'Iteration: {st.session_state.iteration}')122 123# Labels and legend124plt.xlabel('x')125plt.ylabel('f(x)')126plt.legend()127plt.grid(True)128 129# Display the plot130st.pyplot(plt)