Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
greyhatguy007
GitHub Repository: greyhatguy007/machine-learning-specialization-coursera
Path: blob/main/C1 - Supervised Machine Learning - Regression and Classification/week1/Optional Labs/lab_utils_uni.py
2201 views
1
"""
2
lab_utils_uni.py
3
routines used in Course 1, Week2, labs1-3 dealing with single variables (univariate)
4
"""
5
import numpy as np
6
import matplotlib.pyplot as plt
7
from matplotlib.ticker import MaxNLocator
8
from matplotlib.gridspec import GridSpec
9
from matplotlib.colors import LinearSegmentedColormap
10
from ipywidgets import interact
11
from lab_utils_common import compute_cost
12
from lab_utils_common import dlblue, dlorange, dldarkred, dlmagenta, dlpurple, dlcolors
13
14
plt.style.use('./deeplearning.mplstyle')
15
n_bin = 5
16
dlcm = LinearSegmentedColormap.from_list(
17
'dl_map', dlcolors, N=n_bin)
18
19
##########################################################
20
# Plotting Routines
21
##########################################################
22
23
def plt_house_x(X, y,f_wb=None, ax=None):
24
''' plot house with aXis '''
25
if not ax:
26
fig, ax = plt.subplots(1,1)
27
ax.scatter(X, y, marker='x', c='r', label="Actual Value")
28
29
ax.set_title("Housing Prices")
30
ax.set_ylabel('Price (in 1000s of dollars)')
31
ax.set_xlabel(f'Size (1000 sqft)')
32
if f_wb is not None:
33
ax.plot(X, f_wb, c=dlblue, label="Our Prediction")
34
ax.legend()
35
36
37
def mk_cost_lines(x,y,w,b, ax):
38
''' makes vertical cost lines'''
39
cstr = "cost = (1/m)*("
40
ctot = 0
41
label = 'cost for point'
42
addedbreak = False
43
for p in zip(x,y):
44
f_wb_p = w*p[0]+b
45
c_p = ((f_wb_p - p[1])**2)/2
46
c_p_txt = c_p
47
ax.vlines(p[0], p[1],f_wb_p, lw=3, color=dlpurple, ls='dotted', label=label)
48
label='' #just one
49
cxy = [p[0], p[1] + (f_wb_p-p[1])/2]
50
ax.annotate(f'{c_p_txt:0.0f}', xy=cxy, xycoords='data',color=dlpurple,
51
xytext=(5, 0), textcoords='offset points')
52
cstr += f"{c_p_txt:0.0f} +"
53
if len(cstr) > 38 and addedbreak is False:
54
cstr += "\n"
55
addedbreak = True
56
ctot += c_p
57
ctot = ctot/(len(x))
58
cstr = cstr[:-1] + f") = {ctot:0.0f}"
59
ax.text(0.15,0.02,cstr, transform=ax.transAxes, color=dlpurple)
60
61
##########
62
# Cost lab
63
##########
64
65
66
def plt_intuition(x_train, y_train):
67
68
w_range = np.array([200-200,200+200])
69
tmp_b = 100
70
71
w_array = np.arange(*w_range, 5)
72
cost = np.zeros_like(w_array)
73
for i in range(len(w_array)):
74
tmp_w = w_array[i]
75
cost[i] = compute_cost(x_train, y_train, tmp_w, tmp_b)
76
77
@interact(w=(*w_range,10),continuous_update=False)
78
def func( w=150):
79
f_wb = np.dot(x_train, w) + tmp_b
80
81
fig, ax = plt.subplots(1, 2, constrained_layout=True, figsize=(8,4))
82
fig.canvas.toolbar_position = 'bottom'
83
84
mk_cost_lines(x_train, y_train, w, tmp_b, ax[0])
85
plt_house_x(x_train, y_train, f_wb=f_wb, ax=ax[0])
86
87
ax[1].plot(w_array, cost)
88
cur_cost = compute_cost(x_train, y_train, w, tmp_b)
89
ax[1].scatter(w,cur_cost, s=100, color=dldarkred, zorder= 10, label= f"cost at w={w}")
90
ax[1].hlines(cur_cost, ax[1].get_xlim()[0],w, lw=4, color=dlpurple, ls='dotted')
91
ax[1].vlines(w, ax[1].get_ylim()[0],cur_cost, lw=4, color=dlpurple, ls='dotted')
92
ax[1].set_title("Cost vs. w, (b fixed at 100)")
93
ax[1].set_ylabel('Cost')
94
ax[1].set_xlabel('w')
95
ax[1].legend(loc='upper center')
96
fig.suptitle(f"Minimize Cost: Current Cost = {cur_cost:0.0f}", fontsize=12)
97
plt.show()
98
99
# this is the 2D cost curve with interactive slider
100
def plt_stationary(x_train, y_train):
101
# setup figure
102
fig = plt.figure( figsize=(9,8))
103
#fig = plt.figure(constrained_layout=True, figsize=(12,10))
104
fig.set_facecolor('#ffffff') #white
105
fig.canvas.toolbar_position = 'top'
106
#gs = GridSpec(2, 2, figure=fig, wspace = 0.01)
107
gs = GridSpec(2, 2, figure=fig)
108
ax0 = fig.add_subplot(gs[0, 0])
109
ax1 = fig.add_subplot(gs[0, 1])
110
ax2 = fig.add_subplot(gs[1, :], projection='3d')
111
ax = np.array([ax0,ax1,ax2])
112
113
#setup useful ranges and common linspaces
114
w_range = np.array([200-300.,200+300])
115
b_range = np.array([50-300., 50+300])
116
b_space = np.linspace(*b_range, 100)
117
w_space = np.linspace(*w_range, 100)
118
119
# get cost for w,b ranges for contour and 3D
120
tmp_b,tmp_w = np.meshgrid(b_space,w_space)
121
z=np.zeros_like(tmp_b)
122
for i in range(tmp_w.shape[0]):
123
for j in range(tmp_w.shape[1]):
124
z[i,j] = compute_cost(x_train, y_train, tmp_w[i][j], tmp_b[i][j] )
125
if z[i,j] == 0: z[i,j] = 1e-6
126
127
w0=200;b=-100 #initial point
128
### plot model w cost ###
129
f_wb = np.dot(x_train,w0) + b
130
mk_cost_lines(x_train,y_train,w0,b,ax[0])
131
plt_house_x(x_train, y_train, f_wb=f_wb, ax=ax[0])
132
133
### plot contour ###
134
CS = ax[1].contour(tmp_w, tmp_b, np.log(z),levels=12, linewidths=2, alpha=0.7,colors=dlcolors)
135
ax[1].set_title('Cost(w,b)')
136
ax[1].set_xlabel('w', fontsize=10)
137
ax[1].set_ylabel('b', fontsize=10)
138
ax[1].set_xlim(w_range) ; ax[1].set_ylim(b_range)
139
cscat = ax[1].scatter(w0,b, s=100, color=dlblue, zorder= 10, label="cost with \ncurrent w,b")
140
chline = ax[1].hlines(b, ax[1].get_xlim()[0],w0, lw=4, color=dlpurple, ls='dotted')
141
cvline = ax[1].vlines(w0, ax[1].get_ylim()[0],b, lw=4, color=dlpurple, ls='dotted')
142
ax[1].text(0.5,0.95,"Click to choose w,b", bbox=dict(facecolor='white', ec = 'black'), fontsize = 10,
143
transform=ax[1].transAxes, verticalalignment = 'center', horizontalalignment= 'center')
144
145
#Surface plot of the cost function J(w,b)
146
ax[2].plot_surface(tmp_w, tmp_b, z, cmap = dlcm, alpha=0.3, antialiased=True)
147
ax[2].plot_wireframe(tmp_w, tmp_b, z, color='k', alpha=0.1)
148
plt.xlabel("$w$")
149
plt.ylabel("$b$")
150
ax[2].zaxis.set_rotate_label(False)
151
ax[2].xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
152
ax[2].yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
153
ax[2].zaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
154
ax[2].set_zlabel("J(w, b)\n\n", rotation=90)
155
plt.title("Cost(w,b) \n [You can rotate this figure]", size=12)
156
ax[2].view_init(30, -120)
157
158
return fig,ax, [cscat, chline, cvline]
159
160
161
#https://matplotlib.org/stable/users/event_handling.html
162
class plt_update_onclick:
163
def __init__(self, fig, ax, x_train,y_train, dyn_items):
164
self.fig = fig
165
self.ax = ax
166
self.x_train = x_train
167
self.y_train = y_train
168
self.dyn_items = dyn_items
169
self.cid = fig.canvas.mpl_connect('button_press_event', self)
170
171
def __call__(self, event):
172
if event.inaxes == self.ax[1]:
173
ws = event.xdata
174
bs = event.ydata
175
cst = compute_cost(self.x_train, self.y_train, ws, bs)
176
177
# clear and redraw line plot
178
self.ax[0].clear()
179
f_wb = np.dot(self.x_train,ws) + bs
180
mk_cost_lines(self.x_train,self.y_train,ws,bs,self.ax[0])
181
plt_house_x(self.x_train, self.y_train, f_wb=f_wb, ax=self.ax[0])
182
183
# remove lines and re-add on countour plot and 3d plot
184
for artist in self.dyn_items:
185
artist.remove()
186
187
a = self.ax[1].scatter(ws,bs, s=100, color=dlblue, zorder= 10, label="cost with \ncurrent w,b")
188
b = self.ax[1].hlines(bs, self.ax[1].get_xlim()[0],ws, lw=4, color=dlpurple, ls='dotted')
189
c = self.ax[1].vlines(ws, self.ax[1].get_ylim()[0],bs, lw=4, color=dlpurple, ls='dotted')
190
d = self.ax[1].annotate(f"Cost: {cst:.0f}", xy= (ws, bs), xytext = (4,4), textcoords = 'offset points',
191
bbox=dict(facecolor='white'), size = 10)
192
193
#Add point in 3D surface plot
194
e = self.ax[2].scatter3D(ws, bs,cst , marker='X', s=100)
195
196
self.dyn_items = [a,b,c,d,e]
197
self.fig.canvas.draw()
198
199
200
def soup_bowl():
201
""" Create figure and plot with a 3D projection"""
202
fig = plt.figure(figsize=(8,8))
203
204
#Plot configuration
205
ax = fig.add_subplot(111, projection='3d')
206
ax.xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
207
ax.yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
208
ax.zaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
209
ax.zaxis.set_rotate_label(False)
210
ax.view_init(45, -120)
211
212
#Useful linearspaces to give values to the parameters w and b
213
w = np.linspace(-20, 20, 100)
214
b = np.linspace(-20, 20, 100)
215
216
#Get the z value for a bowl-shaped cost function
217
z=np.zeros((len(w), len(b)))
218
j=0
219
for x in w:
220
i=0
221
for y in b:
222
z[i,j] = x**2 + y**2
223
i+=1
224
j+=1
225
226
#Meshgrid used for plotting 3D functions
227
W, B = np.meshgrid(w, b)
228
229
#Create the 3D surface plot of the bowl-shaped cost function
230
ax.plot_surface(W, B, z, cmap = "Spectral_r", alpha=0.7, antialiased=False)
231
ax.plot_wireframe(W, B, z, color='k', alpha=0.1)
232
ax.set_xlabel("$w$")
233
ax.set_ylabel("$b$")
234
ax.set_zlabel("$J(w,b)$", rotation=90)
235
ax.set_title("$J(w,b)$\n [You can rotate this figure]", size=15)
236
237
plt.show()
238
239
def inbounds(a,b,xlim,ylim):
240
xlow,xhigh = xlim
241
ylow,yhigh = ylim
242
ax, ay = a
243
bx, by = b
244
if (ax > xlow and ax < xhigh) and (bx > xlow and bx < xhigh) \
245
and (ay > ylow and ay < yhigh) and (by > ylow and by < yhigh):
246
return True
247
return False
248
249
def plt_contour_wgrad(x, y, hist, ax, w_range=[-100, 500, 5], b_range=[-500, 500, 5],
250
contours = [0.1,50,1000,5000,10000,25000,50000],
251
resolution=5, w_final=200, b_final=100,step=10 ):
252
b0,w0 = np.meshgrid(np.arange(*b_range),np.arange(*w_range))
253
z=np.zeros_like(b0)
254
for i in range(w0.shape[0]):
255
for j in range(w0.shape[1]):
256
z[i][j] = compute_cost(x, y, w0[i][j], b0[i][j] )
257
258
CS = ax.contour(w0, b0, z, contours, linewidths=2,
259
colors=[dlblue, dlorange, dldarkred, dlmagenta, dlpurple])
260
ax.clabel(CS, inline=1, fmt='%1.0f', fontsize=10)
261
ax.set_xlabel("w"); ax.set_ylabel("b")
262
ax.set_title('Contour plot of cost J(w,b), vs b,w with path of gradient descent')
263
w = w_final; b=b_final
264
ax.hlines(b, ax.get_xlim()[0],w, lw=2, color=dlpurple, ls='dotted')
265
ax.vlines(w, ax.get_ylim()[0],b, lw=2, color=dlpurple, ls='dotted')
266
267
base = hist[0]
268
for point in hist[0::step]:
269
edist = np.sqrt((base[0] - point[0])**2 + (base[1] - point[1])**2)
270
if(edist > resolution or point==hist[-1]):
271
if inbounds(point,base, ax.get_xlim(),ax.get_ylim()):
272
plt.annotate('', xy=point, xytext=base,xycoords='data',
273
arrowprops={'arrowstyle': '->', 'color': 'r', 'lw': 3},
274
va='center', ha='center')
275
base=point
276
return
277
278
279
def plt_divergence(p_hist, J_hist, x_train,y_train):
280
281
x=np.zeros(len(p_hist))
282
y=np.zeros(len(p_hist))
283
v=np.zeros(len(p_hist))
284
for i in range(len(p_hist)):
285
x[i] = p_hist[i][0]
286
y[i] = p_hist[i][1]
287
v[i] = J_hist[i]
288
289
fig = plt.figure(figsize=(12,5))
290
plt.subplots_adjust( wspace=0 )
291
gs = fig.add_gridspec(1, 5)
292
fig.suptitle(f"Cost escalates when learning rate is too large")
293
#===============
294
# First subplot
295
#===============
296
ax = fig.add_subplot(gs[:2], )
297
298
# Print w vs cost to see minimum
299
fix_b = 100
300
w_array = np.arange(-70000, 70000, 1000, dtype="int64")
301
cost = np.zeros_like(w_array,float)
302
303
for i in range(len(w_array)):
304
tmp_w = w_array[i]
305
cost[i] = compute_cost(x_train, y_train, tmp_w, fix_b)
306
307
ax.plot(w_array, cost)
308
ax.plot(x,v, c=dlmagenta)
309
ax.set_title("Cost vs w, b set to 100")
310
ax.set_ylabel('Cost')
311
ax.set_xlabel('w')
312
ax.xaxis.set_major_locator(MaxNLocator(2))
313
314
#===============
315
# Second Subplot
316
#===============
317
318
tmp_b,tmp_w = np.meshgrid(np.arange(-35000, 35000, 500),np.arange(-70000, 70000, 500))
319
tmp_b = tmp_b.astype('int64')
320
tmp_w = tmp_w.astype('int64')
321
z=np.zeros_like(tmp_b,float)
322
for i in range(tmp_w.shape[0]):
323
for j in range(tmp_w.shape[1]):
324
z[i][j] = compute_cost(x_train, y_train, tmp_w[i][j], tmp_b[i][j] )
325
326
ax = fig.add_subplot(gs[2:], projection='3d')
327
ax.plot_surface(tmp_w, tmp_b, z, alpha=0.3, color=dlblue)
328
ax.xaxis.set_major_locator(MaxNLocator(2))
329
ax.yaxis.set_major_locator(MaxNLocator(2))
330
331
ax.set_xlabel('w', fontsize=16)
332
ax.set_ylabel('b', fontsize=16)
333
ax.set_zlabel('\ncost', fontsize=16)
334
plt.title('Cost vs (b, w)')
335
# Customize the view angle
336
ax.view_init(elev=20., azim=-65)
337
ax.plot(x, y, v,c=dlmagenta)
338
339
return
340
341
# draw derivative line
342
# y = m*(x - x1) + y1
343
def add_line(dj_dx, x1, y1, d, ax):
344
x = np.linspace(x1-d, x1+d,50)
345
y = dj_dx*(x - x1) + y1
346
ax.scatter(x1, y1, color=dlblue, s=50)
347
ax.plot(x, y, '--', c=dldarkred,zorder=10, linewidth = 1)
348
xoff = 30 if x1 == 200 else 10
349
ax.annotate(r"$\frac{\partial J}{\partial w}$ =%d" % dj_dx, fontsize=14,
350
xy=(x1, y1), xycoords='data',
351
xytext=(xoff, 10), textcoords='offset points',
352
arrowprops=dict(arrowstyle="->"),
353
horizontalalignment='left', verticalalignment='top')
354
355
def plt_gradients(x_train,y_train, f_compute_cost, f_compute_gradient):
356
#===============
357
# First subplot
358
#===============
359
fig,ax = plt.subplots(1,2,figsize=(12,4))
360
361
# Print w vs cost to see minimum
362
fix_b = 100
363
w_array = np.linspace(-100, 500, 50)
364
w_array = np.linspace(0, 400, 50)
365
cost = np.zeros_like(w_array)
366
367
for i in range(len(w_array)):
368
tmp_w = w_array[i]
369
cost[i] = f_compute_cost(x_train, y_train, tmp_w, fix_b)
370
ax[0].plot(w_array, cost,linewidth=1)
371
ax[0].set_title("Cost vs w, with gradient; b set to 100")
372
ax[0].set_ylabel('Cost')
373
ax[0].set_xlabel('w')
374
375
# plot lines for fixed b=100
376
for tmp_w in [100,200,300]:
377
fix_b = 100
378
dj_dw,dj_db = f_compute_gradient(x_train, y_train, tmp_w, fix_b )
379
j = f_compute_cost(x_train, y_train, tmp_w, fix_b)
380
add_line(dj_dw, tmp_w, j, 30, ax[0])
381
382
#===============
383
# Second Subplot
384
#===============
385
386
tmp_b,tmp_w = np.meshgrid(np.linspace(-200, 200, 10), np.linspace(-100, 600, 10))
387
U = np.zeros_like(tmp_w)
388
V = np.zeros_like(tmp_b)
389
for i in range(tmp_w.shape[0]):
390
for j in range(tmp_w.shape[1]):
391
U[i][j], V[i][j] = f_compute_gradient(x_train, y_train, tmp_w[i][j], tmp_b[i][j] )
392
X = tmp_w
393
Y = tmp_b
394
n=-2
395
color_array = np.sqrt(((V-n)/2)**2 + ((U-n)/2)**2)
396
397
ax[1].set_title('Gradient shown in quiver plot')
398
Q = ax[1].quiver(X, Y, U, V, color_array, units='width', )
399
ax[1].quiverkey(Q, 0.9, 0.9, 2, r'$2 \frac{m}{s}$', labelpos='E',coordinates='figure')
400
ax[1].set_xlabel("w"); ax[1].set_ylabel("b")
401
402