随机梯度下降特点:
·每次更新数据只选取一个样本
优点:
·相比于批量梯度,这样的方法更快,更快收敛,虽然不是全局最优,但很多时候是我们可以接受的
代码
首先导入包
import matplotlib.pyplot as plt
import numpy as np
数据的准备
# x = np.array([[-1., 2.], [0., 0.], [0., 2.], [1., 0]])
x = np.array([[0., 2.], [1., 0], [-1., 2.], [0., 0.]])
# y = np.array([1, 1, -1, -1])
y = np.array([-1, -1, 1, 1])
可视化函数
def plot_plot(x, omega, b):
xx = np.linspace(-5, 5, 100)
yy = - 1 / omega[1] * (omega[0] * xx + b)
plt.figure()
plt.scatter(x[:, 0], x[:, 1], c=y)
plt.plot(xx, yy)
plt.xlabel('x1')
plt.ylabel('x2')
plt.title('({}) * x1 + ({}) * x2 + ({}) = 0'.format(*omega, b))
plt.xlim(-3, 3)
plt.ylim(-3, 3)
plt.grid()
随机初始化
omega = np.array([0., 0.])
b = 0.0
eta = 1.0
感知机函数
def sign(pp, b, omega):
return np.sign(np.dot(pp, omega) + b)
定义判断感知机分类对错的函数(选取错的点来优化)
def error_value(x, y):
x_f = []
y_f = []
check = False
while not check:
check = True
for xi, yi in zip(x, y):
if sign(xi, b, omega) * yi <= 0:
x_f.append(xi)
y_f.append(yi)
return x_f, y_f
进行判断和优化
i = 1
check = False
while not check:
x_f, y_f = error_value(x, y)
if len(x_f) == 0:
print("最终梯度下降得到的omega和b分别是:", omega, b)
break
index = np.random.randint(0, len(x_f), 1)[0] # 体现出"随机"
x_tem = x_f[index]
y_tem = y_f[index]
omega = omega - eta * (-np.dot(x_tem, y_tem)) # 体现出"梯度下降"
b = b - eta * (-y_tem)
# print(omega)
print("第{0}此迭代分错的样本为:".format(i), x_f)
i+=1
Out
第1此迭代分错的样本为: [array([0., 2.]), array([1., 0.]), array([-1., 2.]), array([0., 0.])]
第2此迭代分错的样本为: [array([0., 2.]), array([1., 0.])]
第3此迭代分错的样本为: [array([0., 2.]), array([0., 0.])]
第4此迭代分错的样本为: [array([0., 0.])]
第5此迭代分错的样本为: [array([0., 2.]), array([0., 0.])]
第6此迭代分错的样本为: [array([-1., 2.]), array([0., 0.])]
第7此迭代分错的样本为: [array([0., 2.]), array([0., 0.])]
第8此迭代分错的样本为: [array([0., 2.])]
第9此迭代分错的样本为: [array([-1., 2.]), array([0., 0.])]
第10此迭代分错的样本为: [array([0., 2.])]
第11此迭代分错的样本为: [array([-1., 2.]), array([0., 0.])]
第12此迭代分错的样本为: [array([0., 2.])]
第13此迭代分错的样本为: [array([0., 0.])]
最终梯度下降得到的omega和b分别是: [-5. -2.] 1.0
可视化
plot_plot(x, omega, b)
plt.show()
可改进之处:在“进行判断和优化”的代码里面直接打乱数据的顺序,使得能够随机选取一个数进行优化