1 神经网络
功能:曲线拟合
结构:
解析:
(1) 结构:输入层,隐藏层,输出层;
(2) 输入层:1(单输入),输出层:1(单输出),隐藏层:10(10个神经元);
(3) 维度
序号 | 结构 | 维度 |
---|---|---|
1 | input | [1,1] |
2 | weight_1 | [1, 10] |
3 | biase_1 | [1, 10] |
4 | weight_2 | [10, 1] |
5 | biase_2 | [1, 1] |
注:
依据公式:
y
=
w
e
i
g
h
t
∗
x
+
b
y=weight*x + b
y=weight∗x+b
2 源码(绘图部分未贴出)
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
mpl.rcParams["font.serif"] = ['simhei']
x_data = np.linspace(-1, 1, 250, dtype=np.float32)[:, np.newaxis]
noise = np.random.normal(0, 0.05, x_data.shape).astype(np.float32)
y_data = np.square(x_data) - 0.5*x_data + noise
xs = tf.placeholder(tf.float32, [None, 1])
ys = tf.placeholder(tf.float32, [None, 1])
input_size_1 = 1
output_size_1 = 10
input_size_2 = 10
output_size_2 = 1
weights_1 = tf.Variable(tf.random_normal([input_size_1, output_size_1]))
weights_2 = tf.Variable(tf.random_normal([input_size_2, output_size_2]))
biases_1 = tf.Variable(tf.zeros([1, output_size_1]))
biases_2 = tf.Variable(tf.zeros([1, output_size_2]))
layer_1 = tf.nn.relu(tf.matmul(xs, weights_1) + biases_1)
prediction = tf.matmul(layer_1, weights_2) + biases_2
loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys-prediction), reduction_indices=[1]))
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
def __loss():
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
x = sess.run(xs, feed_dict={xs: x_data})
y = sess.run(ys, feed_dict={ys: y_data})
a = 0
for i in range(1200):
sess.run(train_step, feed_dict={xs: x_data, ys: y_data})
loss2 = sess.run(loss, feed_dict={xs: x_data, ys: y_data})
lay1 = sess.run(layer_1, feed_dict={xs: x_data})
def __result():
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
x = sess.run(xs, feed_dict={xs: x_data})
y = sess.run(ys, feed_dict={ys: y_data})
a = 0
for i in range(1200):
sess.run(train_step, feed_dict={xs: x_data, ys: y_data})
if i % 200 == 0:
a += 1
w1 = sess.run(weights_1)
w2 = sess.run(weights_2)
print("Weights_1 :{}".format(w1))
print("weights_2 :{}".format(w2))
# print(a)
loss_1 = sess.run(loss, feed_dict={xs: x_data, ys: y_data})
print("Loss :{}".format(loss_1))
__loss()
__result()
2 效果
- 损失函数
从图2.1可知,损失函数的在逐渐收敛,且速度较快,在训练到50轮时就开始趋于稳定,该训练模型可较好拟合目标函数.依据设定的误差标准,设计训练的次数.
- 拟合结果
图2.2红色为预测值,蓝色为理论值.展示出每200轮训练的拟合结果,第一组训练数据未较好拟合目标函数,从第2组开始,拟合程度逐渐提高,趋于稳定.图2.1的损失函数在第50轮是显示出损失值趋于误差允许范围,而结果在前200次训练并未较好拟合,因为从1-50轮有较大的偏差积累,所以未较好拟合.修改训练周期,采用50次为一个周期,修改部分源码及结果如下:
- 源码
for i in range(300):
sess.run(train_step, feed_dict={xs: x_data, ys: y_data})
if i % 50 == 0:
a += 1
w1 = sess.run(weights_1)
w2 = sess.run(weights_2)
print("Weights_1 :{}".format(w1))
print("weights_2 :{}".format(w2))
# print(a)
loss_1 = sess.run(loss, feed_dict={xs: x_data, ys: y_data})
print("Loss :{}".format(loss_1))
- 损失函数
- 拟合效果
图2.4红色为预测值,蓝色为理论值.对比图2.3和图2.4,前50轮的训练,损失值变化较大,拟合程度变化随之变化,出现第一组的效果.50轮之后,损失值趋于稳定,展示出较好的拟合效果.
3 解析
- 蛇精网络解析(非源码解析)
(1) 输入层(x_data):shape为250x1,即250组数据,每组数据中包含1个浮点数;
(2) 隐藏层:神经元为10个,输入层到隐藏层权重w1,shape为1x10,隐藏层输出shape为250x10,bias为10x1;
(3) 输出层(y_data):输出层的输入为250x10,权重为w2,shape为10x1,输出层shape为250x1,bias为1x1;
(4) 损失函数为每次训练实际及与理论值平方和取均值,即每次训练,使用全部数据进行一次计算(250个输入x_data),会有一组w1和w2,以及一个损失值,训练次数即为优化的次数,会产生训练次数个w1,w2和loss; - github地址
https://github.com/xindaqi/AIFuture/tree/master/NNTest
4 结论
- 神经网络训练,通过前向计算处理输入数据,反向优化损失函数,即控制理论中的闭环控制,计算并提取满足生产需求的一组权重模型;
- 损失函数优化过程,从逐渐收敛到趋于稳定,训练出的模型效果多样,精度越高,训练时间越久,也可能出现局部最优的情况,需要实时调参优化,结合实际生产需求,设置优化器;
- 该实验采用一层隐藏层,达到预期效果;实际生产需要通过大量实验,设计隐藏层层数,以及神经网络结构,以达到预期效果(多做对比实验);
- 隐藏层左侧权重weights尺寸:上一层的列数量为weights的行数量,隐藏层层数为weights列数量;
- 隐藏层左侧bias尺寸:右侧隐藏层层数(列数量);
- 隐藏层右侧weights尺寸:隐藏层数量为weights行数量,下一层行数量为weights列数量;
- 隐藏层右侧bias尺寸:右侧隐藏层层数或输出层层数(列数量);
[参考文献]
[1]https://morvanzhou.github.io/tutorials/machine-learning/tensorflow/3-2-create-NN/