使用Tensorflow建造神经网络
一、Tensorflow建造神经网络
添加一层神经元的函数
def add_layer(inputs,in_size,out_size,activation_function=None):
Weights = tf.Variable(tf.random.rand([in_size, out_size])) # 定义权重
biases = tf.Variable(tf.zeros([1,in_size])+0.1) # 定义偏置
Wx_plus_b = tf.matmul(inputs,Weights)+biases # 计算Σ
# 激活函数选择
if activation_function is None:
outputs = Wx_plus_b
else:
outputs = activation_function(Wx_plus_b)
return outputs
1. 定义数据 — 输入层
构建所需的数据。 这里的 x_data 和 y_data 并不是严格的一元二次函数的关系,因为多加了一个noise,这样看起来会更像真实情况。
x_data = np.linspace(-1,1,300,dtype=np.float32)[:,np.newaxis]
noise = np.random.rand(0,0.05,x_data.shape).astype(np.float32) #产生部分噪点
y_data = np.square(x_data)+noise
利用占位符定义我们所需的神经网络的输入。 tf.placeholder()就是代表占位符,这里的None代表无论输入有多少都可以,因为输入只有一个特征,所以这里是1。
xs = tf.placeholder(tf.float32,[None,1]) #便于后续模拟时填充数据
ys = tf.placeholder(tf.float32,[None,1])
接下来,我们就可以开始定义神经层了。 通常神经层都包括输入层、隐藏层和输出层。这里的输入层只有一个属性, 所以我们就只有一个输入;隐藏层我们可以自己假设,这里我们假设隐藏层有10个神经元; 输出层和输入层的结构是一样的,所以我们的输出层也是只有一层。 所以,我们构建的是——输入层1个、隐藏层10个、输出层1个的神经网络。
2. 创建隐藏层和输出层
开始定义隐藏层,利用之前的 add_layer() 函数,这里使用 Tensorflow 自带的激励函数 tf.nn.relu
。
l1 = add_layer(xs,1,10,activation_function=tf.nn.relu) #从输入层(x_data)到隐藏层(l1)
定义输出层。此时的输入就是隐藏层的输出——l1,输入有10层(隐藏层的输出层),输出有1层
prediction = add_layer(l1,10,1,activation_function=None) #从隐藏层(l1)到输出层(prediction)
3. 误差计算
计算预测值prediction和真实值的误差,对二者差的平方求和再取平均。
loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys-prediction) , reduction_indices=[1]))
4. 误差传播
是很关键的一步,如何让机器学习提升它的准确率。tf.train.GradientDescentOptimizer()中的值通常都小于1,这里取的是0.1,代表以0.1的效率来最小化误差loss
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
5. 参数初始化
使用变量时,都要对它进行初始化,这是必不可少的。
init = tf.gloal_variables_initializer()
6. 开始模拟
定义Session,并用 Session 来执行 init 初始化步骤。 (注意:在tensorflow中,只有session.run()才会执行我们定义的运算。)
with tf.Session as sess:
for i in range(1000):
sess.run(train_step,feed_dict={xs:x_data,ys:y_data})
print(sess.run(loss,feed_dict={xs:x_data,ys:y_data}))
7. 完整代码
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt #用于可视化
#import os
#os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
#tf.compat.v1.disable_eager_execution()
def add_layer(inputs,in_size,out_size,activation_function=None):
Weights = tf.Variable(tf.random.rand([in_size, out_size])) # 定义权重
biases = tf.Variable(tf.zeros([1,in_size])+0.1) # 定义偏置
Wx_plus_b = tf.matmul(inputs,Weights)+biases # 计算Σ
# 激活函数选择
if activation_function is None:
outputs = Wx_plus_b
else:
outputs = activation_function(Wx_plus_b)
return outputs
# 初始化数据
x_data = np.linspace(-1,1,300,dtype=np.float32)[:,np.newaxis]
noise = np.random.rand(0,0.05,x_data.shape).astype(np.float32)
y_data = np.square(x_data)+noise
xs = tf.placeholder(tf.float32,[None,1])
ys = tf.placeholder(tf.float32,[None,1])
# 从输入层到隐含层 ,从隐含层到输出层
l1 = add_layer(xs,1,10,activation_function=tf.nn.relu) #从输入层(x_data)到隐藏层(l1)
prediction = add_layer(l1,10,1,activation_function=None) #从隐藏层(l1)到输出层(prediction)
# 计算误差 和 传播误差
loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys-prediction) , reduction_indices=[1]))
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss) #优化误差
init = tf.gloal_variables_initializer()
# 画出散点图
fig = plt.figure() #创建一个画框
ax = fig.add_subplot(1,1,1)
ax.scatter(x_data,y_data)
plt.ion() #使得可以动态画图,否则在一次plt.show之后,就会停止画图
plt.show()
# 开始使用 tf.Session 模拟
with tf.Session as sess:
for i in range(1000):
sess.run(train_step,feed_dict={xs:x_data,ys:y_data})
print(sess.run(loss,feed_dict={xs:x_data,ys:y_data}))
# 画图
try:
ax.lines.remove(lines[0]) #新的曲线绘制出来的前一瞬间,需要把上一次绘制的拟合曲线删除
except Exception:
pass
prediction_value = sess.run(prediction,feed_dict={xs:x_data,y_data}) # 获取本次最新训练的预测结果
lines = ax.plot(x_data,prediction_value,'r-',lw=5)
二、【附录】
1. 关于reduction_indices
在tf.reduce_sum
等函数中,有一个reduction_indices
参数,表示函数的处理维度。
在tf.reduce_sum等函数中,有一个reduction_indices参数,表示函数的处理维度。
2. 关于tf.nn.relu
线性整流函数(Rectified Linear Unit, ReLU),又称修正线性单元。
其定义如下图,在横坐标的右侧,ReLU函数为线性函数。在横坐标的左侧侧,ReLU函数为值为 0 。
因此,tf.nn.relu()
函数的目的是,将输入小于0的值幅值为0,输入大于0的值不变。
代码测试结果如下:
import tensorflow as tf
a = tf.constant([-1.0, 2.0,-3.6])
with tf.Session() as sess:
b = tf.nn.relu(a)
print(sess.run(b))
#测试结果为:
#[0. 2. 0.]
3. 关于numpy.linspace()
numpy.linspace()
函数用于在线性空间中以均匀步长生成数字序列。
格式:
array = numpy.linspace(start, end,num=num_points)
将在start和end之间生成一个统一的序列,共有num_points个元素。
- start -> Starting point (included) of the rangestart ->范围的起点(包括)
- end -> Endpoint (included) of the rangeend ->范围的端点(包括)
- num ->Total number of points in the sequencenum >序列中的总点数
如果不想在序列计算中包括最后一点,则可以使用另一个关键字参数endpoint ,可以将其设置为False(默认为True )a = np.linspace(0.02, 2, 10, endpoint=False) 。
4. 关于tf.train.GradientDescentOptimizer().minimize()
1.tf.train.GradientDescentOptimizer().minimize()
其中的minimize可以拆为以下两个步骤:
① 梯度计算
② 将计算出来的梯度应用到变量的更新中
- 拆开的好处是,可以对计算的梯度进行限制,防止梯度消失和爆炸
下一节:【使用Tensorboard 可视化神经网络】