update
This commit is contained in:
parent
9d6006c9a6
commit
9b4039d95f
|
@ -12,72 +12,39 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": null,
|
||||
"id": "0a5c51d2-8b18-4143-b6f1-73a909ccb623",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "70a42b75bdbf466faf21e0cebc36f929",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"VBox(children=(HBox(children=(VBox(children=(Text(value='x**3 - x**(1/2)', description='Expression:', style=Te…"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "d694d1ca0515436ba380b3c1987752c2",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Output()"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "350dce1753724cddbc0c5d5c883a451b",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Output()"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"gd1 = gradient_descent_1d(environ=\"jupyterlab\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"execution_count": null,
|
||||
"id": "15c6e757-cde3-422b-be7e-3f55b7752142",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"gd2 = gradient_descent_2d(environ=\"jupyterlab\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "694b7e27-cc21-44f4-9a89-7a6b97725a64",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "ee383167ceff45b7818279fdfbeb9535",
|
||||
"model_id": "08df46f6a3b54543a15dd79d71c334bc",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"VBox(children=(HBox(children=(Dropdown(index=2, options=(('(sin(x1) - 2) + (sin(x2) - 2) ** 2', '(sin(x1) - 2)…"
|
||||
"VBox(children=(Text(value='(sin(x1) - 2) ** 2 + (sin(x2) - 2) ** 2', description='Expression:'), Text(value='(…"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
|
@ -86,21 +53,7 @@
|
|||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "5325cc88a8fa46ffb92b466701a2b8b1",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Output()"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "d76a192e28344ae99821b441b0c74b75",
|
||||
"model_id": "ee2bc3a3c2b843aeae594ece6e02596e",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
|
@ -113,13 +66,36 @@
|
|||
}
|
||||
],
|
||||
"source": [
|
||||
"gd2 = gradient_descent_2d(environ=\"jupyterlab\")"
|
||||
"gd2_race = gradient_descent_2d_race(environ=\"jupyterlab\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "5a2aec3f-e47b-44ab-b3da-2275578e9636",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[array([-4., -4.]),\n",
|
||||
" array([-1.2519118 , 0.90778485]),\n",
|
||||
" array([-2.02500166, 2.8935338 ])]"
|
||||
]
|
||||
},
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"gd2_race.df_list_p1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "52862bf7-6db4-45bc-b963-b140b84795ef",
|
||||
"id": "b89040ec-4318-419b-95eb-60320f146877",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
|
|
|
@ -100,120 +100,6 @@ class gradient_descent_1d(object):
|
|||
fig.update_layout(updatemenus=[dict(type="buttons",buttons=[dict(label="Play",method="animate",args=[None])])])
|
||||
fig.show()
|
||||
|
||||
|
||||
class gradient_descent_2d_custom(object):
|
||||
def __init__(self, environ:str="jupyterlab"):
|
||||
pio.renderers.default = environ # 'notebook' or 'colab' or 'jupyterlab'
|
||||
|
||||
self.wg_expr = widgets.Text(value="(sin(x1) - 2) ** 2 + (sin(x2) - 2) ** 2",
|
||||
description="Expression:") #style={'description_width': 'initial'})
|
||||
self.wg_x0 = widgets.Text(value="5,5",
|
||||
description="Startpoint:")
|
||||
self.wg_lr = widgets.FloatText(value="1e-1",
|
||||
description="step size:")
|
||||
self.wg_epsilon = widgets.FloatText(value="1e-5",
|
||||
description="criterion:")
|
||||
self.wg_max_iter = widgets.IntText(value="1000",
|
||||
description="max iteration")
|
||||
self.button_compute = widgets.Button(description="Compute")
|
||||
self.button_plot = widgets.Button(description="Plot")
|
||||
|
||||
self.compute_output = widgets.Output()
|
||||
self.plot_output = widgets.Output()
|
||||
self.params_lvbox = widgets.VBox([self.wg_expr, self.wg_x0, self.wg_lr])
|
||||
self.params_rvbox = widgets.VBox([self.wg_epsilon, self.wg_max_iter])
|
||||
self.params_box = widgets.HBox([self.params_lvbox, self.params_rvbox], description="Parameters")
|
||||
self.button_box = widgets.HBox([self.button_compute, self.button_plot], description="operations")
|
||||
self.config = widgets.VBox([self.params_box, self.button_box])
|
||||
self.initialization()
|
||||
|
||||
def initialization(self):
|
||||
display(self.config)
|
||||
self.button_compute.on_click(self.compute)
|
||||
display(self.compute_output)
|
||||
self.button_plot.on_click(self.plot)
|
||||
display(self.plot_output)
|
||||
|
||||
def compute(self, *args):
|
||||
with self.compute_output:
|
||||
x0 = np.array(self.wg_x0.value.split(","), dtype=float)
|
||||
xn = x0
|
||||
x1 = symbols("x1")
|
||||
x2 = symbols("x2")
|
||||
expr = sympify(self.wg_expr.value)
|
||||
self.xn_list, self.df_list = [], []
|
||||
for n in tqdm(range(0, self.wg_max_iter.value)):
|
||||
gradient = np.array([diff(expr, x1).subs(x1, xn[0]).subs(x2, xn[1]),
|
||||
diff(expr, x2).subs(x1, xn[0]).subs(x2, xn[1])], dtype=float)
|
||||
self.xn_list.append(xn)
|
||||
self.df_list.append(gradient)
|
||||
if np.linalg.norm(gradient, ord=2) < self.wg_epsilon.value:
|
||||
clear_output(wait=True)
|
||||
print("Found solution of {} after".format(expr), n, "iterations")
|
||||
print("x* = [{}, {}]".format(xn[0], xn[1]))
|
||||
return None
|
||||
xn = xn - self.wg_lr.value * gradient
|
||||
clear_output(wait=True)
|
||||
display("Exceeded maximum iterations. No solution found.")
|
||||
return None
|
||||
|
||||
def plot(self, *args):
|
||||
with self.plot_output:
|
||||
clear_output(wait=True)
|
||||
x0 = np.array(self.wg_x0.value.split(","), dtype=float)
|
||||
x1 = symbols("x1")
|
||||
x2 = symbols("x2")
|
||||
expr = sympify(self.wg_expr.value)
|
||||
xx1 = np.arange(np.array(self.xn_list)[:, 0].min()*0.5, np.array(self.xn_list)[:, 0].max()*1.5, 0.05)
|
||||
xx2 = np.arange(np.array(self.xn_list)[:, 1].min()*0.5, np.array(self.xn_list)[:, 1].max()*1.5, 0.05)
|
||||
xx1, xx2 = np.meshgrid(xx1, xx2)
|
||||
|
||||
f = lambdify((x1, x2), expr, "numpy")
|
||||
fx = f(xx1, xx2)
|
||||
f_xn = f(np.array(self.xn_list)[:, 0], np.array(self.xn_list)[:, 1])
|
||||
|
||||
frames, steps = [], []
|
||||
for k in range(len(f_xn)):
|
||||
#frame = go.Frame(data=[go.Surface(x=xx1, y=xx2, z=fx, showscale=True, opacity=0.8)])
|
||||
#fig.add_trace(go.Scatter3d(x=np.array(self.xn_list)[:k, 0], y=np.array(self.xn_list)[:k, 1], z=f_xn))
|
||||
frame = go.Frame(dict(data=[go.Scatter3d(x=np.array(self.xn_list)[:k,0], y=np.array(self.xn_list)[:k,1], z=f_xn)], name=f'frame{k+1}'), traces=[1])
|
||||
frames.append(frame)
|
||||
step = dict(
|
||||
method="update",
|
||||
args=[{"visible": [True]},
|
||||
{"title": "Slider switched to step: " + str(k+1)}], # layout attribute
|
||||
)
|
||||
steps.append(step)
|
||||
|
||||
sliders = [dict(steps= [dict(method= 'animate',
|
||||
args= [[f'frame{k+1}'],
|
||||
dict(mode= 'immediate',
|
||||
frame= dict( duration=0, redraw= True ),
|
||||
transition=dict( duration=0)
|
||||
)
|
||||
],
|
||||
#label='Date : {}'.format(date_range[k])
|
||||
) for k in range(0,len(frames))],
|
||||
transition= dict(duration=0),
|
||||
x=0,
|
||||
y=0,
|
||||
currentvalue=dict(font=dict(size=12), visible=True, xanchor= 'center'),
|
||||
len=1.0)
|
||||
]
|
||||
|
||||
trace1 = go.Surface(x=xx1, y=xx2, z=fx, showscale=True, opacity=0.8)
|
||||
trace2 = go.Scatter3d(x=None, y=None, z=None)
|
||||
fig = go.Figure(data=[trace1, trace2], frames=frames)
|
||||
#fig.add_surface(x=xx1, y=xx2, z=fx, showscale=True, opacity=0.9)
|
||||
#fig.update_traces(contours_z=dict(show=True, usecolormap=True, highlightcolor="limegreen", project_z=True))
|
||||
#fig.update(frames=frames)
|
||||
fig.update_layout(updatemenus=[dict(type="buttons", buttons=[dict(label="Play", method="animate", args=[None, dict(fromcurrent=True)]), \
|
||||
dict(label="Pause", method="animate", args=[[None], dict(fromcurrent=True, mode='immediate', transition= {'duration': 0}, frame=dict(redraw=True, duration=0))])])],
|
||||
margin=dict(l=0, r=0, b=0, t=0), sliders=sliders)
|
||||
fig.show()
|
||||
|
||||
|
||||
|
||||
class gradient_descent_2d(object):
|
||||
def __init__(self, environ:str="jupyterlab"):
|
||||
pio.renderers.default = environ # 'notebook' or 'colab' or 'jupyterlab'
|
||||
|
@ -333,3 +219,161 @@ class gradient_descent_2d(object):
|
|||
dict(fromcurrent=True, mode='immediate', transition= {'duration': 0}, frame=dict(redraw=True, duration=0))])])],
|
||||
margin=dict(r=20, l=10, b=10, t=10), sliders=sliders)
|
||||
fig.show()
|
||||
|
||||
class gradient_descent_2d_custom(object):
|
||||
def __init__(self, environ:str="jupyterlab"):
|
||||
pio.renderers.default = environ # 'notebook' or 'colab' or 'jupyterlab'
|
||||
|
||||
self.wg_expr = widgets.Text(value="(sin(x1) - 2) ** 2 + (sin(x2) - 2) ** 2", description="Expression:")
|
||||
self.wg_x0 = widgets.Text(value="5,5", description="Startpoint:")
|
||||
self.wg_lr = widgets.FloatText(value="1e-1", description="step size:")
|
||||
self.wg_epsilon = widgets.FloatText(value="1e-5", description="criterion:")
|
||||
self.wg_max_iter = widgets.IntText(value="1000", description="max iteration")
|
||||
self.button_compute = widgets.Button(description="Compute")
|
||||
self.button_plot = widgets.Button(description="Plot")
|
||||
|
||||
self.compute_output = widgets.Output()
|
||||
self.plot_output = widgets.Output()
|
||||
self.params_lvbox = widgets.VBox([self.wg_expr, self.wg_x0, self.wg_lr])
|
||||
self.params_rvbox = widgets.VBox([self.wg_epsilon, self.wg_max_iter])
|
||||
self.params_box = widgets.HBox([self.params_lvbox, self.params_rvbox], description="Parameters")
|
||||
self.button_box = widgets.HBox([self.button_compute, self.button_plot], description="operations")
|
||||
self.config = widgets.VBox([self.params_box, self.button_box])
|
||||
self.initialization()
|
||||
|
||||
def initialization(self):
|
||||
display(self.config)
|
||||
self.button_compute.on_click(self.compute)
|
||||
display(self.compute_output)
|
||||
self.button_plot.on_click(self.plot)
|
||||
display(self.plot_output)
|
||||
|
||||
def compute(self, *args):
|
||||
with self.compute_output:
|
||||
x0 = np.array(self.wg_x0.value.split(","), dtype=float)
|
||||
xn = x0
|
||||
x1 = symbols("x1")
|
||||
x2 = symbols("x2")
|
||||
expr = sympify(self.wg_expr.value)
|
||||
self.xn_list, self.df_list = [], []
|
||||
for n in tqdm(range(0, self.wg_max_iter.value)):
|
||||
gradient = np.array([diff(expr, x1).subs(x1, xn[0]).subs(x2, xn[1]),
|
||||
diff(expr, x2).subs(x1, xn[0]).subs(x2, xn[1])], dtype=float)
|
||||
self.xn_list.append(xn)
|
||||
self.df_list.append(gradient)
|
||||
if np.linalg.norm(gradient, ord=2) < self.wg_epsilon.value:
|
||||
clear_output(wait=True)
|
||||
print("Found solution of {} after".format(expr), n, "iterations")
|
||||
print("x* = [{}, {}]".format(xn[0], xn[1]))
|
||||
return None
|
||||
xn = xn - self.wg_lr.value * gradient
|
||||
clear_output(wait=True)
|
||||
display("Exceeded maximum iterations. No solution found.")
|
||||
return None
|
||||
|
||||
def plot(self, *args):
|
||||
with self.plot_output:
|
||||
clear_output(wait=True)
|
||||
x0 = np.array(self.wg_x0.value.split(","), dtype=float)
|
||||
x1 = symbols("x1")
|
||||
x2 = symbols("x2")
|
||||
expr = sympify(self.wg_expr.value)
|
||||
xx1 = np.arange(np.array(self.xn_list)[:, 0].min()*0.5, np.array(self.xn_list)[:, 0].max()*1.5, 0.05)
|
||||
xx2 = np.arange(np.array(self.xn_list)[:, 1].min()*0.5, np.array(self.xn_list)[:, 1].max()*1.5, 0.05)
|
||||
xx1, xx2 = np.meshgrid(xx1, xx2)
|
||||
|
||||
f = lambdify((x1, x2), expr, "numpy")
|
||||
fx = f(xx1, xx2)
|
||||
f_xn = f(np.array(self.xn_list)[:, 0], np.array(self.xn_list)[:, 1])
|
||||
|
||||
frames, steps = [], []
|
||||
for k in range(len(f_xn)):
|
||||
#frame = go.Frame(data=[go.Surface(x=xx1, y=xx2, z=fx, showscale=True, opacity=0.8)])
|
||||
#fig.add_trace(go.Scatter3d(x=np.array(self.xn_list)[:k, 0], y=np.array(self.xn_list)[:k, 1], z=f_xn))
|
||||
frame = go.Frame(dict(data=[go.Scatter3d(x=np.array(self.xn_list)[:k,0], y=np.array(self.xn_list)[:k,1], z=f_xn)], name=f'frame{k+1}'), traces=[1])
|
||||
frames.append(frame)
|
||||
step = dict(
|
||||
method="update",
|
||||
args=[{"visible": [True]},
|
||||
{"title": "Slider switched to step: " + str(k+1)}], # layout attribute
|
||||
)
|
||||
steps.append(step)
|
||||
|
||||
sliders = [dict(steps= [dict(method= 'animate',
|
||||
args= [[f'frame{k+1}'],
|
||||
dict(mode= 'immediate',
|
||||
frame= dict( duration=0, redraw= True ),
|
||||
transition=dict( duration=0)
|
||||
)
|
||||
],
|
||||
#label='Date : {}'.format(date_range[k])
|
||||
) for k in range(0,len(frames))],
|
||||
transition= dict(duration=0),
|
||||
x=0,
|
||||
y=0,
|
||||
currentvalue=dict(font=dict(size=12), visible=True, xanchor= 'center'),
|
||||
len=1.0)
|
||||
]
|
||||
|
||||
trace1 = go.Surface(x=xx1, y=xx2, z=fx, showscale=True, opacity=0.8)
|
||||
trace2 = go.Scatter3d(x=None, y=None, z=None)
|
||||
fig = go.Figure(data=[trace1, trace2], frames=frames)
|
||||
#fig.add_surface(x=xx1, y=xx2, z=fx, showscale=True, opacity=0.9)
|
||||
#fig.update_traces(contours_z=dict(show=True, usecolormap=True, highlightcolor="limegreen", project_z=True))
|
||||
#fig.update(frames=frames)
|
||||
fig.update_layout(updatemenus=[dict(type="buttons", buttons=[dict(label="Play", method="animate", args=[None, dict(fromcurrent=True)]), \
|
||||
dict(label="Pause", method="animate", args=[[None], dict(fromcurrent=True, mode='immediate', transition= {'duration': 0}, frame=dict(redraw=True, duration=0))])])],
|
||||
margin=dict(l=0, r=0, b=0, t=0), sliders=sliders)
|
||||
fig.show()
|
||||
|
||||
class gradient_descent_2d_race(object):
|
||||
def __init__(self, environ:str="jupyterlab"):
|
||||
pio.renderers.default = environ # 'notebook' or 'colab' or 'jupyterlab'
|
||||
self.wg_expr = widgets.Text(value="(sin(x1) - 2) ** 2 + (sin(x2) - 2) ** 2", description="Expression:")
|
||||
self.wg_person_one = widgets.Text(value="(0, 0)", description="coordinate 1:")
|
||||
self.wg_person_two = widgets.Text(value="(0, 0)", description="coordinate 2:")
|
||||
self.button_compute = widgets.Button(description="Compute")
|
||||
self.button_plot = widgets.Button(description="Plot")
|
||||
self.compute_output = widgets.Output()
|
||||
self.config = widgets.VBox([self.wg_expr, self.wg_person_one, self.wg_person_two, self.button_compute])
|
||||
self.xn_list_p1, self.df_list_p1 = [], []
|
||||
self.xn_list_p2, self.df_list_p2 = [], []
|
||||
self.initialization()
|
||||
|
||||
def initialization(self):
|
||||
display(self.config)
|
||||
self.button_compute.on_click(self.compute)
|
||||
display(self.compute_output)
|
||||
#self.button_plot.on_click(self.plot)
|
||||
#display(self.plot_output)
|
||||
|
||||
def compute(self, *args):
|
||||
with self.compute_output:
|
||||
# person_one
|
||||
x0 = np.array(self.wg_person_one.value.split("(")[1].split(")")[0].split(","), dtype=float)
|
||||
xn = x0
|
||||
x1 = symbols("x1")
|
||||
x2 = symbols("x2")
|
||||
expr = sympify(self.wg_expr.value)
|
||||
gradient = np.array([diff(expr, x1).subs(x1, xn[0]).subs(x2, xn[1]),
|
||||
diff(expr, x2).subs(x1, xn[0]).subs(x2, xn[1])], dtype=float)
|
||||
self.xn_list_p1.append(xn)
|
||||
self.df_list_p1.append(gradient)
|
||||
print("player one: x = [{}, {}]".format(xn[0], xn[1]))
|
||||
print("player one: gradient= {}".format(gradient))
|
||||
# person_two
|
||||
x0 = np.array(self.wg_person_two.value.split("(")[1].split(")")[0].split(","), dtype=float)
|
||||
xn = x0
|
||||
x1 = symbols("x1")
|
||||
x2 = symbols("x2")
|
||||
expr = sympify(self.wg_expr.value)
|
||||
gradient = np.array([diff(expr, x1).subs(x1, xn[0]).subs(x2, xn[1]),
|
||||
diff(expr, x2).subs(x1, xn[0]).subs(x2, xn[1])], dtype=float)
|
||||
self.xn_list_p2.append(xn)
|
||||
self.df_list_p2.append(gradient)
|
||||
print("player two: x = [{}, {}]".format(xn[0], xn[1]))
|
||||
print("player two: gradient= {}".format(gradient))
|
||||
clear_output(wait=True)
|
||||
return None
|
||||
|
||||
|
|
@ -100,120 +100,6 @@ class gradient_descent_1d(object):
|
|||
fig.update_layout(updatemenus=[dict(type="buttons",buttons=[dict(label="Play",method="animate",args=[None])])])
|
||||
fig.show()
|
||||
|
||||
|
||||
class gradient_descent_2d_custom(object):
|
||||
def __init__(self, environ:str="jupyterlab"):
|
||||
pio.renderers.default = environ # 'notebook' or 'colab' or 'jupyterlab'
|
||||
|
||||
self.wg_expr = widgets.Text(value="(sin(x1) - 2) ** 2 + (sin(x2) - 2) ** 2",
|
||||
description="Expression:") #style={'description_width': 'initial'})
|
||||
self.wg_x0 = widgets.Text(value="5,5",
|
||||
description="Startpoint:")
|
||||
self.wg_lr = widgets.FloatText(value="1e-1",
|
||||
description="step size:")
|
||||
self.wg_epsilon = widgets.FloatText(value="1e-5",
|
||||
description="criterion:")
|
||||
self.wg_max_iter = widgets.IntText(value="1000",
|
||||
description="max iteration")
|
||||
self.button_compute = widgets.Button(description="Compute")
|
||||
self.button_plot = widgets.Button(description="Plot")
|
||||
|
||||
self.compute_output = widgets.Output()
|
||||
self.plot_output = widgets.Output()
|
||||
self.params_lvbox = widgets.VBox([self.wg_expr, self.wg_x0, self.wg_lr])
|
||||
self.params_rvbox = widgets.VBox([self.wg_epsilon, self.wg_max_iter])
|
||||
self.params_box = widgets.HBox([self.params_lvbox, self.params_rvbox], description="Parameters")
|
||||
self.button_box = widgets.HBox([self.button_compute, self.button_plot], description="operations")
|
||||
self.config = widgets.VBox([self.params_box, self.button_box])
|
||||
self.initialization()
|
||||
|
||||
def initialization(self):
|
||||
display(self.config)
|
||||
self.button_compute.on_click(self.compute)
|
||||
display(self.compute_output)
|
||||
self.button_plot.on_click(self.plot)
|
||||
display(self.plot_output)
|
||||
|
||||
def compute(self, *args):
|
||||
with self.compute_output:
|
||||
x0 = np.array(self.wg_x0.value.split(","), dtype=float)
|
||||
xn = x0
|
||||
x1 = symbols("x1")
|
||||
x2 = symbols("x2")
|
||||
expr = sympify(self.wg_expr.value)
|
||||
self.xn_list, self.df_list = [], []
|
||||
for n in tqdm(range(0, self.wg_max_iter.value)):
|
||||
gradient = np.array([diff(expr, x1).subs(x1, xn[0]).subs(x2, xn[1]),
|
||||
diff(expr, x2).subs(x1, xn[0]).subs(x2, xn[1])], dtype=float)
|
||||
self.xn_list.append(xn)
|
||||
self.df_list.append(gradient)
|
||||
if np.linalg.norm(gradient, ord=2) < self.wg_epsilon.value:
|
||||
clear_output(wait=True)
|
||||
print("Found solution of {} after".format(expr), n, "iterations")
|
||||
print("x* = [{}, {}]".format(xn[0], xn[1]))
|
||||
return None
|
||||
xn = xn - self.wg_lr.value * gradient
|
||||
clear_output(wait=True)
|
||||
display("Exceeded maximum iterations. No solution found.")
|
||||
return None
|
||||
|
||||
def plot(self, *args):
|
||||
with self.plot_output:
|
||||
clear_output(wait=True)
|
||||
x0 = np.array(self.wg_x0.value.split(","), dtype=float)
|
||||
x1 = symbols("x1")
|
||||
x2 = symbols("x2")
|
||||
expr = sympify(self.wg_expr.value)
|
||||
xx1 = np.arange(np.array(self.xn_list)[:, 0].min()*0.5, np.array(self.xn_list)[:, 0].max()*1.5, 0.05)
|
||||
xx2 = np.arange(np.array(self.xn_list)[:, 1].min()*0.5, np.array(self.xn_list)[:, 1].max()*1.5, 0.05)
|
||||
xx1, xx2 = np.meshgrid(xx1, xx2)
|
||||
|
||||
f = lambdify((x1, x2), expr, "numpy")
|
||||
fx = f(xx1, xx2)
|
||||
f_xn = f(np.array(self.xn_list)[:, 0], np.array(self.xn_list)[:, 1])
|
||||
|
||||
frames, steps = [], []
|
||||
for k in range(len(f_xn)):
|
||||
#frame = go.Frame(data=[go.Surface(x=xx1, y=xx2, z=fx, showscale=True, opacity=0.8)])
|
||||
#fig.add_trace(go.Scatter3d(x=np.array(self.xn_list)[:k, 0], y=np.array(self.xn_list)[:k, 1], z=f_xn))
|
||||
frame = go.Frame(dict(data=[go.Scatter3d(x=np.array(self.xn_list)[:k,0], y=np.array(self.xn_list)[:k,1], z=f_xn)], name=f'frame{k+1}'), traces=[1])
|
||||
frames.append(frame)
|
||||
step = dict(
|
||||
method="update",
|
||||
args=[{"visible": [True]},
|
||||
{"title": "Slider switched to step: " + str(k+1)}], # layout attribute
|
||||
)
|
||||
steps.append(step)
|
||||
|
||||
sliders = [dict(steps= [dict(method= 'animate',
|
||||
args= [[f'frame{k+1}'],
|
||||
dict(mode= 'immediate',
|
||||
frame= dict( duration=0, redraw= True ),
|
||||
transition=dict( duration=0)
|
||||
)
|
||||
],
|
||||
#label='Date : {}'.format(date_range[k])
|
||||
) for k in range(0,len(frames))],
|
||||
transition= dict(duration=0),
|
||||
x=0,
|
||||
y=0,
|
||||
currentvalue=dict(font=dict(size=12), visible=True, xanchor= 'center'),
|
||||
len=1.0)
|
||||
]
|
||||
|
||||
trace1 = go.Surface(x=xx1, y=xx2, z=fx, showscale=True, opacity=0.8)
|
||||
trace2 = go.Scatter3d(x=None, y=None, z=None)
|
||||
fig = go.Figure(data=[trace1, trace2], frames=frames)
|
||||
#fig.add_surface(x=xx1, y=xx2, z=fx, showscale=True, opacity=0.9)
|
||||
#fig.update_traces(contours_z=dict(show=True, usecolormap=True, highlightcolor="limegreen", project_z=True))
|
||||
#fig.update(frames=frames)
|
||||
fig.update_layout(updatemenus=[dict(type="buttons", buttons=[dict(label="Play", method="animate", args=[None, dict(fromcurrent=True)]), \
|
||||
dict(label="Pause", method="animate", args=[[None], dict(fromcurrent=True, mode='immediate', transition= {'duration': 0}, frame=dict(redraw=True, duration=0))])])],
|
||||
margin=dict(l=0, r=0, b=0, t=0), sliders=sliders)
|
||||
fig.show()
|
||||
|
||||
|
||||
|
||||
class gradient_descent_2d(object):
|
||||
def __init__(self, environ:str="jupyterlab"):
|
||||
pio.renderers.default = environ # 'notebook' or 'colab' or 'jupyterlab'
|
||||
|
@ -333,3 +219,161 @@ class gradient_descent_2d(object):
|
|||
dict(fromcurrent=True, mode='immediate', transition= {'duration': 0}, frame=dict(redraw=True, duration=0))])])],
|
||||
margin=dict(r=20, l=10, b=10, t=10), sliders=sliders)
|
||||
fig.show()
|
||||
|
||||
class gradient_descent_2d_custom(object):
|
||||
def __init__(self, environ:str="jupyterlab"):
|
||||
pio.renderers.default = environ # 'notebook' or 'colab' or 'jupyterlab'
|
||||
|
||||
self.wg_expr = widgets.Text(value="(sin(x1) - 2) ** 2 + (sin(x2) - 2) ** 2", description="Expression:")
|
||||
self.wg_x0 = widgets.Text(value="5,5", description="Startpoint:")
|
||||
self.wg_lr = widgets.FloatText(value="1e-1", description="step size:")
|
||||
self.wg_epsilon = widgets.FloatText(value="1e-5", description="criterion:")
|
||||
self.wg_max_iter = widgets.IntText(value="1000", description="max iteration")
|
||||
self.button_compute = widgets.Button(description="Compute")
|
||||
self.button_plot = widgets.Button(description="Plot")
|
||||
|
||||
self.compute_output = widgets.Output()
|
||||
self.plot_output = widgets.Output()
|
||||
self.params_lvbox = widgets.VBox([self.wg_expr, self.wg_x0, self.wg_lr])
|
||||
self.params_rvbox = widgets.VBox([self.wg_epsilon, self.wg_max_iter])
|
||||
self.params_box = widgets.HBox([self.params_lvbox, self.params_rvbox], description="Parameters")
|
||||
self.button_box = widgets.HBox([self.button_compute, self.button_plot], description="operations")
|
||||
self.config = widgets.VBox([self.params_box, self.button_box])
|
||||
self.initialization()
|
||||
|
||||
def initialization(self):
|
||||
display(self.config)
|
||||
self.button_compute.on_click(self.compute)
|
||||
display(self.compute_output)
|
||||
self.button_plot.on_click(self.plot)
|
||||
display(self.plot_output)
|
||||
|
||||
def compute(self, *args):
|
||||
with self.compute_output:
|
||||
x0 = np.array(self.wg_x0.value.split(","), dtype=float)
|
||||
xn = x0
|
||||
x1 = symbols("x1")
|
||||
x2 = symbols("x2")
|
||||
expr = sympify(self.wg_expr.value)
|
||||
self.xn_list, self.df_list = [], []
|
||||
for n in tqdm(range(0, self.wg_max_iter.value)):
|
||||
gradient = np.array([diff(expr, x1).subs(x1, xn[0]).subs(x2, xn[1]),
|
||||
diff(expr, x2).subs(x1, xn[0]).subs(x2, xn[1])], dtype=float)
|
||||
self.xn_list.append(xn)
|
||||
self.df_list.append(gradient)
|
||||
if np.linalg.norm(gradient, ord=2) < self.wg_epsilon.value:
|
||||
clear_output(wait=True)
|
||||
print("Found solution of {} after".format(expr), n, "iterations")
|
||||
print("x* = [{}, {}]".format(xn[0], xn[1]))
|
||||
return None
|
||||
xn = xn - self.wg_lr.value * gradient
|
||||
clear_output(wait=True)
|
||||
display("Exceeded maximum iterations. No solution found.")
|
||||
return None
|
||||
|
||||
def plot(self, *args):
|
||||
with self.plot_output:
|
||||
clear_output(wait=True)
|
||||
x0 = np.array(self.wg_x0.value.split(","), dtype=float)
|
||||
x1 = symbols("x1")
|
||||
x2 = symbols("x2")
|
||||
expr = sympify(self.wg_expr.value)
|
||||
xx1 = np.arange(np.array(self.xn_list)[:, 0].min()*0.5, np.array(self.xn_list)[:, 0].max()*1.5, 0.05)
|
||||
xx2 = np.arange(np.array(self.xn_list)[:, 1].min()*0.5, np.array(self.xn_list)[:, 1].max()*1.5, 0.05)
|
||||
xx1, xx2 = np.meshgrid(xx1, xx2)
|
||||
|
||||
f = lambdify((x1, x2), expr, "numpy")
|
||||
fx = f(xx1, xx2)
|
||||
f_xn = f(np.array(self.xn_list)[:, 0], np.array(self.xn_list)[:, 1])
|
||||
|
||||
frames, steps = [], []
|
||||
for k in range(len(f_xn)):
|
||||
#frame = go.Frame(data=[go.Surface(x=xx1, y=xx2, z=fx, showscale=True, opacity=0.8)])
|
||||
#fig.add_trace(go.Scatter3d(x=np.array(self.xn_list)[:k, 0], y=np.array(self.xn_list)[:k, 1], z=f_xn))
|
||||
frame = go.Frame(dict(data=[go.Scatter3d(x=np.array(self.xn_list)[:k,0], y=np.array(self.xn_list)[:k,1], z=f_xn)], name=f'frame{k+1}'), traces=[1])
|
||||
frames.append(frame)
|
||||
step = dict(
|
||||
method="update",
|
||||
args=[{"visible": [True]},
|
||||
{"title": "Slider switched to step: " + str(k+1)}], # layout attribute
|
||||
)
|
||||
steps.append(step)
|
||||
|
||||
sliders = [dict(steps= [dict(method= 'animate',
|
||||
args= [[f'frame{k+1}'],
|
||||
dict(mode= 'immediate',
|
||||
frame= dict( duration=0, redraw= True ),
|
||||
transition=dict( duration=0)
|
||||
)
|
||||
],
|
||||
#label='Date : {}'.format(date_range[k])
|
||||
) for k in range(0,len(frames))],
|
||||
transition= dict(duration=0),
|
||||
x=0,
|
||||
y=0,
|
||||
currentvalue=dict(font=dict(size=12), visible=True, xanchor= 'center'),
|
||||
len=1.0)
|
||||
]
|
||||
|
||||
trace1 = go.Surface(x=xx1, y=xx2, z=fx, showscale=True, opacity=0.8)
|
||||
trace2 = go.Scatter3d(x=None, y=None, z=None)
|
||||
fig = go.Figure(data=[trace1, trace2], frames=frames)
|
||||
#fig.add_surface(x=xx1, y=xx2, z=fx, showscale=True, opacity=0.9)
|
||||
#fig.update_traces(contours_z=dict(show=True, usecolormap=True, highlightcolor="limegreen", project_z=True))
|
||||
#fig.update(frames=frames)
|
||||
fig.update_layout(updatemenus=[dict(type="buttons", buttons=[dict(label="Play", method="animate", args=[None, dict(fromcurrent=True)]), \
|
||||
dict(label="Pause", method="animate", args=[[None], dict(fromcurrent=True, mode='immediate', transition= {'duration': 0}, frame=dict(redraw=True, duration=0))])])],
|
||||
margin=dict(l=0, r=0, b=0, t=0), sliders=sliders)
|
||||
fig.show()
|
||||
|
||||
class gradient_descent_2d_race(object):
|
||||
def __init__(self, environ:str="jupyterlab"):
|
||||
pio.renderers.default = environ # 'notebook' or 'colab' or 'jupyterlab'
|
||||
self.wg_expr = widgets.Text(value="(sin(x1) - 2) ** 2 + (sin(x2) - 2) ** 2", description="Expression:")
|
||||
self.wg_person_one = widgets.Text(value="(0, 0)", description="coordinate 1:")
|
||||
self.wg_person_two = widgets.Text(value="(0, 0)", description="coordinate 2:")
|
||||
self.button_compute = widgets.Button(description="Compute")
|
||||
self.button_plot = widgets.Button(description="Plot")
|
||||
self.compute_output = widgets.Output()
|
||||
self.config = widgets.VBox([self.wg_expr, self.wg_person_one, self.wg_person_two, self.button_compute])
|
||||
self.xn_list_p1, self.df_list_p1 = [], []
|
||||
self.xn_list_p2, self.df_list_p2 = [], []
|
||||
self.initialization()
|
||||
|
||||
def initialization(self):
|
||||
display(self.config)
|
||||
self.button_compute.on_click(self.compute)
|
||||
display(self.compute_output)
|
||||
#self.button_plot.on_click(self.plot)
|
||||
#display(self.plot_output)
|
||||
|
||||
def compute(self, *args):
|
||||
with self.compute_output:
|
||||
# person_one
|
||||
x0 = np.array(self.wg_person_one.value.split("(")[1].split(")")[0].split(","), dtype=float)
|
||||
xn = x0
|
||||
x1 = symbols("x1")
|
||||
x2 = symbols("x2")
|
||||
expr = sympify(self.wg_expr.value)
|
||||
gradient = np.array([diff(expr, x1).subs(x1, xn[0]).subs(x2, xn[1]),
|
||||
diff(expr, x2).subs(x1, xn[0]).subs(x2, xn[1])], dtype=float)
|
||||
self.xn_list_p1.append(xn)
|
||||
self.df_list_p1.append(gradient)
|
||||
print("player one: x = [{}, {}]".format(xn[0], xn[1]))
|
||||
print("player one: gradient= {}".format(gradient))
|
||||
# person_two
|
||||
x0 = np.array(self.wg_person_two.value.split("(")[1].split(")")[0].split(","), dtype=float)
|
||||
xn = x0
|
||||
x1 = symbols("x1")
|
||||
x2 = symbols("x2")
|
||||
expr = sympify(self.wg_expr.value)
|
||||
gradient = np.array([diff(expr, x1).subs(x1, xn[0]).subs(x2, xn[1]),
|
||||
diff(expr, x2).subs(x1, xn[0]).subs(x2, xn[1])], dtype=float)
|
||||
self.xn_list_p2.append(xn)
|
||||
self.df_list_p2.append(gradient)
|
||||
print("player two: x = [{}, {}]".format(xn[0], xn[1]))
|
||||
print("player two: gradient= {}".format(gradient))
|
||||
clear_output(wait=True)
|
||||
return None
|
||||
|
||||
|
Loading…
Reference in New Issue