Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
greyhatguy007
GitHub Repository: greyhatguy007/Machine-Learning-Specialization-Coursera
Path: blob/main/C2 - Advanced Learning Algorithms/week2/optional-labs/backprop/lab_utils_backprop.py
3589 views
1
from sympy import *
2
import numpy as np
3
import re
4
5
import matplotlib.pyplot as plt
6
from matplotlib.widgets import TextBox
7
from matplotlib.widgets import Button
8
import ipywidgets as widgets
9
10
def widgvis(fig):
11
fig.canvas.toolbar_visible = False
12
fig.canvas.header_visible = False
13
fig.canvas.footer_visible = False
14
15
def between(a, b, x):
16
''' determine if a point x is between a and b. a may be greater or less than b '''
17
if a > b:
18
return b <= x <= a
19
if b > a:
20
return a <= x <= b
21
22
def near(pt, alist, dist=15):
23
for a in alist:
24
x, y = a.ao.get_position() #(bot left, bot right) data coords, not relative
25
x = x - 5
26
y = y + 2.5
27
if 0 < (pt[0] - x) < 25 and 0 < (y - pt[1]) < 25:
28
return(True, a)
29
return(False,None)
30
31
def inboxes(pt, boxlist):
32
''' returns true if pt is within one of the boxes in boxlist '''
33
#with out:
34
# print(f" inboxes:{boxlist}, {pt}")
35
for b in boxlist:
36
if b.inbox(pt):
37
return(True, b)
38
return(False, None)
39
40
41
class avalue():
42
''' one of the values on the figure that can be filled in '''
43
def __init__(self, value, pt, cl):
44
self.value = value
45
self.cl = cl # color
46
self.pt = pt # point
47
48
def add_anote(self, ax):
49
self.ax = ax
50
self.ao = self.ax.annotate("?", self.pt, c=self.cl, fontsize='x-small')
51
52
class astring():
53
''' a string that can be set visible or invisible '''
54
def __init__(self, ax, string, pt, cl):
55
self.string = string
56
self.cl = cl # color
57
self.pt = pt # point
58
self.ax = ax
59
self.ao = self.ax.annotate(self.string, self.pt, c="white", fontsize='x-small')
60
61
def astring_visible(self):
62
self.ao.set_color(self.cl)
63
64
def astring_invisible(self):
65
self.ao.set_color("white")
66
67
68
class abox():
69
''' one of the boxes in the graph that has a value '''
70
def __init__(self, ax, value, left, bottom, right, top, anpt, cl, adj_anote_obj):
71
self.ax = ax
72
self.value = value # correct value for annotation
73
self.left = left
74
self.right = right
75
self.bottom = bottom
76
self.top = top
77
self.anpt= anpt # x,y where expression should be listed
78
self.cl = cl
79
self.ao = self.ax.annotate("?", self.anpt, c=self.cl, fontsize='x-small')
80
self.astr = adj_anote_obj # 2ndary text for marking edges or none
81
82
def inbox(self, pt):
83
''' true if point is within the box '''
84
#with out: #debug
85
# print(f" b.inbox: {pt}")
86
x, y = pt
87
isbetween = between(self.top, self.bottom, y) and between(self.left, self.right, x)
88
return isbetween
89
90
def update_val(self, value, cl=None):
91
self.ao.set_text(value)
92
if cl:
93
self.ao.set_c(cl)
94
else:
95
self.ao.set_c(self.cl)
96
97
def show_secondary(self):
98
if self.astr: # if there is a 2ndary set of text
99
self.astr.ao.set_c("green")
100
101
def clear_secondary(self):
102
if self.astr: # if there is a 2ndary set of text
103
self.astr.ao.set_c("white")
104
105
106
107
## For debug, put this in the notebook being debugged and be sure to set the out=out parameter
108
#out = widgets.Output(layout={'border': '1px solid black'})
109
#out
110
111
class plt_network():
112
113
def __init__(self, fn, image, out=None):
114
self.out = out # debug
115
#with self.out:
116
# print("hello world")
117
img = plt.imread(image)
118
self.fig, self.ax = plt.subplots(figsize=self.sizefig(img))
119
boxes = fn(self.ax)
120
self.boxes = boxes
121
widgvis(self.fig)
122
self.ax.xaxis.set_visible(False)
123
self.ax.yaxis.set_visible(False)
124
self.ax.imshow(img)
125
self.fig.text(0.1,0.9, "Click in boxes to fill in values.")
126
self.glist = [] # place to stash global things
127
self.san = [] # selected annotation
128
129
self.cid = self.fig.canvas.mpl_connect('button_press_event', self.onclick)
130
self.axreveal = plt.axes([0.55, 0.02, 0.15, 0.075]) #[left, bottom, width, height]
131
self.axhide = plt.axes([0.76, 0.02, 0.15, 0.075])
132
self.breveal = Button(self.axreveal, 'Reveal All')
133
self.breveal.on_clicked(self.reveal_values)
134
self.bhide = Button(self.axhide, 'Hide All')
135
self.bhide.on_clicked(self.hide_values)
136
#plt.show()
137
138
def sizefig(self,img):
139
iy,ix,iz = np.shape(img)
140
if 10/5 < ix/iy: # if x is the limiting size
141
figx = 10
142
figy = figx*iy/ix
143
else:
144
figy = 5
145
figx = figy*ix/iy
146
return(figx,figy)
147
148
def updateval(self, event):
149
#with self.out: #debug
150
# print(event)
151
box = self.san[0]
152
num_format = re.compile(r"[+-]?\d+(?:\.\d+)?")
153
isnumber = re.match(num_format,event)
154
if not isnumber:
155
box.update_val('?','red')
156
else:
157
#with self.out:
158
# print(event)
159
newval = int(float(event)) if int(float(event)) == float(event) else float(event)
160
newval = round(newval,2)
161
#with self.out:
162
# print(newval, box.value, type(newval), type(box.value))
163
if newval == box.value:
164
box.show_secondary()
165
box.update_val(round(newval,2))
166
else:
167
box.update_val(round(newval,2), 'red')
168
box.clear_secondary()
169
self.glist[0].remove()
170
self.glist.clear()
171
self.san.clear()
172
173
# collects all clicks within diagram and dispatches
174
def onclick(self, event):
175
#with self.out:
176
# print('%s click: button=%d, x=%d, y=%d, xdata=%f, ydata=%f' %
177
# ('double' if event.dblclick else 'single', event.button,
178
# event.x, event.y, event.xdata, event.ydata))
179
if len(self.san) != 0: # already waiting for new value
180
return
181
inbox, box = inboxes((event.xdata, event.ydata), self.boxes)
182
#with self.out:
183
# print(f" in box: {inbox, box}")
184
if inbox:
185
self.san.append(box)
186
#an.set_text(an.get_text() + "1") # debug
187
graphBox = self.fig.add_axes([0.225, 0.02, 0.2, 0.075]) # [left, bottom, width, height]
188
txtBox = TextBox(graphBox, "newvalue: ")
189
txtBox.on_submit(self.updateval)
190
self.glist.append(graphBox)
191
self.glist.append(txtBox)
192
return
193
194
def reveal_values(self, event):
195
for b in self.boxes:
196
b.update_val(b.value)
197
b.show_secondary()
198
plt.draw()
199
200
def hide_values(self, event):
201
for b in self.boxes:
202
b.update_val("?")
203
b.clear_secondary()
204
plt.draw()
205
206
#--------------------------------------------------------------------------
207
208
209
def config_nw0(ax):
210
#"./images/C2_W2_BP_network0.PNG"
211
212
w = 3
213
a = 2+3*w
214
J = a**2
215
216
pass ; dJ_dJ = 1
217
dJ_da = 2*a ; dJ_da = dJ_dJ * dJ_da
218
da_dw = 3 ; dJ_dw = dJ_da * da_dw
219
220
box1 = abox(ax, round(a,2), 307, 140, 352, 100, (315, 128),'blue', None) # left, bottom, right, top,
221
box2 = abox(ax, round(J,2), 581, 138, 624, 100, (589, 128),'blue', None)
222
223
dJ_da_a = astring(ax, r"$\frac{\partial J}{\partial a}=$"+f"{dJ_da}", (291,186), "green")
224
box3 = abox(ax, round(dJ_da,2), 545, 417, 588, 380, (553,407), 'green', dJ_da_a)
225
226
dJ_dw_a = astring(ax, r"$\frac{\partial J}{\partial w}=$"+f"{dJ_dw}", (60,186), "green")
227
box4 = abox(ax, round(da_dw,2), 195, 421, 237, 380, (203,411), 'green', None)
228
box5 = abox(ax, round(dJ_dw,2), 265, 515, 310, 475, (273,505), 'green', dJ_dw_a)
229
230
boxes = [box1, box2, box3, box4, box5]
231
232
return boxes
233
234
def config_nw1(ax):
235
# "./images/C2_W2_BP_Network1.PNG"
236
237
x = 2
238
w = -2
239
b = 8
240
y = 1
241
242
c = w * x
243
a = c + b
244
d = a - y
245
J = d**2/2
246
247
pass ; dJ_dJ = 1
248
dJ_dd = 2*d/2 ; dJ_dd = dJ_dJ * dJ_dd
249
dd_da = 1 ; dJ_da = dJ_dd * dd_da
250
da_db = 1 ; dJ_db = dJ_da * da_db
251
da_dc = 1 ; dJ_dc = dJ_da * da_dc
252
dc_dw = x ; dJ_dw = dJ_dc * dc_dw
253
254
box1 = abox(ax, round(c,2), 330, 162, 382, 114, (338, 150),'blue', None) # left, bottom, right, top,
255
box2 = abox(ax, round(a,2), 636, 162, 688, 114, (644, 150),'blue', None)
256
box3 = abox(ax, round(d,2), 964, 162, 1015, 114, (972, 150),'blue', None)
257
box4 = abox(ax, round(J,2), 1266, 162, 1315, 114, (1274,150),'blue', None)
258
259
dJ_dd_a = astring(ax, r"$\frac{\partial J}{\partial d}=$"+f"{dJ_dd}", (967,208), "green")
260
box5 = abox(ax, round(dJ_dd,2), 1222, 488, 1275, 441, (1230,478), 'green', dJ_dd_a)
261
262
dJ_da_a = astring(ax, r"$\frac{\partial J}{\partial a}=$"+f"{dJ_da}", (615,208), "green")
263
box6 = abox(ax, round(dd_da,2), 900, 383, 951, 333, (908,373), 'green', None)
264
box7 = abox(ax, round(dJ_da,2), 988, 483, 1037, 441, (996,473), 'green', dJ_da_a)
265
266
dJ_dc_a = astring(ax, r"$\frac{\partial J}{\partial c}=$"+f"{dJ_dc}", (337,208), "green")
267
box8 = abox(ax, round(da_dc,2), 570, 380, 620, 333, (578,370), 'green', None)
268
box9 = abox(ax, round(dJ_dc,2), 638, 467, 688, 419, (646,457), 'green', dJ_dc_a)
269
270
dJ_db_a = astring(ax, r"$\frac{\partial J}{\partial b}=$"+f"{dJ_dc}", (474,252), "green")
271
box10 = abox(ax, round(da_db,2), 563, 582, 615, 533, (571,572), 'green', None)
272
box11 = abox(ax, round(dJ_db,2), 630, 677, 684, 630, (638,667), 'green', dJ_db_a)
273
274
dJ_dw_a = astring(ax, r"$\frac{\partial J}{\partial w}=$"+f"{dJ_dw}", (60,208), "green")
275
box12 = abox(ax, round(dc_dw,2), 191, 379, 341, 332, (199,369), 'green', None)
276
box13 = abox(ax, round(dJ_dw,2), 266, 495, 319, 448, (274,485), 'green', dJ_dw_a)
277
278
boxes = [box1, box2, box3, box4, box5, box6, box7, box8, box9, box10, box11, box12, box13]
279
280
return boxes
281
282
#not used
283
def config_nw2():
284
x0 = 1
285
x1 = 2
286
w0 = -2
287
w1 = 3
288
b = -4
289
y = 1
290
d = x0 * w0
291
e = x1 * w1
292
f = d+e+b
293
g = -f
294
h = np.exp(g)
295
i = h+1
296
a = 1/i
297
k = y-a
298
L = k**2
299
300
pass ; dL_dL = 1
301
dL_dk = 2*k ; dL_dk = dL_dL * dL_dk
302
dk_da = -1 ; dL_da = dL_dk * dk_da
303
da_di = -1/i**2 ; dL_di = dL_da * da_di
304
di_dh = 1 ; dL_dh = dL_di * di_dh
305
dh_dg = exp(g) ; dL_dg = dL_dh * dh_dg
306
dg_df = -1 ; dL_df = dL_dg * dg_df
307
df_dd = 1 ; dL_dd = dL_df * df_dd
308
df_de = 2 ; dL_de = dL_df * df_de
309
df_db = 1 ; dL_db = dL_df * df_db
310
dd_dw0 = 1 ; dL_dw0 = dL_dd * dd_dw0
311
de_dw1 = 2 ; dL_dw1 = dL_de * de_dw1
312
313
an1 = avalue(round(d,2), (270,265), 'blue')
314
an2 = avalue(round(e,2), (270,350), 'blue')
315
an3 = avalue(round(f,2), (400,315), 'blue')
316
an4 = avalue(round(g,2), (540,315), 'blue')
317
an5 = avalue(round(h,2), (650,315), 'blue')
318
an6 = avalue(round(i,2), (760,315), 'blue')
319
an7 = avalue(round(a,2), (890,315), 'blue')
320
an8 = avalue(round(k,2), (1015,315), 'blue')
321
an9 = avalue(round(L,2), (1120,315), 'blue')
322
bn1 = avalue(round(dL_dd,2), (260,300), 'green') #d
323
bn2 = avalue(round(dL_de,2), (270,385), 'green') #e
324
bn3 = avalue(round(dL_df,2), (408,350), 'green') #f
325
bn4 = avalue(round(dL_dg,2), (540,350), 'green') #g
326
bn5 = avalue(round(dL_dh,2), (650,350), 'green') #h
327
bn6 = avalue(round(dL_di,2), (760,350), 'green') #i
328
bn7 = avalue(round(dL_da,2), (890,350), 'green') #a
329
bn8 = avalue(round(dL_dk,2), (1015,350), 'green') #k
330
bn9 = avalue(round(dL_dw0,2), (210,300), 'green') #w0
331
bn10 = avalue(round(dL_dw1,2), (205,440),'green') #w1
332
bn11 = avalue(round(dL_db,2), (345,385), 'green') #b
333
334
anotes = [an1, an2, an3, an4, an5, an6, an7, an8, an9,
335
bn1, bn2, bn3, bn4, bn5, bn6, bn7, bn8, bn9, bn10, bn11]
336
337
box1 = abox(r"$\frac{\partial v}{\partial t}$", 943, 347, 980, 310, (980,300))
338
boxes = [box1]
339
340
fn = "./images/C2_W2_BP_bkground.PNG"
341
return fn, anotes, boxes
342