Spaces:
Sleeping
Sleeping
File size: 3,835 Bytes
c7544bc 38fc399 c7544bc 509fadc c7544bc 38fc399 c7544bc 251c397 bfc5dfe c7544bc 38fc399 c7544bc 38fc399 c7544bc 251c397 c7544bc | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | # Import required libraries
import numpy as np
import matplotlib.pyplot as plt
import streamlit as st
import sympy as sp
# Pre-defined functions and their derivatives
def square(x):
return x**2
def derivative_square(x):
return 2*x
def cube(x):
return x**3
def derivative_cube(x):
return 3 * x**2
def sin(x):
return np.sin(x)
def derivative_sin(x):
return np.cos(x)
def inverse(x):
return 1/x
def derivative_inverse(x):
return - (1 / x **2)
def poly(x):
return x + 2 * (x**2) + (0.4) * x**3
def derivative_poly(x):
return 1 + 4 * x + 1.2 * x**2
# Function to calculate the derivative using SymPy
def calculate_derivative(func_str):
x = sp.symbols('x')
try:
# Parse the function string into a sympy expression
func = sp.sympify(func_str)
# Calculate the derivative
derivative = sp.diff(func, x)
func_lambdified = sp.lambdify(x, func, "numpy")
derivative_lambdified = sp.lambdify(x, derivative, "numpy")
return func_lambdified, derivative_lambdified
except sp.SympifyError:
st.error("Invalid function input. Please enter a valid mathematical expression.")
return None, None
# Title
st.title('Gradient Descent Visualizer')
st.sidebar.title("It's your turn..")
# User input
function = st.sidebar.selectbox('Pre Defined Functions', ['Square', 'Cube', 'Polynomial', 'sin', '1/x', 'None'])
starting_point = st.sidebar.number_input('Starting Point', value=5, step=1)
learning_rate = st.sidebar.number_input('Learning Rate', value=0.1, step=0.01)
# Define the selected function and its derivative
if function == 'Square':
func = square
derivative_func = derivative_square
elif function == 'Cube':
func = cube
derivative_func = derivative_cube
elif function == 'Polynomial':
func = poly
derivative_func = derivative_poly
elif function == 'sin':
func = sin
derivative_func = derivative_sin
elif function == '1/x':
func = inverse
derivative_func = derivative_inverse
elif function == 'None':
user_func = st.sidebar.text_input("Enter a function (in terms of x): ")
func, derivative_func = calculate_derivative(user_func)
if func is None:
st.stop()
# Check if the starting point has changed
if 'last_starting_point' not in st.session_state or st.session_state.last_starting_point != starting_point:
st.session_state.path = [starting_point]
st.session_state.iteration = 0
st.session_state.last_starting_point = starting_point
# Perform one iteration of gradient descent
if st.sidebar.button('Next Iteration'):
current_point = st.session_state.path[-1]
new_point = current_point - learning_rate * derivative_func(current_point)
st.session_state.path.append(new_point)
st.session_state.iteration += 1
# Create an array of values for plotting
x_values = np.linspace(-10, 10, 500)
y_values = func(x_values)
# Dynamic scaling based on the function's range
y_min, y_max = np.min(y_values), np.max(y_values)
y_padding = (y_max - y_min) * 0.1
# Plot the function and the path of points
plt.figure(figsize=(8, 6))
plt.plot(x_values, y_values, label=function, color='blue')
plt.scatter(st.session_state.path, [func(x) for x in st.session_state.path], color='red', zorder=5)
# Calculate and plot the tangent line
current_point = st.session_state.path[-1]
slope = derivative_func(current_point)
y_tangent = slope * (x_values - current_point) + func(current_point)
plt.plot(x_values, y_tangent, '--', color='red')
# Set plot limits dynamically
plt.xlim([-10, 10])
plt.ylim([y_min - y_padding, y_max + y_padding])
# Display the iteration number
plt.title(f'Iteration: {st.session_state.iteration}')
# Labels and legend
plt.xlabel('x')
plt.ylabel('f(x)')
plt.legend()
plt.grid(True)
# Display the plot
st.pyplot(plt)
|