rk803/gradient_app
0
1import streamlit as st2import numpy as np3import plotly.graph_objects as go4 5# Title of the app6st.title("Gradient Descent Visualizer with Tangent Lines")7st.markdown(8 """9 This app visualizes the **Gradient Descent Algorithm**. 10 Use the sidebar to define your function, starting point, and learning rate. 11 Click "Next Iteration" to see the algorithm in action.12 """13)14 15# Safe function evaluation16def safe_eval(func_str, x_val):17 """Safely evaluates the function at a given x value."""18 try:19 allowed_names = {"x": x_val, "np": np} # Only allow x and numpy20 return eval(func_str, {"__builtins__": None}, allowed_names)21 except Exception as e:22 st.error(f"Error in function evaluation: {e}")23 raise24 25# Function derivative using finite difference method26def derivative(func_str, x_val, h=1e-5):27 """Numerically compute the derivative of the function at x using finite differences."""28 try:29 return (safe_eval(func_str, x_val + h) - safe_eval(func_str, x_val - h)) / (2 * h)30 except Exception as e:31 st.error(f"Error in derivative computation: {e}")32 raise33 34# Tangent Line Equation35def tangent_line(func_str, x_val, x_range):36 """Compute the tangent line at a given x value."""37 y_val = safe_eval(func_str, x_val)38 slope = derivative(func_str, x_val)39 return slope * (x_range - x_val) + y_val40 41# Initialize session state variables42def initialize_state(func_str, starting_point):43 """Initialize or reset session state variables."""44 try:45 st.session_state.x = starting_point46 st.session_state.iteration = 047 st.session_state.x_vals = [starting_point]48 st.session_state.y_vals = [safe_eval(func_str, starting_point)]49 except Exception as e:50 st.error(f"Initialization error: {e}")51 raise52 53# Sidebar: Function input54st.sidebar.header("Gradient Descent Settings")55func_input = st.sidebar.text_input(56 "Function (use 'x' as the variable):",57 value="x**2 + x",58 key="func_input"59)60 61# Sidebar: Starting point and learning rate62starting_point = st.sidebar.number_input(63 "Starting Point:",64 value=4.0,65 step=0.1,66 format="%.2f",67 key="starting_point"68)69learning_rate = st.sidebar.number_input(70 "Learning Rate:",71 value=0.1,72 step=0.00001,73 format="%.5f",74 key="learning_rate"75)76 77# Reset button78if st.sidebar.button("Reset Gradient Descent"):79 initialize_state(func_input, starting_point)80 81# Initialize session state on first load82if "x" not in st.session_state:83 initialize_state(func_input, starting_point)84 85# Sidebar: Perform next iteration86if st.sidebar.button("Next Iteration"):87 try:88 grad = derivative(func_input, st.session_state.x)89 st.session_state.x -= learning_rate * grad90 st.session_state.iteration += 191 st.session_state.x_vals.append(st.session_state.x)92 st.session_state.y_vals.append(safe_eval(func_input, st.session_state.x))93 except Exception as e:94 st.error(f"Error during iteration: {e}")95 96# Sidebar: Display gradient descent progress97st.sidebar.subheader("Progress")98st.sidebar.write(f"Iteration: {st.session_state.iteration}")99st.sidebar.write(f"Current x: {st.session_state.x:.4f}")100st.sidebar.write(f"Current f(x): {st.session_state.y_vals[-1]:.4f}")101progress = st.sidebar.progress(st.session_state.iteration % 100 / 100)102 103# Main area: Plot function, points, and tangent line104try:105 x_plot = np.linspace(-10, 10, 400)106 y_plot = [safe_eval(func_input, x) for x in x_plot]107 108 fig = go.Figure()109 110 # Function curve111 fig.add_trace(go.Scatter(x=x_plot, y=y_plot, mode="lines", name="Function"))112 113 # Gradient descent points114 fig.add_trace(go.Scatter(115 x=st.session_state.x_vals,116 y=st.session_state.y_vals,117 mode="markers",118 marker=dict(color="red", size=8),119 name="Gradient Descent Points"120 ))121 122 # Tangent line123 current_x = st.session_state.x124 tangent_x = np.linspace(current_x - 2, current_x + 2, 100)125 tangent_y = tangent_line(func_input, current_x, tangent_x)126 127 fig.add_trace(go.Scatter(128 x=tangent_x,129 y=tangent_y,130 mode="lines",131 line=dict(color="orange", width=3),132 name="Tangent Line"133 ))134 135 # Update layout136 fig.update_layout(137 xaxis_title="x",138 yaxis_title="f(x)",139 title="Gradient Descent Visualization",140 template="plotly_white"141 )142 143 st.plotly_chart(fig)144 145except Exception as e:146 st.error(f"Error during plotting: {e}")147 