Skip to content

Commit 31e3df4

Browse files
committed
对p1进行了大修,修复了图1和图2显示错误的bug。原因是所有的losses没有做转置。矩阵和绘图用的坐标系起点不同。
1 parent 3dfd35e commit 31e3df4

File tree

3 files changed

+199
-49
lines changed

3 files changed

+199
-49
lines changed

p1 gradient descent.py

+49-41
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@
22
import matplotlib.pyplot as plt
33
from mpl_toolkits.mplot3d import Axes3D
44
# 本代码是一个最简单的线形回归问题,优化函数为经典的gradient descent
5-
rate = 1e-2 # learning rate
5+
rate = 0.2 # learning rate
66
def da(y,y_p,x):
77
return (y-y_p)*(-x)
88

99
def db(y,y_p):
1010
return (y-y_p)*(-1)
11-
11+
def calc_loss(a,b,x,y):
12+
tmp = y - (a * x + b)
13+
tmp = tmp ** 2 # 对矩阵内的每一个元素平方
14+
SSE = sum(tmp) / (2 * len(x))
15+
return SSE
1216
def draw_hill(x,y):
1317
a = np.linspace(-20,20,100)
1418
print(a)
@@ -21,52 +25,54 @@ def draw_hill(x,y):
2125
for bi in range(0,len(b)):
2226
a0 = a[ai]
2327
b0 = b[bi]
24-
tmp = y - (a0*x + b0)
25-
tmp = tmp**2 # 对矩阵内的每一个元素平方
26-
SSE = sum(tmp)/2
28+
SSE = calc_loss(a=a0,b=b0,x=x,y=y)
2729
allSSE[ai][bi] = SSE
2830

2931
a,b = np.meshgrid(a, b)
3032

3133
return [a,b,allSSE]
32-
# simulated data
34+
# 模拟数据
3335
x = [30 ,35,37, 59, 70, 76, 88, 100]
3436
y = [1100, 1423, 1377, 1800, 2304, 2588, 3495, 4839]
3537

36-
3738
# 数据归一化
3839
x_max = max(x)
3940
x_min = min(x)
4041
y_max = max(y)
4142
y_min = min(y)
42-
# x_mean = np.mean(x)
43+
4344
for i in range(0,len(x)):
4445
x[i] = (x[i] - x_min)/(x_max - x_min)
4546
y[i] = (y[i] - y_min)/(y_max - y_min)
4647

4748
[ha,hb,hallSSE] = draw_hill(x,y)
48-
49+
hallSSE = hallSSE.T# 重要,将所有的losses做一个转置。原因是矩阵是以左上角至右下角顺序排列元素,而绘图是以左下角为原点。
4950
# 初始化a,b值
50-
a = 10
51-
b = -20
52-
fig4 = plt.figure(4,figsize=(12,8))
51+
a = 10.0
52+
b = -20.0
53+
fig = plt.figure(1, figsize=(12, 8))
54+
55+
# 绘制图1的曲面
56+
ax = fig.add_subplot(2, 2, 1, projection='3d')
57+
ax.set_top_view()
58+
ax.plot_surface(ha, hb, hallSSE, rstride=2, cstride=2, cmap='rainbow')
59+
60+
# 绘制图2的等高线图
5361
plt.subplot(2,2,2)
54-
plt.contourf(ha,hb,hallSSE,15,alpha=0.75,cmap=plt.cm.hot)
62+
ta = np.linspace(-20, 20, 100)
63+
tb = np.linspace(-20, 20, 100)
64+
plt.contourf(ha,hb,hallSSE,15,alpha=0.5,cmap=plt.cm.hot)
5565
C = plt.contour(ha,hb,hallSSE,15,colors='black')
5666
plt.clabel(C,inline=True)
5767
plt.xlabel('a')
5868
plt.ylabel('b')
59-
plt.xticks()
60-
plt.yticks()
61-
# plt.show()
62-
# plot bowl
63-
ax = fig4.add_subplot(2, 2, 1, projection='3d')
64-
ax.plot_surface(ha, hb, hallSSE, rstride=2, cstride=2, cmap='rainbow')
69+
6570
plt.ion() # iteration on
66-
all_a = []
67-
all_b = []
71+
6872
all_loss = []
6973
all_step = []
74+
last_a = a
75+
last_b = b
7076
for step in range(1,500):
7177
loss = 0
7278
all_da = 0
@@ -76,36 +82,38 @@ def draw_hill(x,y):
7682
loss = loss + (y[i] - y_p)*(y[i] - y_p)/2
7783
all_da = all_da + da(y[i],y_p,x[i])
7884
all_db = all_db + db(y[i],y_p)
85+
#loss_ = calc_loss(a = a,b=b,x=np.array(x),y=np.array(y))
86+
loss = loss/len(x)
7987

