Spaces:
Sleeping
Sleeping
| ## CHOOSE BETWEEN ALTAIR & MATPLOTLIB | |
| import gradio as gr | |
| import altair as alt | |
| import numpy as np | |
| import pandas as pd | |
| import matplotlib.pyplot as plt | |
| import time | |
| def make_plot(plot_type, a, epoch, progress=gr.Progress()): | |
| if plot_type == "log": | |
| return logReg(a=a, epoch=epoch, progress=progress) | |
| elif plot_type == "lin": | |
| return linReg(a=a,epoch=epoch, progress=progress) | |
| # a = learning rate | |
| # epoch = number of training iterations | |
| def logReg(a, epoch, progress): | |
| #### generate random data-set #### | |
| progress(0.2, desc="Generating Data") | |
| time.sleep(1) | |
| #np.random.seed(0) # set random seed (optional) | |
| ## set mean and covariance of our datasets | |
| mean1 = [20,35] | |
| cov1 = [[100,100],[-100,100]] | |
| mean2 = [60,70] | |
| cov2 = [[100,100],[100,-100]] | |
| ## concatenate values to set x values for datasets | |
| x1, x2 = np.random.multivariate_normal(mean1, cov1, 100).T | |
| x_1, x_2 = np.random.multivariate_normal(mean2, cov2, 100).T | |
| x1 = (np.concatenate((x1, x_1), axis=0))/10 | |
| x2 = (np.concatenate((x2, x_2), axis=0))/10 | |
| ## set y values of datasets | |
| y1 = np.zeros(100) # y[0:100] is zero dataset (dataset we want our decision boundary to be above) | |
| y2 = np.ones(100) # y[101:200] is one dataset (dataset we want our decision boundary to be below) | |
| y = np.concatenate((y1, y2), axis=0) # combine datasets into one term | |
| w = np.matrix([(np.random.rand())/100,(np.random.rand())+0.0001/100]) # begin weights at random starting point | |
| b = np.matrix([np.random.rand()]) # begin bias term at random starting point | |
| wb = np.concatenate((b, w), axis=1) # combine w and b into one weight term | |
| print('f = b + x1*w1 + x2*w2') | |
| print('Starting weights:', 'f = ', wb[0,0],'+ x1', wb[0,1], '+ x2' , wb[0,2]) | |
| loss = np.empty([epoch]) # term to store all loss terms for plotting | |
| iterat = np.empty([epoch]) # term to store all epoch numbers to be plotted vs loss | |
| for n in range (epoch): | |
| iterat[n] = n | |
| progress(0.5, desc="Finding Loss & Regression") | |
| time.sleep(1.5) | |
| for p in range (epoch): | |
| L, J = np.matrix([[0.0, 0.0, 0.0]]), 0.0 # reset gradient (∂J(w)/∂w) and loss for each epoch | |
| #### Code the equations to solve for the loss and to update | |
| #### the weights and biases for each epoch below. | |
| #### Hint: you will need to use the for loop below to create a summation to solve | |
| #### for wb and J (loss) for each epoch. xj has been given as a starting point. | |
| for i in range(len(x1)): | |
| xj = np.matrix([1,x1[i],x2[i]]) | |
| # y_hat = (y_hat or h_w(x) expression) | |
| y_hat = 1 / (1 + np.exp(-(wb * xj.T))) | |
| # J = (cost function, also referred to as L) | |
| J = -((y[i] * np.log(y_hat)) + ((1 - y[i])*np.log(1 - y_hat))) | |
| # d_J = (∂J(w)/∂w function, equation can be solved with information on slide 27) | |
| d_J = ((y_hat) - y[i]) * xj | |
| # wb = (weight updating equation) | |
| wb = wb - a * (d_J) | |
| loss[p] = J | |
| if ((p % 100) == 0): | |
| print('loss:', J,' Gradient (∂J(w)/∂w) [[b, w1, w2]]:',L[0]) | |
| print('Updated weights:', 'f = ', wb[0,0],'+ x1', wb[0,1], '+ x2' , wb[0,2]) | |
| equation = "f = {w1} + {w2}x1 + {w3}x2".format(w1 = wb[0,0], w2 = wb[0,1], w3 = wb[0,2]) | |
| ## Plot decision boundary and data | |
| progress(0.8, desc="Plotting Data") | |
| time.sleep(1.5) | |
| scatterData1 = pd.DataFrame({'x': x1[1:100], | |
| 'y': x2[1:100]}) | |
| scatterFig1 = alt.Chart(scatterData1).mark_point().encode( | |
| x='x:Q', | |
| y='y:Q' | |
| ).properties( | |
| title="Decision Boundary" | |
| ) | |
| scatterData2 = pd.DataFrame({'x': x1[101:200], | |
| 'y': x2[101:200]}) | |
| scatterFig2 = alt.Chart(scatterData2).mark_point(color='green').encode( | |
| x='x:Q', | |
| y='y:Q', | |
| ).properties( | |
| title="Decision Boundary" | |
| ) | |
| y2 = np.array(np.array(-(x1*wb[0,1] + wb[0,0])/wb[0,2],dtype=float)) | |
| trendLine = pd.DataFrame({'x': x1.flatten(), | |
| 'y': y2.flatten() }) | |
| trendLineFig = alt.Chart(trendLine).mark_line().encode( | |
| x='x:Q', | |
| y='y:Q' | |
| ).properties( | |
| title="Decision Boundary" | |
| ) | |
| finalFig = scatterFig1 + scatterFig2 + trendLineFig | |
| lossData = pd.DataFrame({'Number of Iterations': iterat[100:], | |
| 'Loss Value': loss[100:] }) | |
| lossFig = alt.Chart(lossData).mark_line().encode( | |
| x='Number of Iterations:Q', | |
| y='Loss Value:Q' | |
| ).properties( | |
| title='Plot of loss values over number of iterations' | |
| ) | |
| plt.close() | |
| plt.figure() | |
| plt.plot(x1[1:100],x2[1:100],'x', x1[101:200], x2[101:200],'x') # plot random data points | |
| plt.plot(x1, -(x1*wb[0,1] + wb[0,0])/wb[0,2] , linestyle = 'solid') # plot decision boundary | |
| plt.axis('equal') | |
| plt.xlabel('x1') | |
| plt.ylabel('x2') | |
| plt.title('Decision Boundary') | |
| plt.savefig("plt1.png") | |
| ## Plot training loss v epoch | |
| plt.figure() | |
| plt.plot(iterat[100:],loss[100:],'x') | |
| plt.xlabel('Epoch') | |
| plt.ylabel('Loss') | |
| plt.title('Training Loss v Epoch') | |
| plt.savefig("plt2.png") | |
| return [finalFig.interactive(),lossFig.interactive(),"plt1.png","plt2.png",str(loss[len(loss)-1]),str(equation)] | |
| # a = learning rate step size | |
| # epoch = number of training iterations | |
| def linReg(a, epoch, progress): | |
| # generate random data-set | |
| progress(0.2, desc="Generating Data") | |
| time.sleep(1) | |
| # np.random.seed(0) # choose random seed (optional) | |
| x = np.random.rand(100, 1) | |
| y = 2 + 3 * x + np.random.rand(100, 1) | |
| # J = 0 # initialize J, this can be deleted once J is defined in the loop | |
| w = np.matrix([np.random.rand(),np.random.rand()]) # slope and y-intercept | |
| ite = epoch # number of training iterations | |
| jList = [] | |
| numIte = [] | |
| # Write Linear Regression Code to Solve for w (slope and y-intercept) Here ## | |
| progress(0.5, desc="Finding Loss & Regression") | |
| time.sleep(1.5) | |
| for p in range (ite): | |
| for i in range(len(x)): | |
| # Calculate w and J here | |
| x_vec = np.matrix([x[i][0],1]) # Option 1 | Setting up a vector for x (x_vec[j] corresponds to w[j]) | |
| h = w * x_vec.T ## Hint: you may need to transpose x or w by adding .T to the end of the variable | |
| w = w - a * (h - y[i]) * x_vec | |
| J = (1/2) * (((h - y[i])) ** 2) | |
| J = J.item() | |
| jList.append(J) | |
| numIte.append(p) | |
| print('Loss:', J) | |
| ## if done correctly the line should be in line with the data points ## | |
| print('f = ', w[0,0],'x + ', w[0,1]) | |
| equation = "f = {w1}x + {w2}".format(w1 = w[0,0], w2 = w[0,1]) | |
| progress(0.8, desc="Plotting Data") | |
| time.sleep(1.5) | |
| y2 = np.array(np.array((w[0,1]+(w[0,0] * x)),dtype=float)).T | |
| scatterData = pd.DataFrame({'x': x.flatten(), | |
| 'y': y.flatten()}) | |
| scatterFig = alt.Chart(scatterData).mark_point().encode( | |
| x='x:Q', | |
| y='y:Q' | |
| ).properties( | |
| title='Plot of random data values with linear regression line' | |
| ) | |
| trendLine = pd.DataFrame({'x': x.flatten(), | |
| 'y': y2.flatten() }) | |
| trendLineFig = alt.Chart(trendLine).mark_line().encode( | |
| x='x:Q', | |
| y='y:Q' | |
| ) | |
| finalFig = scatterFig + trendLineFig | |
| lossData = pd.DataFrame({'Number of Iterations': range(1,len(jList)+1), | |
| 'Loss Value': jList }) | |
| lossFig = alt.Chart(lossData).mark_line().encode( | |
| x='Number of Iterations:Q', | |
| y='Loss Value:Q' | |
| ).properties( | |
| title='Plot of loss values over number of iterations' | |
| ) | |
| # plot | |
| plt.close() | |
| plt.figure() | |
| plt.scatter(x,y,s=ite) | |
| plt.plot(x, w[0,1] + (w[0,0] * x), linestyle='solid') | |
| plt.xlabel('x') | |
| plt.ylabel('y') | |
| plt.title('Plot of random data values with linear regression line') | |
| plt.savefig("plt1.png") | |
| plt.figure() | |
| plt.plot(jList) | |
| plt.xlabel('Number of Iterations') | |
| plt.ylabel('Loss Value') | |
| plt.title('Plot of loss values over number of iterations') | |
| plt.savefig("plt2.png") | |
| return [finalFig.interactive(),lossFig.interactive(),"plt1.png","plt2.png",str(jList[len(jList)-1]),str(equation)] | |
| with gr.Blocks(title="Regression Visualization") as demo: | |
| gr.Markdown( | |
| """ | |
| # Regression Visualization for Machine Learning | |
| Choose your variables below to create a linear or logistic regression model! | |
| """) | |
| with gr.Row(): | |
| pack = gr.Radio(label="Plot Package",info="Choose 'MatPlot' for MatPlotLib, Choose 'Altair' for Altair", | |
| choices=['MatPlot','Altair'], value='Altair') | |
| bType = gr.Radio(label="Regression Type",info="Choose 'log' for logistic, Choose 'lin' for linear", | |
| choices=['log','lin'], value='log') | |
| l_rate = gr.Number(value=0.01,label="Learning Rate",info="Enter a value in the range 0.0 - 1.0") | |
| epochs = gr.Number(value=100,label="Number of Epochs (Number of Training Iterations)",info="Enter an integer larger than 0",precision=0) | |
| bStart = gr.Button(value="Start") | |
| with gr.Row() as alt_row: | |
| altPlot1 = gr.Plot() | |
| altPlot2 = gr.Plot() | |
| with gr.Row(visible=False) as mat_row: | |
| matPlot1 = gr.Image(type='filepath',label="Regression Graph",height=600,width=600) | |
| matPlot2 = gr.Image(type='filepath',label="Regression Graph",height=600,width=600) | |
| loss = gr.Textbox(label="Final Loss Value") | |
| equ = gr.Textbox(label="Equation for Plotted Line") | |
| def changeComp(package): | |
| if package == "Altair": | |
| return { | |
| alt_row: gr.Row.update(visible=True), | |
| mat_row: gr.Row.update(visible=False) | |
| } | |
| else: | |
| return { | |
| alt_row: gr.Row.update(visible=False), | |
| mat_row: gr.Row.update(visible=True) | |
| } | |
| pack.input(changeComp, show_progress=True, inputs=[pack], outputs=[alt_row, mat_row]) | |
| bStart.click(make_plot, show_progress=True, inputs=[bType,l_rate,epochs], outputs=[altPlot1,altPlot2, matPlot1, matPlot2, loss, equ]) | |
| demo.load() | |
| if __name__== "__main__" : | |
| demo.queue().launch() |