tensorflow之非线性规划

这次做的是使用tensorflow进行非线性规划,对原始数据点学习拟合。

  • 首先,载入需要的模块
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
  • 然后,生成原始数据点,构建函数。
# using numpy to create 200 random values
x_data = np.linspace(-0.5,0.5,200)[:,np.newaxis]
noise = np.random.normal(0,0.02,x_data.shape)
y_data = np.square(x_data) + noise  # y_data = (x_data)^2 + noise

这里需要提一下numpy中的random里的normal函数,它就是数学上的高斯分布(正态分布)。具体函数写法为:

numpy.random.normal(loc=0.0, scale=1.0, size=None)

 参数的意义为:

loc:float
    此概率分布的均值(对应着整个分布的中心centre)
scale:float
    此概率分布的标准差(对应于分布的宽度,scale越大越矮胖,scale越小,越瘦高)
size:int or tuple of ints
    输出的shape,默认为None,只输出一个值

那么上述代码中的noise就是生成均值为0,标准差为0.02,且与x_data形状相同的高斯分布。

  •  接着,创建神经网络的中间层
# create two placeholders
x = tf.placeholder(tf.float32,[None,1])
y = tf.placeholder(tf.float32,[None,1])

# create hidden layer
Weights_L1 = tf.Variable(tf.random_normal([1,10]))
biases_L1 = tf.Variable(tf.zeros([1,10]))
Wx_plus_b_L1 = tf.matmul(x,Weights_L1) + biases_L1
L1 = tf.nn.tanh(Wx_plus_b_L1)

 tf中也有类似numpy.random.normal()的函数:tf.random_naomal

tf.random_normal()函数用于从服从指定正太分布的数值中取出指定个数的值。

tf.random_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)

 参数意义为:

    shape: 输出张量的形状,必选
    mean: 正态分布的均值,默认为0
    stddev: 正态分布的标准差,默认为1.0
    dtype: 输出的类型,默认为tf.float32
    seed: 随机数种子,是一个整数,当设置之后,每次生成的随机数都一样
    name: 操作的名称

 所以这里的系数矩阵Weight_L1是1行10列,数据为随机的标准正态分布的值。

这里的重点是———激励函数(activation function)

 由于博主水平有限,拜读了一位大佬的博客,讲的不错,参考   这个  就行了。

这里用的是tanh()激励函数,如大佬所说,有一定的缺点,无法解决软饱和性,不能解决梯度消失问题。

  • 然后是创建神经网络输出层:
# define output layer
Weights_L2 = tf.Variable(tf.random_normal([10,1]))
biases_L2 = tf.Variable(tf.zeros([1,1]))
Wx_plus_b_L2 = tf.matmul(L1,Weights_L2) + biases_L2
prediction = tf.nn.tanh(Wx_plus_b_L2)
  • 创建代价函数和优化器:
# quadratic cost function
loss = tf.reduce_mean(tf.square(y - prediction))
# training with gradient descent
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

优化器也有一篇博客讲的不错,参见   这里

常见的优化器是optimizer基类,但基本不会直接使用,而是用到它的子类:

GradientDescentOptimizer(learning_rate)

括号中的是训练模型的学习速率,这个指的是每次学习后更新的幅度大小。所以,如果设置过大的话(一般不会超过1),幅度变化也快,那么损耗的肯定就越多;太小的话效率不高,严重吃内存。

值得一提的是,tensorflow中的学习速率是可以自适应更改的。

tf.train.exponential_decay(learning_rate, global_step, decay_steps, decay_rate, staircase=False, name=None)

 写成数学表达式就是:

decayed_learning_rate=learning_rate×decay_rate^(global_step/decay_steps)

第一个参数learning_rate即初始学习速率,第二个参数,global_step是用来计算步骤的,每调用一次优化器,即自增1,第三个参数,decay_steps通常设为一个常数,如数学公式中所示,与第五个参数配合使用效果较好,第五个参数staircase如果设置为True,那么指数部分就会采用整除策略,表示每decay_step,学习速率变为原来的decay_rate,至于第四个参数decay_rate表示的是学习速率的下降倍率。

更多更详细的关于学习速率的设置,参见  这里

  •  最后就是常规做法
init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    for step in range(2001):
        sess.run(train_step,feed_dict={x:x_data,y:y_data})
        if step % 200 == 0:
            print(step,sess.run(loss,feed_dict={x:x_data,y:y_data}))

    # retrieve prediction values using matplot
    prediction_value = sess.run(prediction,feed_dict={x:x_data})
    plt.figure()
    plt.scatter(x_data,y_data)
    plt.plot(x_data,prediction_value,'r-',lw=5)
    plt.show()
  •  输出结果如下:
0 0.0649974
200 0.00542269
400 0.0033273
600 0.00214143
800 0.00145638
1000 0.00106146
1200 0.000833334
1400 0.000700014
1600 0.000620565
1800 0.000572079
2000 0.000541712

 还有plt的图:

曲线拟合结果良好。


但这个程序还有可以改进的地方,比如神经网络定义层 的时候重复代码过多,可以考虑写成函数;

画图可以采用一种动态显示的方法,使学习过程可视化,看起来更直观、更有说服力。

如果改成线性规划,则把y_data关于x_data的函数写成一次的就可以了。

猜你喜欢

转载自blog.csdn.net/HollyRan/article/details/86167632