这里我们运用简单的神经网络模拟一下股票的收盘价格,是一个学习的示例。
首先要知道,股票曲线图的参数意义:
这个曲线图主要记录股票的开盘价格和收盘价格,如果开盘价格低于收盘价格,那么证明这个股票在增长,每天的规律如此,所以,在下面,首先定义股票价格的座标图如下:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
data = np.linspace(1, 15, 15) # linspace的功能用来创建等差数列
endPrice = np.array([2511.6, 2538.6, 2510.3, 2591.6, 2732.9, 2701.69, 2702.69, 2703.69, 2704.69, 2721.69, 2711.69, 2711.69, 2721.69, 2731.69, 2741.69]) # 收盘价格
beginPrice = np.array([2438.7, 2500.9, 2534.9, 2512.6, 2594.6, 2743.26, 2753.26, 2752.26, 2754.26, 2751.26, 2732.26, 2725.26, 2745.26, 2756.26, 2737.26]) # 开盘价格
print(data) # 1-15天
plt.figure()
for i in range(0, 15):
'''柱状图'''
dateOne = np.zeros([2]) # 生成一个一行两列全为0的矩阵,分别赋值
dateOne[0] = i
dateOne[1] = i
priceOne = np.zeros([2])
priceOne[0] = beginPrice[i]
priceOne[1] = endPrice[i]
if endPrice[i] > beginPrice[i]:
plt.plot(dateOne, priceOne, 'r', lw=8) # 如果收盘价格高于开盘价格,则柱状图为红色
else:
plt.plot(dateOne, priceOne, 'g', lw=8) # 如果开盘价格高于收盘价格,则柱状图为绿色
plt.show()
画出来的结果图为:
首先,这个原始的柱状图,画出来了,股票图形的绘制就是这样了。接下来的就是神经网络的认识了:
首先矩阵相乘的知识,我们要知道:
L1(a,b)*L2(c,d)=L3(a,d)
矩阵的维度变化是这样的,行列的数是这个规律。接下来就是神经网络的结构的说明了:
首先,我们需要知道的是:神经网络是大体可以分为三层结构的,第一层(输入层)第二层(隐藏层,可以有多层)第三层(输出层),在我们的这个问题上,这里的输入层为日期,即为15天,且可以看作是一个15x1的矩阵,这里的隐藏层则可以规定为一个10x1的矩阵,这个隐藏层的设计可以根据数据来合理设计,这里的输出层和输入层一样,我们需要得到对应天数预测得到的股票的收盘的值,所以也是15x1。在这里,我们把输入矩阵看作是A,中间层即隐藏层看作是B,输出层(每天都股价)可以看作是C。
其次,我们需要知道的是中间层的值B,是由输入层的值乘以一个权重值w1,然后加上偏执值b1得到的,即可以用上图表示。同理,C的值也是如此。这个就是简单的神经网络结构,接下来,其中神经网络的细节如下:
这里一层到二层,二层到三层即为B的值怎么得到的,的值怎么得到的,上面也有比较详细的叙述,然后接下来,我们需要知道的是其中神经网网络整个数据的维度的变化了,以上图可以看出,经过一系列的运算,最后输入和输出的维度是相同的。
最后,我们需要知道的是,其中神经网络的调参的过程了,如果说第一次循环的神经网络得到的预测值是2400,然后实际值是2511,这里预测值和实际值是相差111点的,所以,我们的目的是将这个预测值和实际值缩小,而这里的预测值是C,能够让C变化,更贴近真实值,我们这里的输入A变不了,而B又是由A得到的,所以能变的就是这些W1和B1,W2和B2这些值了,我们利用梯度下降法来减少真实值和预测值的差异,(此处先不讲梯度下降,之后的博客会进行相应的更新说明),经过一次次的循环训练,我们会将这四个参数值进行调节,调节至预测值和真实值是我们想要的那个结果为止,或者说可以控制循环,我们要求循环多少次为止。
接下来就是实现整个神经网络的部分了,下面的代码中也有详细的介绍,相关注释对代码有一个大体的把握:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
data = np.linspace(1, 15, 15) # linspace的功能用来创建等差数列
endPrice = np.array([2511.6, 2538.6, 2510.3, 2591.6, 2732.9, 2701.69, 2702.69, 2703.69, 2704.69, 2721.69, 2711.69, 2711.69, 2721.69, 2731.69, 2741.69]) # 收盘价格
beginPrice = np.array([2438.7, 2500.9, 2534.9, 2512.6, 2594.6, 2743.26, 2753.26, 2752.26, 2754.26, 2751.26, 2732.26, 2725.26, 2745.26, 2756.26, 2737.26]) # 开盘价格
print(data) # 1-15天
plt.figure()
for i in range(0, 15):
'''柱状图'''
dateOne = np.zeros([2]) # 生成一个一行两列全为0的矩阵,分别赋值
dateOne[0] = i
dateOne[1] = i
priceOne = np.zeros([2])
priceOne[0] = beginPrice[i]
priceOne[1] = endPrice[i]
if endPrice[i] > beginPrice[i]:
plt.plot(dateOne, priceOne, 'r', lw=8) # 如果收盘价格高于开盘价格,则柱状图为红色
else:
plt.plot(dateOne, priceOne, 'g', lw=8) # 如果开盘价格高于收盘价格,则柱状图为绿色
# plt.show()
'''数据的归一化处理'''
'''A(15x1)*W1(1x10)+b1(1x10)=B(15x10)'''
'''B(15x10)*W2(10x1)+b2(15x1)=C(15x1)'''
dateNormal = np.zeros([15, 1])
priceNormal = np.zeros([15, 1])
for i in range(0, 15):
dateNormal[i, 0] = i/14.0
priceNormal[i, 0] = endPrice[i]/3000.0
x = tf.placeholder(tf.float32, [None, 1])
y = tf.placeholder(tf.float32, [None, 1])
# B的定义,隐藏层
w1 = tf.Variable(tf.random_uniform([1, 10], 0, 1)) # 在0-1之间取10个数
b1 = tf.Variable(tf.zeros([1, 10])) # 建一个一行十列的矩阵
wb1 = tf.matmul(x, w1)+b1 # 得到B
layer1 = tf.nn.relu(wb1) # 激活函数,完成wb1的映射,以后再进行描述
# C的定义,输出层
w2 = tf.Variable(tf.random_uniform([10, 1], 0, 1))
b2 = tf.Variable(tf.zeros([15, 1]))
wb2 = tf.matmul(layer1, w2)+b2
layer2 = tf.nn.relu(wb2)
# 我们计算预测值,通过差异调参
loss = tf.reduce_mean(tf.square(y-layer2)) # 标准差的损失函数,之后再进行描述
# 定义我们每次调参的步长,我们选择梯度下降法,作用是缩小loss,减小预测值和真实值的差异,通过不断调整w和b
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer()) # 完成数据的初始化
# 定义中止的条件,有两个,定义真实值和预测值之间的差异,比如说差别2%中止,或者说定义循环的次数,在这里定义循环100次中止
for i in range(0, 1000):
sess.run(train_step, feed_dict={x: dateNormal, y: priceNormal})
# 经过10000次训练之后,输出了一组优化后的w1,w2,b1,b2。那么我们怎么检测这些参数呢/我们可以喂入之前的输出的值预测绘制相应的曲线去验证
prediction = sess.run(layer2, feed_dict={x: dateNormal})
predictionPrice = np.zeros([15, 1])
for i in range(0, 15):
predictionPrice[i, 0] = (prediction*3000)[i, 0] # 这里乘以300是为了恢复预测值,之前处以了3000
plt.plot(data, predictionPrice, 'b', lw=1)
plt.show()
下面是运行的结果图:
可以看出来,模拟的蓝色的曲线的预测值还是和真实值相对吻合的。