80-
a = a - rate*all_da
81-
b = b - rate*all_db
82-
83-
all_a.append(a)
84-
all_b.append(b)
85-
all_loss.append(loss)
86-
all_step.append(step)
87-
88-
# plot gradient descent point
88+
# 绘制图1中的loss点
8989
ax.scatter(a, b, loss, color='black')
90-
90+
# 绘制图2中的loss点
9191
plt.subplot(2,2,2)
92-
plt.scatter(a,b,loss,color='blue')
93-
94-
# plot lines
95-
plt.subplot(2,2,3)
96-
plt.plot(x,y)
97-
plt.plot(x,y,'o')
92+
plt.scatter(a,b,s=5,color='blue')
93+
plt.plot([last_a,a],[last_b,b],color='aqua')
94+
# 绘制图3中的回归直线
95+
plt.subplot(2, 2, 3)
96+
plt.plot(x, y)
97+
plt.plot(x, y, 'o')
9898
x_ = np.linspace(0, 1, 2)
9999
y_draw = a * x_ + b
100-
plt.plot(x_,y_draw)
101-
102-
# plot losses
100+
plt.plot(x_, y_draw)
101+
# 绘制图4的loss更新曲线
102+
all_loss.append(loss)
103+
all_step.append(step)
103104
plt.subplot(2,2,4)
104105
plt.plot(all_step,all_loss,color='orange')
105106
plt.xlabel("step")
106107
plt.ylabel("loss")
107108

108-
if step%10 == 0:
109+
110+
# print('a = %.3f,b = %.3f' % (a,b))
111+
last_a = a
112+
last_b = b
113+
a = a - rate*all_da
114+
b = b - rate*all_db
115+
116+
if step%1 == 0:
109117
print("step: ", step, " loss: ", loss)
110118
plt.show()
111119
plt.pause(0.01)

p4 momentum.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def db(y,y_p):
1212
return (y-y_p)*(-1)
1313

1414
def draw_hill(x,y):
15-
a = np.linspace(-20,20,100)
15+
a = np.linspace(-5,18,100)
1616
print(a)
1717
b = np.linspace(-20,20,100)
1818
x = np.array(x)
@@ -68,8 +68,8 @@ def get_batch_data(x,y,batch=3):
6868

6969
# 绘制等高线图
7070
plt.subplot(2,2,2)
71-
plt.contourf(ha,hb,hallSSE,15,alpha=0.75,cmap=plt.cm.hot)
72-
C = plt.contour(ha,hb,hallSSE,15,colors='black')
71+
plt.contourf(ha,hb,hallSSE,30,alpha=0.75,cmap=plt.cm.hot)
72+
C = plt.contour(ha,hb,hallSSE,10,colors='black')
7373
plt.clabel(C,inline=True)
7474
plt.xlabel('a')
7575
plt.ylabel('b')
@@ -98,7 +98,7 @@ def get_batch_data(x,y,batch=3):
9898

9999
all_da = all_da + da(y[i],y_p,x[i])
100100
all_db = all_db + db(y[i],y_p)
101-
101+
loss = loss/len(x)
102102
va = gamma * last_va + rate*all_da
103103
vb = gamma * last_vb + rate*all_db
104104

@@ -114,11 +114,11 @@ def get_batch_data(x,y,batch=3):
114114
all_step.append(step)
115115

116116
# plot gradient descent point
117-
ax.scatter(a, b, loss/len(x), color='black')
117+
ax.scatter(a, b, loss, color='black')
118118

119119
# plot on contour
120120
plt.subplot(2,2,2)
121-
plt.scatter(a,b,loss/len(x),color='blue',marker='.',linewidths=0.1)
121+
plt.scatter(a,b,3,color='blue',marker='.')
122122

123123
# plot lines
124124
plt.subplot(2,2,3)
@@ -134,9 +134,9 @@ def get_batch_data(x,y,batch=3):
134134
plt.xlabel("step")
135135
plt.ylabel("loss")
136136

137-
if step%10 == 0:
137+
if step%1 == 0:
138138
print("step: ", step, " loss: ", loss)
139139
plt.show()
140-
plt.pause(0.01)
140+
plt.pause(5)
141141
plt.show()
142142
plt.pause(99999999999)

p5 Nesterov.py

