weights[i] += 0.2 * layer.T.dot(delta) #0.2学习效率,应该是一个小于0.5的数,
同时在 tensorflow实例(2)--机器学习初试 篇文章中用tensorflow实现上述的神经网络算法,该文中也有一句
train=tf.train.GradientDescentOptimizer(0.25).minimize(loss) #梯度下降优化器,0.25学习效率,应该是一个小于0.5的数,
这两句里都有一个学习率的参数,
在 tensorflow实例(6)--机器学习中学习率的实验 中得到一个结论
当神经元越多时,我们的学习率应该越小,同时学习次数应该增加
在这三个案例中,都使用到了学习率,同时在第三例中的结论并不完全,因为这里的学习率其实和梯度下降法息息相关2、使用一元的原因,是为了matplotlib.pyplot显示的了,本文中的梯度下降函数是可适用于多元线性方程的
# -*- coding:utf-8 -*-
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
#构建数据
#带有后缀_data的变量是简单虚拟出来的数据,相当于实际后的样本数据,
#不含后缀_data的变量就是我们建模时的变量,也就是我们最后的求解
def create_data(a,b):
'''
一元一次的方程为y=a*x+b 在构建这个数据时,x_data[:,0]为0-99 代表的是X的坐表,x_data[:,1]为常量1
,因为我们后面要用到矩阵乘法和b,相当于留个位给b,用于计算
y最后np.random.uniform(0,1,[100])*(b/2),产生一个随机数,
这样使得y的数据更加真实也更能看出梯度下降后的效果,以下是x的值,y值根据a,b的值的不同发生变化
[[ 0. 1.]
[ 1. 1.]
[ 2. 1.]
...
[99. 1.]
'''
x=np.array([np.arange(100),np.ones(100)]).T
y = x[:,0]*a + b + np.random.uniform(-1,1,[100])*b
return x,y
x_data,y_data=create_data(2,25)
weight=np.ones(x_data.shape[1]) #初始化weight,其实这个weight的最后一个相当于b的位置
xt=x_data.T
weightStep=[]#用于存存下降过程中计算结果,后面绘图需要
for i in range(100000):
y=np.dot(x_data,weight) #以weight为参数计测试值
loss=y-y_data #计算实际值与测试值之间的差额
#也是cost,并不参于最后计算,这是一种简单方法loss的一个转换,由100个数据转为一个数据
#简单的公式推导一下就可以发现,如果y和y_data相等时,cost=0,当然因为我们加了随机数,等于0是不可能的
#可以将这个理解为返映测试值y的好坏的一个值,当这个值越小时说明我们的weight质量越好,
cost=np.sum(loss ** 2) / (2 * x_data.shape[0])
gradient=np.dot(xt,loss) / x_data.shape[0] # 计算梯度
#0.0005就是学习率,如果简单将这个值调大,就会造成weight往无限大的方向扩大,当然太小的话计算次数也需要增加
#前面说的,当神经元越多时,我们的学习率应该越小,同时学习次数应该增加,,最终原因也在这
weight=weight-0.0005*gradient
if i % 20000==0 or i <10:#每10000次显示一次结果,之所以还i <10因为前期数值变化明显,后面变化其实并不大
print(i,cost,weight)
weightStep.append(weight)
weightStep.append(weight)
plt.axis([0,110,0,150]) # 用于定义X,Y轴的范围
plt.scatter(x_data[:,0],y_data,c='b') # 后面图中蓝色的点为样本数据
plt.ion()#该命令的作用是plt.show()是不暂停,
plt.show()
pltStep=None
for weight in weightStep:
if pltStep!=None : pltStep.remove();#如果绘制过了红点,则清除,进行下一次的绘制
y=np.dot(x_data,weight)
print(weight,y_data[0],y[0])
pltStep=plt.scatter(x_data[:,0],y,c='r') # 后面图中红色的点为计算出来的数据,因为是一元一次,组成的应该是一条直线
plt.pause(0.6)#暂停0.6秒
#通过图案可以看到一开始的红点直线和原来蓝点毫无关联,但最后,基本中从散点分布的蓝点中间穿过,也证明了我们的梯度降维是有效的