Mpavan45 commited on
Commit
f3ec8f2
·
verified ·
1 Parent(s): bcde049

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +127 -64
app.py CHANGED
@@ -1,66 +1,129 @@
1
- import numpy as np
2
- import seaborn as sns
3
- import matplotlib.pyplot as plt
4
  import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- # Function definition
7
- def loss_function(x):
8
- return x**2
9
-
10
- # Gradient of the loss function
11
- def gradient(x):
12
- return 2 * x
13
-
14
- # Gradient descent algorithm
15
- def gradient_descent(starting_point, learning_rate, iterations):
16
- x_values = [starting_point]
17
- for _ in range(iterations):
18
- gradient_value = gradient(x_values[-1])
19
- new_x = x_values[-1] - learning_rate * gradient_value
20
- x_values.append(new_x)
21
- return x_values
22
-
23
- # Streamlit layout
24
- st.title("Gradient Descent Visualization using Seaborn")
25
-
26
- # Sidebar inputs
27
- st.sidebar.header("Parameters")
28
- starting_point = st.sidebar.slider("Starting Point", -10.0, 10.0, 5.0, 0.1)
29
- learning_rate = st.sidebar.slider("Learning Rate", 0.01, 1.0, 0.1, 0.01)
30
- iterations = st.sidebar.slider("Number of Iterations", 1, 50, 10, 1)
31
-
32
- # Perform gradient descent
33
- x_values = gradient_descent(starting_point, learning_rate, iterations)
34
- y_values = [loss_function(x) for x in x_values]
35
-
36
- # Generate plot using Seaborn
37
- sns.set(style="whitegrid")
38
- fig, ax = plt.subplots(figsize=(8, 5))
39
- x_range = np.linspace(-10, 10, 500)
40
- y_range = loss_function(x_range)
41
-
42
- # Plot the loss function
43
- sns.lineplot(x=x_range, y=y_range, ax=ax, label="Loss Function", color="blue")
44
- # Plot gradient descent steps
45
- sns.scatterplot(x=x_values, y=y_values, ax=ax, color="red", label="Gradient Steps", zorder=5)
46
- sns.lineplot(x=x_values, y=y_values, ax=ax, color="orange", linestyle="--", label="Path")
47
-
48
- # Annotate points
49
- for i, (x, y) in enumerate(zip(x_values, y_values)):
50
- ax.text(x, y, f"{i}", fontsize=8, ha="right")
51
-
52
- ax.set_title("Gradient Descent")
53
- ax.set_xlabel("x")
54
- ax.set_ylabel("Loss")
55
- ax.legend()
56
-
57
- # Display in Streamlit
58
- st.pyplot(fig)
59
-
60
- # Display final results
61
- st.write("### Gradient Descent Results")
62
- st.write(f"**Starting Point:** {starting_point}")
63
- st.write(f"**Learning Rate:** {learning_rate}")
64
- st.write(f"**Number of Iterations:** {iterations}")
65
- st.write(f"**Final x Value:** {x_values[-1]:.4f}")
66
- st.write(f"**Final Loss Value:** {loss_function(x_values[-1]):.4f}")
 
 
 
 
1
  import streamlit as st