+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
from mpl_toolkits.mplot3d import Axes3D
4+
import random
5+
# 本代码是一个最简单的线形回归问题,优化函数为 NAG (Nesterov accelerated gradient),该优化函数基于momentum改进而来
6+
7+
rate = 1e-2 # learning rate
8+
def da(y,y_p,x):
9+
return (y-y_p)*(-x)
10+
11+
def db(y,y_p):
12+
return (y-y_p)*(-1)
13+
14+
def draw_hill(x,y):
15+
a = np.linspace(-10,15,100)
16+
print(a)
17+
b = np.linspace(-20,20,100)
18+
x = np.array(x)
19+
y = np.array(y)
20+
21+
allSSE = np.zeros(shape=(len(a),len(b)))
22+
for ai in range(0,len(a)):
23+
for bi in range(0,len(b)):
24+
a0 = a[ai]
25+
b0 = b[bi]
26+
tmp = y - (a0*x + b0)
27+
tmp = tmp**2 # 对矩阵内的每一个元素平方
28+
SSE = sum(tmp)/(2*len(x))
29+
allSSE[ai][bi] = SSE
30+
31+
a,b = np.meshgrid(a, b)
32+
33+
return [a,b,allSSE]
34+
35+
def shuffle_data(x,y):
36+
# 随机打乱x,y的数据,并且保持x和y一一对应
37+
seed = random.random()
38+
random.seed(seed)
39+
random.shuffle(x)
40+
random.seed(seed)
41+
random.shuffle(y)
42+
43+
def get_batch_data(x,y,batch=3):
44+
shuffle_data(x,y)
45+
x_new = x[0:batch]
46+
y_new = y[0:batch]
47+
return [x_new,y_new]
48+
# simulated data
49+
x = [30 , 35, 37, 59, 70, 76, 88, 100]
50+
y = [1100, 1423, 1377, 1800, 2304, 2588, 3495, 4839]
51+
52+
53+
# 数据归一化
54+
x_max = max(x)
55+
x_min = min(x)
56+
y_max = max(y)
57+
y_min = min(y)
58+
for i in range(0,len(x)):
59+
x[i] = (x[i] - x_min)/(x_max - x_min)
60+
y[i] = (y[i] - y_min)/(y_max - y_min)
61+
62+
[ha,hb,hallSSE] = draw_hill(x,y)
63+
64+
# 初始化a,b值
65+
a = 10
66+
b = -20
67+
fig4 = plt.figure(4,figsize=(12,8))
68+
69+
# 绘制等高线图
70+
plt.subplot(2,2,2)
71+
plt.contourf(ha,hb,hallSSE,15,alpha=0.75,cmap=plt.cm.hot)
72+
C = plt.contour(ha,hb,hallSSE,15,colors='black')
73+
plt.clabel(C,inline=True)
74+
plt.xlabel('a')
75+
plt.ylabel('b')
76+
plt.xticks()
77+
plt.yticks()
78+
# plt.show()
79+
# plot bowl
80+
ax = fig4.add_subplot(2, 2, 1, projection='3d')
81+
ax.plot_surface(ha, hb, hallSSE, rstride=2, cstride=2, cmap='rainbow')
82+
plt.ion() # iteration on
83+
all_a = []
84+
all_b = []
85+
all_loss = []
86+
all_step = []
87+
last_va = 0 # momentum
88+
last_vb = 0
89+
gamma = 0.9
90+
for step in range(1,500):
91+
loss = 0
92+
all_da = 0
93+
all_db = 0
94+
95+
for i in range(0,len(x)):
96+
y_p = a*x[i] + b
97+
loss = loss +(y[i] - y_p)*(y[i] - y_p)/2
98+
99+
all_da = all_da + da(y[i],y_p,x[i])
100+
all_db = all_db + db(y[i],y_p)
101+
102+
va = gamma * last_va + rate*all_da
103+
vb = gamma * last_vb + rate*all_db
104+
105+
a = a - va
106+
b = b - vb
107+
108+
last_va = va
109+
last_vb = vb
110+
111+
all_a.append(a)
112+
all_b.append(b)
113+
all_loss.append(loss)
114+
all_step.append(step)
115+
116+
# plot gradient descent point
117+
ax.scatter(a, b, loss/len(x), color='black')
118+
119+
# plot on contour
120+
plt.subplot(2,2,2)
121+
plt.scatter(a,b,loss/len(x),color='blue',marker='.',linewidths=0.1)
122+
123+
# plot lines
124+
plt.subplot(2,2,3)
125+
plt.plot(x,y)
126+
plt.plot(x,y,'o')
127+
x_ = np.linspace(0, 1, 2)
128+
y_draw = a * x_ + b
129+
plt.plot(x_,y_draw)
130+
131+
# plot losses
132+
plt.subplot(2,2,4)
133+
plt.plot(all_step,all_loss,color='orange')
134+
plt.xlabel("step")
135+
plt.ylabel("loss")
136+
137+
if step%10 == 0:
138+
print("step: ", step, " loss: ", loss)
139+
plt.show()
140+
plt.pause(0.01)
141+
plt.show()
142+
plt.pause(99999999999)

0 commit comments

Comments
 (0)