TensorFlow训练神经网络模型的步骤:
(1)定义神经网络的结构和向前传播的输出结果
(2)定义损失函数以及选择反向传播优化的算法
(3)生成会话(tf.Session),并且在训练数据上反复运行反向传播优化算法
例:下面是一个完整的程序来训练神经网络解决二分类问题
import tensorflow as tf
import numpy as np #通过NumPy工具包生成模拟数据
batch_size=8 #定义训练数据batch的大小
#定义神经网络的参数
w1=tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))
w2=tf.Variable(tf.random_normal([3,1],stddev=1,seed=1))
#定义placeholder存放输入数据
#在shape的一个维度上使用None可以方便使用不大的batch大小
x_data=tf.placeholder(tf.float32,shape=(None,2),name='x-input')
y_data=tf.placeholder(tf.float32,shape=(None,1),name='y-input')
#定义神经网络向前传播过程
a=tf.matmul(x_data,w1)
y=tf.matmul(a,w2)
#定义损失函数和反向传播算法
cross_entropy=-tf.reduce_mean(y_data*tf.log(tf.clip_by_value(y,1e-10,1.0)))
train_step=tf.train.AdadeltaOptimizer(0.001).minimize(cross_entropy)
#通过随机数生成一个模拟数据集
rdm=np.random.RandomState(1)
dataset_size=128
X=rdm.rand(dataset_size,2)
#定义规则来给出样本的标签。
Y=[[int(x1+x2<1)] for (x1,x2) in X]
#创建一个会话来运行TensorFlow程序
with tf.Session() as sess:
sess.run(tf.global_variables_initializer()) #初始化变量
print("训练之前的神经网络参数值:")
print(sess.run(w1)) #输出训练之前神经网络参数的值
print(sess.run(w2))
#设置训练5000次
for i in range(5000):
start=(i*batch_size)%dataset_size #每次选取batch_size个样本进行训练
end=min(start+batch_size,dataset_size)
#通过选取的样本训练神经网络并更新参数
sess.run(train_step,feed_dict={x_data:X[start:end],y_data:Y[start:end]})
#每隔一段时间计算在所有数据上的交叉熵并输出
if i%1000==0:
total_cross_entropy=sess.run(cross_entropy,feed_dict={x_data:X,y_data:Y})
print("After %d training steps,cross entropy on all data is %g" %(i,total_cross_entropy))
#输出训练5000次之后的神经网络参数值
print("训练之后的神经网络参数值:")
print(sess.run(w1))
print(sess.run(w2))
输出结果为:
详解交叉熵损失函数
cross_entropy=-tf.
reduce_mean
(y_data*tf.
log
(tf.
clip_by_value
(y,
1e-10
,
1.0
)))
(1)tf.clip_by_value()函数
#tf.clip_by_value()
函数可以将一个张量中的数值限制在一个范围之内,这样可以避免一些运算错误
v1=tf.
constant
([[
1.0
,
2.0
,
3.0
],[
4.0
,
5.0
,
6.0
]])
with
tf.
Session
()
as
sess:
print
(sess.
run
(tf.
clip_by_value
(v1,
2.5
,
4.5
)))
#
如上,小于
2.5
的数都被换成了
2.5
,大于
4.5
的数都被换成了
4.5
#tf.clip_by_value()
函数可以保证在进行
log
运算时不会出现
log0
这样的错误或者大于
1
的概率
#输出结果为:[[2.5 2.5 3. ]
[4. 4.5 4.5]]
(2)tf.log()函数
#tf.log()
函数完成张量中所有元素依次求对数的功能
v2=tf.
constant
([
1.0
,
2.0
,
3.0
])
with
tf.
Session
()
as
sess:
print
(sess.
run
(tf.
log
(v2)))
#输出结果为:[0. 0.6931472 1.0986123]
(3)"
*
"操作
在实现交叉熵的代码中,直接将两个矩阵通过"
*
"操作相乘,这个操作不是矩阵的乘法,而是
元素之间的直接相乘
;
矩阵乘法
需要使用
tf.matmul()函数
来完成
(4)cross_entropy=tf.nn.softmax_cross_entropy_with_logits(y,y_data)
#
交叉熵一般会与
softmax
回归一起使用,
TensorFlow
对这两个功能进行了统一封装
#
通过以下代码实现使用
softmax
回归之后的交叉熵损失函数
cross_entropy=tf.nn.
softmax_cross_entropy_with_logits
(y,y_data)
#
其中
y
代表了原始神经网络的输出结果,
y_data
是标准答案
(5)tf.nn.sparse_softmax_cross_entropy_with_logits(y,y_data)
#
在只有一个正确答案的分类问题中,
TensorFlow
提供了如下函数来进一步加速计算过程
tf.nn.
sparse_softmax_cross_entropy_with_logits
(y,y_data)
参考资料:《TensorFlow实战 Google深度学习框架》