jiehou commited on
Commit
3b146d8
·
1 Parent(s): aa6ce78

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +250 -0
app.py ADDED
@@ -0,0 +1,250 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### CSCI 4750/5750: regression models
2
+
3
+
4
+ import gradio as gr
5
+ import matplotlib
6
+ import matplotlib.pyplot as plt
7
+ import numpy as np
8
+ from sklearn.linear_model import LinearRegression
9
+
10
+ def cal_mse(X,y,b,w):
11
+ thetas = np.array([[b], [w]])
12
+ X_b = np.c_[np.ones((len(X), 1)), X] # add x0 = 1 to each instance
13
+ y_predict = X_b.dot(thetas)
14
+ mse = np.mean((y_predict-y)**2)
15
+ return mse
16
+
17
+ def gradient_descent(n_samples=100, intercept=4, slope=3, intercept_random=4, slope_random=3, gradient_descent='False', gradient_descent_type = 'Batch GradientDescent' , learning_rate= 0.01, iteration=100):
18
+ ### (1) generate simulated data points
19
+ X = 2 * np.random.rand(n_samples, 1)
20
+ y = intercept + slope * X + np.random.randn(n_samples, 1)
21
+
22
+ ### (2) fit regression model
23
+ lin_reg = LinearRegression()
24
+ lin_reg.fit(X, y)
25
+
26
+ ### (3) make a prediction on training data
27
+ y_predict = lin_reg.predict(X)
28
+ y_predict
29
+
30
+ ### (4) Draw baseline linear Line
31
+ fig = plt.figure(figsize=(12,18))
32
+
33
+ plt.subplot(3,1,1)
34
+ plt.plot(X, y_predict, "r-", linewidth=2, label = "Line of best fit")
35
+ plt.plot(X, y, "b.")
36
+
37
+
38
+ ### (4.2) Draw random line
39
+ if intercept_random != intercept or slope_random != slope: #avoid overlap
40
+ X_new = np.array([[0], [2]])
41
+ X_new_b = np.c_[np.ones((2, 1)), X_new] # add x0 = 1 to each instance
42
+ y_predict = X_new_b.dot(np.array([intercept_random, slope_random]))
43
+ plt.plot(X_new, y_predict, "g-", linewidth=2, label = "Random line")
44
+
45
+
46
+ ### (4.3) Apply gradient desc
47
+ if gradient_descent:
48
+ b = intercept_random
49
+ w = slope_random
50
+
51
+ lr = learning_rate # learning rate
52
+ iteration = iteration
53
+
54
+ if gradient_descent_type == 'Batch GradientDescent':
55
+ # Store initial values for plotting.
56
+ b_history = [b]
57
+ w_history = [w]
58
+
59
+ train_mse = []
60
+ # Iterations
61
+ for i in range(iteration):
62
+ b_grad = 0.0
63
+ w_grad = 0.0
64
+ for n in range(len(X)):
65
+ b_grad = b_grad - 2*(y[n,0] - b - w*X[n,0])*1.0
66
+ w_grad = w_grad - 2*(y[n,0] - b - w*X[n,0])*X[n,0]
67
+ b_grad /= len(X)
68
+ w_grad /= len(X)
69
+
70
+ # Update parameters.
71
+ b = b - lr * b_grad
72
+ w = w - lr * w_grad
73
+
74
+ # Store parameters for plotting
75
+ b_history.append(b)
76
+ w_history.append(w)
77
+
78
+ train_mse.append(cal_mse(X,y,b,w))
79
+ elif gradient_descent_type == 'Stochastic GradientDescent':
80
+ # Store initial values for plotting.
81
+ b_history = [b]
82
+ w_history = [w]
83
+
84
+ train_mse = []
85
+ # Iterations
86
+ for i in range(iteration):
87
+ for n in range(len(X)):
88
+ random_index = np.random.randint(len(X))
89
+ b_grad = -2*(y[random_index,0] - b - w*X[random_index,0])*1.0
90
+ w_grad = -2*(y[random_index,0] - b - w*X[random_index,0])*X[random_index,0]
91
+
92
+ # Update parameters.
93
+ b = b - lr * b_grad
94
+ w = w - lr * w_grad
95
+
96
+ # Store parameters for plotting
97
+ b_history.append(b)
98
+ w_history.append(w)
99
+
100
+ train_mse.append(cal_mse(X,y,b,w))
101
+ if gradient_descent_type == 'Mini-Batch GradientDescent':
102
+ # Store initial values for plotting.
103
+ b_history = [b]
104
+ w_history = [w]
105
+
106
+ train_mse = []
107
+ # Iterations
108
+ minibatch_size = 32
109
+ for i in range(iteration):
110
+ # shuffle dataset
111
+ shuffled_indices = np.random.permutation(len(X))
112
+ X_b_shuffled = X[shuffled_indices]
113
+ y_shuffled = y[shuffled_indices]
114
+ for b in range(0, len(X), minibatch_size):
115
+ X_mini = X_b_shuffled[b:b+minibatch_size]
116
+ y_mini = y_shuffled[b:b+minibatch_size]
117
+
118
+ b_grad = 0.0
119
+ w_grad = 0.0
120
+ for n in range(len(X_mini)):
121
+ b_grad = b_grad - 2*(y_mini[n,0] - b - w*X_mini[n,0])*1.0
122
+ w_grad = w_grad - 2*(y_mini[n,0] - b - w*X_mini[n,0])*X_mini[n,0]
123
+ b_grad /= len(X_mini)
124
+ w_grad /= len(X_mini)
125
+
126
+ # Update parameters.
127
+ b = b - lr * b_grad
128
+ w = w - lr * w_grad
129
+
130
+ # Store parameters for plotting
131
+ b_history.append(b)
132
+ w_history.append(w)
133
+
134
+ train_mse.append(cal_mse(X,y,b,w))
135
+
136
+ plt.xlabel("$x_1$", fontsize=22)
137
+ plt.ylabel("$y$", rotation=0, fontsize=22)
138
+ plt.xticks(fontsize=18)
139
+ plt.yticks(fontsize=18)
140
+ plt.axis([np.min(X)*0.1, np.max(X)*1.1, np.min(y)*0.1, np.max(y)*1.1])
141
+ plt.title("Linear Regression model predictions", fontsize=22)
142
+ plt.legend(fontsize=18)
143
+ plt.xlim(0,2)
144
+ plt.ylim(-10,10)
145
+
146
+
147
+
148
+
149
+
150
+ ### (5) Visualize loss function
151
+ plt.subplot(3,1,2)
152
+
153
+ ### (5.1) generate grid of parameters
154
+ b = np.arange(-10,10,0.1) #bias
155
+ w = np.arange(-10,10,0.1) #weight
156
+
157
+ ### (5.2) Calculate MSE over parameters
158
+ Z = np.zeros((len(w), len(b)))
159
+
160
+ for i in range(len(w)):
161
+ for j in range(len(b)):
162
+ w0 = w[i]
163
+ b0 = b[j]
164
+ Z[i][j] = cal_mse(X, y, b0, w0)
165
+
166
+
167
+ ### (5.3) Get optimal parameters
168
+ theta0_best = lin_reg.intercept_[0]
169
+ theta1_best = lin_reg.coef_[0][0]
170
+
171
+
172
+ ### (5.4) Draw the contour graph
173
+ plt.contourf(b,w,Z, 50, alpha=0.5, cmap=plt.get_cmap('jet'))
174
+
175
+ ### (5.5) Add optimal loss
176
+ plt.plot(theta0_best, theta1_best, 'x', ms=12, markeredgewidth=3, color='orange')
177
+ plt.text(theta0_best, theta1_best,'MSE:'+str(np.round(cal_mse(X,y,theta0_best, theta1_best),2)), color='red', fontsize=22)
178
+
179
+
180
+ ### (5.6) Add loss of random lines
181
+ if intercept_random != intercept or slope_random != slope: #avoid overlap
182
+ plt.plot(intercept_random, slope_random, 'o', ms=5, markeredgewidth=3, color='orange')
183
+ plt.text(intercept_random, slope_random,'MSE:'+str(np.round(cal_mse(X,y,intercept_random, slope_random),2)), fontsize=22)
184
+
185
+ ### (5.7) draw gradient updates
186
+ if gradient_descent:
187
+ plt.plot(b_history, w_history, 'o-', ms=3, lw=1.5, color='black')
188
+ plt.title("Visualization of Gradient Descent Process ("+gradient_descent_type+")", fontsize=22)
189
+ else:
190
+ plt.title("Visualization of Loss Function Map", fontsize=22)
191
+ else:
192
+ plt.title("Visualization of Loss Function Map", fontsize=22)
193
+ plt.xlabel("$Intercept$", fontsize=22)
194
+ plt.ylabel("$Slope$", rotation=0, fontsize=22)
195
+ plt.xticks(fontsize=18)
196
+ plt.yticks(fontsize=18)
197
+ plt.xlim(-10,10)
198
+ plt.ylim(-10,10)
199
+
200
+
201
+ ### 6. Visualize the learning curves
202
+ if gradient_descent:
203
+ plt.subplot(3,1,3)
204
+ plt.plot(train_mse,label="train_loss (lr="+str(learning_rate)+")")
205
+ plt.xlabel('Iteration',fontweight="bold",fontsize = 22)
206
+ plt.ylabel('Loss',fontweight="bold",fontsize = 22)
207
+ plt.title("Learning curve: Loss VS Epochs",fontweight="bold",fontsize = 22)
208
+ plt.legend(fontsize=18)
209
+ plt.xticks(fontsize=18)
210
+ plt.yticks(fontsize=18)
211
+
212
+ #plt.show()
213
+ fig.tight_layout()
214
+ plt.savefig('plot_line.png', dpi=300)
215
+ return 'plot_line.png'
216
+
217
+
218
+ #### Define input component
219
+ input_sample = gr.inputs.Slider(1, 100000, step=50, default=100, label='N samples')
220
+ input_intercept = gr.inputs.Slider(1, 8, step=0.5, default=4, label='(Baseline) Intercept')
221
+ input_slope = gr.inputs.Slider(-8, 8, step=0.5, default=2.8, label='(Baseline) Slope')
222
+
223
+ input_intercept_random = gr.inputs.Slider(-8, 8, step=0.5, default=-7.5, label='(Random) Intercept')
224
+ input_slope_random = gr.inputs.Slider(-8, 8, step=0.5, default=-4.5, label='(Random) Slope')
225
+
226
+ input_gradients = gr.inputs.Checkbox(label="Apply Gradient Descent")
227
+ #input_gradients_type = gr.inputs.CheckboxGroup(['Batch GradientDescient', 'Stochastic GradientDescent', 'Mini-Batch GradientDescent'],label="Type of Gradient Descent")
228
+ input_gradients_type = gr.inputs.Dropdown(['Batch GradientDescent', 'Stochastic GradientDescent', 'Mini-Batch GradientDescent'],label="Type of Gradient Descent")
229
+
230
+ input_learningrate = gr.inputs.Slider(0,2, step=0.0001, default=0.001, label='Learning Rate')
231
+ input_interation = gr.inputs.Slider(1, 1000, step=2, default=100, label='Iteration')
232
+
233
+
234
+ #### Define output component
235
+ output_plot1 = gr.outputs.Image(label="Regression plot")
236
+
237
+
238
+ ### configure gradio, detailed can be found at https://www.gradio.app/docs/#i_slider
239
+ interface = gr.Interface(fn=gradient_descent,
240
+ inputs=[input_sample, input_intercept, input_slope, input_intercept_random, input_slope_random, input_gradients, input_gradients_type, input_learningrate, input_interation],
241
+ outputs=[output_plot1],
242
+ examples_per_page = 2,
243
+ #examples = [[4, 3, -7, -5, True, 0.0001, 100], [1, 2, -7, -8, False, 0.0001, 100]],
244
+ title="CSCI4750/5750: Regression models (Batch/Mini-Batch/Stochastic Gradient Descent)",
245
+ description= "Click examples to generate random dataset and select gradient descent parameters",
246
+ theme = 'huggingface',
247
+ layout = 'vertical'
248
+ )
249
+
250
+ interface.launch(debug=True)