Tensorflow是一个基于计算图(数据流图)的的数值计算系统,计算图是一个有向图,图中的节点代表数学计算操作的算子(函数),节点之间连接的边代表参与计算的高维数组数据。计算图本质上就是构造模型数据的前向流动路径(参考文献【1】)。
前面介绍了计算图是构造模型数据的前向流动路径。Session是驱动Tensorflow系统执行计算的交互入口,Session负责完成多计算设备或集群分布式的节点布置和数据传输节点的添加,负责将子图分配给相应的执行器单元来运行。是不是没看懂,我们换言之,Session会话会根据上述前向计算图来反向传播优化模型参数(参考文献【1】)。
步骤一:构建计算图
(1)、声明样本特征和标签的占位符
(2)、声明模型参数
(3)、构造计算图
(4)、声明代价函数和寻优算法
步骤二:以tf.Session()为入口训练模型参数
本人之前的博文(参考文献【2】)已经介绍过RBF神经网络的网络结构、前向传播计算误差和反向传播计算模型参数。反向传播需要计算损失函数对各个参数的偏导,采用梯度下降算法不断迭代获得最优的模型参数。但是因为损失函数对各个参数的偏导计算比较复杂,所以在本人的上一篇博文中介绍的RBF神经网络是简化的版本,输出层的激活函数采用线性函数 y = x y=x y=x,而不是分类效果更好的sigmoid函数。为了避免需要手动推导损失函数对各个参数的偏导,本博文介绍采用tensorflow框架构建RBF神经网络的方法。首先介绍构建RBF神经网络需要用到的几个tensorflow函数,然后根据tensorflow的应用流程介绍RBF神经网络的构建方法。
t f . t i l e ( ) tf.tile() tf.tile()表示平铺复制一个已知矩阵(参考资料【3】)。
t f . s u b t r a c t ( ) tf.subtract() tf.subtract()表示tensorflow中算术运算中的减操作(两个矩阵中对应元素各自相减)。
t f . s q u a r e ( ) tf.square() tf.square()表示对给定对象中的每一个元素求平方。
t f . r e d u c e s u m ( ) tf.reduce_sum() tf.reducesum()表示给定对象按行或按列求和(参考资料【4】)。
t f . t r a n s p o s e ( ) tf.transpose() tf.transpose()表示矩阵的转置。
t f . m u l t i p l y ( ) tf.multiply() tf.multiply()表示两个矩阵中对应元素各自相乘(参考资料【5】)。
t f . m a t m u l ( ) tf.matmul() tf.matmul()将矩阵a乘以矩阵b,生成a * b(参考资料【5】)。
t f . d i v i d e ( ) tf.divide() tf.divide()表示两个矩阵中对应元素各自相除。
完整Python代码和样本地址:https://github.com/shiluqiang/RBF_NN_tensorflow
其中tensorflow构造流程的python代码如下:
def fit(self):
'''模型训练
'''
# 1.声明输入输出的占位符
n_input = (self.input_data_trainX).shape[1]
n_output = (self.input_data_trainY).shape[1]
X = tf.placeholder('float',[None,n_input],name = 'X')
Y = tf.placeholder('float',[None,n_output],name = 'Y')
# 2.参数设置
## RBF函数参数
c = tf.Variable(tf.random_normal([self.hidden_nodes,n_input]),name = 'c')
delta = tf.Variable(tf.random_normal([1,self.hidden_nodes]),name = 'delta')
## 隐含层到输出层权重和偏置
W = tf.Variable(tf.random_normal([self.hidden_nodes,n_output]),name = 'W')
b = tf.Variable(tf.random_normal([1,n_output]),name = 'b')
# 3.构造前向传播计算图
## 隐含层输出
### 特征样本与RBF均值的距离
dist = tf.reduce_sum(tf.square(tf.subtract(tf.tile(X,[self.hidden_nodes,1]),c)),1)
dist = tf.multiply(1.0,tf.transpose(dist))
### RBF方差的平方
delta_2 = tf.square(delta)
### 隐含层输出
RBF_OUT = tf.exp(tf.multiply(-1.0,tf.divide(dist,tf.multiply(2.0,delta_2))))
## 输出层输入
output_in = tf.matmul(RBF_OUT,W) + b
## 输出层输出
y_pred = tf.nn.sigmoid(output_in)
# 4.声明代价函数优化算法
cost = tf.reduce_mean(tf.pow(Y - y_pred,2)) #损失函数为均方误差
train_op = tf.train.GradientDescentOptimizer(0.05).minimize(cost) #优化算法为梯度下降法
# 5.反向传播求参数
trX = self.input_data_trainX
trY = self.input_data_trainY
with tf.Session() as sess:
##初始化所有参数
tf.global_variables_initializer().run()
for epoch in range(100):
for i in range(len(trX)):
feed = {X:trX[i],Y:trY[i]}
sess.run(train_op,feed_dict = feed)
if epoch % 10.0 == 0:
total_loss = 0.0
for j in range(len(trX)):
total_loss += sess.run(cost,feed_dict = {X:trX[j],Y:trY[j]})
print('Loss function at step %d is %s'%(epoch,total_loss / len(trX)))
print('Training complete!')
W = W.eval()
b = b.eval()
c = c.eval()
delta = delta.eval()
pred_trX = np.mat(np.zeros((len(trX),n_output)))
## 训练准确率
correct_tr = 0.0
for i in range(len(trX)):
pred_tr = sess.run(y_pred,feed_dict = {X:trX[i]})
pred_trX[i,:] = pred_tr
if np.argmax(pred_tr,1) == np.argmax(trY[i],1):
correct_tr += 1.0
print('Accuracy on train set is :%s'%(correct_tr/len(trX)))
self.save_model('RBF_predict_results.txt',pred_trX)
对于本博文提供的样本,当迭代次数为100,梯度下降算法中步长设为0.05时,训练准确率为0.9725。
1、《深度学习原理与TensorFlow实践》
2、https://blog.csdn.net/Luqiang_Shi/article/details/84450655
3、https://blog.csdn.net/eric_lh/article/details/79074583
4、https://blog.csdn.net/arjick/article/details/78415675?utm_source=blogxgwz9
5、https://blog.csdn.net/mumu_1233/article/details/78887068