梯度下降

梯度下降(随性的)

本文摘要

1.捏造一些用于拟合模型的数据

2.编写代价函数

3.编写梯度下降算法

捏造数据

​ 因为手头没有数据,所以决定随机生成一批数据来进行拟合,因为存粹是尝试复现算法,所以姑且容忍这样射箭画靶子的行为。

1
2
3
4
5
6
7
import random
import numpy
data = numpy.empty((2,100))
for i in range(100):
data[1][i] = random.randint(1,10)
data[0][i] = 100-data[1][i]*random.uniform(1,1.2)*2-pow(random.uniform(1,10),1.2)+pow(random.uniform(1,1.8),4)*3
print(data)
image-20221127224625722

看起来还可以,蛮随机的

代价函数

$$
y=\theta_1x+\theta_2
$$

以上时我假定的一元回归模型,现在我们有一个模型,几个参数和一堆数据,对参数θ构建代价函数 J(θ)(cost function),通过求 J(θ)的最小值来求得最合适的参数。这个代价函数可以用离均平方和来计算

然后开始写我们的cost function

1
2
3
4
5
6
7
8
9
10
def cost_function(theta1,theta2,data):
cost = 0
for i in range(len(data[0])):
print(f'x is: {data[1][i]}')
print(f'x is: {data[0][i]}')
cost = cost+ pow(data[1][i]- (data[0][i]*theta1+theta2),2)
print(f'cost is: {cost}')
cost = 0.5*cost*(1/len(data[0]))
return cost
print(cost_function(2,90,data))

可以了,完美,现在我们画画图看看

2

数据、模型、和代价函数,运行良好

3

θ2为80、90、100时θ1的代价函数

梯度下降

梯度下降采用了一个逐步逼进的方法,选定一个下降率α,就可以逐步,慢慢的或者快快的得到我们最合适的参数
$$
\theta_1:=\theta_1-\alpha\frac{d}{d\theta_1}J(\theta1)
$$
4

搓了一个,结果乱七八糟

经过十几分钟的尝试,终于找到了问题所在

1.α下降率设的太大了,我以为0.1是一个合适的值,但不是,太大了,直接飞出去了,导致参数爆了

2.没有做参数的标准化,两个参数插了两个量级….

其实在视频里早都提到了这两个问题,但是真的实践起来,还是和理论有些脱节的,一时间没想到,不过也好,这样理解相当深了

5

勉强跑起来的梯度下降

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
t1,t2=-2,0
a = 0.00001
dx=0.01
deri1,deri2 = 0,0
# print((cost_function(-2+dx,90,data)-cost_function(-2,90,data))/dx)
plt.plot(range(20), numpy.array(range(20)) * t1 + t2*100)
for i in range(30):
t2t= t2*100
# print(cost_function(t1,t2,data),cost_function(t1+dx,t2,data),dx)
deri1 = (cost_function(t1+dx,t2,data)-cost_function(t1,t2,data))/dx
deri2 = (cost_function(t1,t2+dx,data)-cost_function(t1,t2,data))/dx
# print(deri1,deri2)
t1 = t1 - a*deri1
t2 = t2 - a*deri2
plt.plot(range(20), numpy.array(range(20)) * t1 + t2*100)

print(t1,t2)
# plt.plot(range(20),numpy.array(range(20))*t1+t2)

这是具体的梯度下降实现,下降率0.00001

6

十万次迭代得到的极致模型

完整代码见下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import random
import numpy
import matplotlib.pyplot as plt
data = numpy.empty((2,100))
for i in range(100):
data[1][i] = random.uniform(0,20)
data[0][i] = 100-data[1][i]*random.uniform(1,1.2)*2-pow(random.uniform(1,10),1.2)+pow(random.uniform(1,1.8),4)*3
# print(data)
plt.figure(0)
plt.scatter(data[1],data[0])
# plt.show()

def cost_function(theta1,theta2,data):
cost = 0
for i in range(len(data[0])):
# print("x is: ")
# print(data[1][i])
# print("y is: ")
# print(data[0][i])
cost = cost+ pow(data[1][i]- (data[0][i]*theta1+theta2*50),2)
# print("cost is: ")
# print(cost)
cost = 0.5*cost*(1/len(data[0]))
return cost

# print(deri(cost_function()))
print(cost_function(-2,90,data))
t1=-2
t2=0.3
a = 0.000001
dx=0.001
deri1 = 0
deri2 = 0
n=100000
# print((cost_function(-2+dx,90,data)-cost_function(-2,90,data))/dx)
plt.plot(range(20), numpy.array(range(20)) * t1 + t2*100)
t1ar=numpy.empty(n)
t2ar=numpy.empty(n)
for i in range(n):
t2t= t2*100
# print(cost_function(t1,t2,data),cost_function(t1+dx,t2,data),dx)
deri1 = (cost_function(t1+dx,t2,data)-cost_function(t1,t2,data))/dx
deri2 = (cost_function(t1,t2+dx,data)-cost_function(t1,t2,data))/dx
# print(deri1,deri2)
t1 = t1 - a*deri1
t2 = t2 - a*deri2
t1ar[i] = t1
t2ar[i] = t2
if(i % (n/20)==0):
plt.plot(range(20), numpy.array(range(20)) * t1 + t2*100)

print(t1,t2)
print("cost is ")
print(cost_function(t1,t2,data))
# plt.plot(range(20),numpy.array(range(20))*t1+t2)
plt.figure(1)
plt.plot(range(n),t1ar)
plt.plot(range(n),t2ar)
plt.show()