2
+ import numpy as np
3
+ import plotly.graph_objects as go
4
+
5
+ # Title of the app
6
+ st.title("Interactive Gradient Descent Visualizer")
7
+ st.markdown("---") # Horizontal separator for cleaner layout
8
+
9
+ # Safe function evaluation
10
+ def evaluate_function(expression, x_value):
11
+ """Safely evaluates the mathematical function."""
12
+ allowed_names = {"x": x_value, "np": np} # Allow only x and numpy
13
+ return eval(expression, {"_builtins_": None}, allowed_names)
14
+
15
+ # Compute derivative using finite difference
16
+ def compute_derivative(expression, x_value, h=1e-5):
17
+ """Numerically calculates the derivative at a given point."""
18
+ return (evaluate_function(expression, x_value + h) - evaluate_function(expression, x_value - h)) / (2 * h)
19
+
20
+ # Tangent line calculation
21
+ def calculate_tangent(expression, x_value, x_range):
22
+ """Generates the tangent line for a given point."""
23
+ y_value = evaluate_function(expression, x_value)
24
+ slope = compute_derivative(expression, x_value)
25
+ return slope * (x_range - x_value) + y_value
26
+
27
+ # Reset state
28
+ def reset_session_state():
29
+ st.session_state.x_current = st.session_state.initial_point
30
+ st.session_state.iter_count = 0
31
+ st.session_state.x_points = [st.session_state.initial_point]
32
+ st.session_state.y_points = [evaluate_function(st.session_state.math_function, st.session_state.initial_point)]
33
+
34
+ # Input section for function
35
+ st.header("Input Your Function")
36
+ st.markdown("Define a mathematical function (e.g., `x**2`, `np.sin(x)`, `x**3 - 3*x + 2`):")
37
+ function_input = st.text_input("Enter Function:", "x**2 + x", key="math_function", on_change=reset_session_state)
38
+ st.markdown("---")
39
+
40
+ # Gradient descent parameters
41
+ st.header("Set Parameters for Gradient Descent")
42
+ st.markdown("Configure the starting point and learning rate:")
43
+ col1, col2 = st.columns(2)
44
+ with col1:
45
+ initial_point = st.number_input(
46
+ "Initial Value of x", value=4.0, step=0.1, format="%.2f", key="initial_point", on_change=reset_session_state
47
+ )
48
+ with col2:
49
+ learning_rate = st.number_input(
50
+ "Learning Rate", value=0.1, step=0.01, format="%.2f", key="learning_rate", on_change=reset_session_state
51
+ )
52
+ st.markdown("---")
53
+
54
+ # Initialize session state
55
+ if "x_current" not in st.session_state:
56
+ st.session_state.x_current = initial_point
57
+ st.session_state.iter_count = 0
58
+ st.session_state.x_points = [initial_point]
59
+ st.session_state.y_points = [evaluate_function(function_input, initial_point)]
60
+
61
+ # Gradient Descent Step
62
+ if st.button("Perform Gradient Descent Step", type="primary"):
63
+ try:
64
+ gradient = compute_derivative(function_input, st.session_state.x_current)
65
+ st.session_state.x_current -= learning_rate * gradient
66
+ st.session_state.iter_count += 1
67
+ st.session_state.x_points.append(st.session_state.x_current)
68
+ st.session_state.y_points.append(evaluate_function(function_input, st.session_state.x_current))
69
+ except Exception as e:
70
+ st.error(f"Error: {str(e)}")
71
+
72
+ # Display the progress
73
+ st.subheader("Gradient Descent Updates")
74
+ st.markdown(f"**Iteration:** {st.session_state.iter_count}")
75
+ st.markdown(f"**Current x Value:** {st.session_state.x_current:.4f}")
76
+ st.markdown(f"**Current Function Value (f(x)):** {st.session_state.y_points[-1]:.4f}")
77
+ st.markdown("---")
78
+
79
+ # Generate plot data
80
+ x_vals = np.linspace(-10, 10, 400)
81
+ y_vals = [evaluate_function(function_input, x) for x in x_vals]
82
+
83
+ # Create the plot
84
+ plot = go.Figure()
85
+
86
+ # Add function plot
87
+ plot.add_trace(
88
+ go.Scatter(x=x_vals, y=y_vals, mode="lines", line=dict(color="green", width=3), name="Function Curve")
89
+ )
90
+
91
+ # Add gradient descent points
92
+ plot.add_trace(
93
+ go.Scatter(
94
+ x=st.session_state.x_points,
95
+ y=st.session_state.y_points,
96
+ mode="markers",
97
+ marker=dict(color="red", size=10, symbol="diamond"),
98
+ name="Descent Steps",
99
+ )
100
+ )
101
+
102
+ # Add tangent line
103
+ current_x = st.session_state.x_current
104
+ current_y = evaluate_function(function_input, current_x)
105
+ slope = compute_derivative(function_input, current_x)
106
+ tangent_x = np.linspace(current_x - 2, current_x + 2, 100)
107
+ tangent_y = calculate_tangent(function_input, current_x, tangent_x)
108
+
109
+ plot.add_trace(
110
+ go.Scatter(
111
+ x=tangent_x,
112
+ y=tangent_y,
113
+ mode="lines",
114
+ line=dict(color="blue", width=2, dash="dash"),
115
+ name="Tangent Line",
116
+ )
117
+ )
118
+
119
+ # Update plot layout
120
+ plot.update_layout(
121
+ title="Interactive Gradient Descent with Tangent Visualization",
122
+ xaxis_title="x",
123
+ yaxis_title="f(x)",
124
+ template="plotly_dark",
125
+ legend=dict(bgcolor="rgba(255,255,255,0.5)", bordercolor="gray", borderwidth=1),
126
+ )
127
 
128
+ # Display the plot
129
+ st.plotly_chart(plot)