TensorFlow如何实现反向传播
使用TensorFlow的一个优势是,它可以维护操作状态和基于反向传播自动地更新模型变量。
TensorFlow通过计算图来更新变量和最小化损失函数来反向传播误差的。这步将通过声明优化函数(optimizationfunction)来实现。一旦声明好优化函数,TensorFlow将通过它在所有的计算图中解决反向传播的项。当我们传入数据,最小化损失函数,TensorFlow会在计算图中根据状态相应的调节变量。
回归算法的例子从均值为1、标准差为0.1的正态分布中抽样随机数,然后乘以变量A,损失函数为L2正则损失函数。理论上,A的最优值是10,因为生成的样例数据均值是1。
二个例子是一个简单的二值分类算法。从两个正态分布(N(-1,1)和N(3,1))生成100个数。所有从正态分布N(-1,1)生成的数据标为目标类0;从正态分布N(3,1)生成的数据标为目标类1,模型算法通过sigmoid函数将这些生成的数据转换成目标类数据。换句话讲,模型算法是sigmoid(x+A),其中,A是要拟合的变量,理论上A=-1。假设,两个正态分布的均值分别是m1和m2,则达到A的取值时,它们通过-(m1+m2)/2转换成到0等距的值。后面将会在TensorFlow中见证怎样取到相应的值。
同时,指定一个合适的学习率对机器学习算法的收敛是有帮助的。优化器类型也需要指定,前面的两个例子会使用标准梯度下降法,它在TensorFlow中的实现是GradientDescentOptimizer()函数。
#反向传播
#----------------------------------
#
#以下Python函数主要是展示回归和分类模型的反向传播
importmatplotlib.pyplotasplt
importnumpyasnp
importtensorflowastf
fromtensorflow.python.frameworkimportops
ops.reset_default_graph()
#创建计算图会话
sess=tf.Session()
#回归算法的例子:
#Wewillcreatesampledataasfollows:
#x-data:100randomsamplesfromanormal~N(1,0.1)
#target:100valuesofthevalue10.
#Wewillfitthemodel:
#x-data*A=target
#Theoretically,A=10.
#生成数据,创建占位符和变量A
x_vals=np.random.normal(1,0.1,100)
y_vals=np.repeat(10.,100)
x_data=tf.placeholder(shape=[1],dtype=tf.float32)
y_target=tf.placeholder(shape=[1],dtype=tf.float32)
#Createvariable(onemodelparameter=A)
A=tf.Variable(tf.random_normal(shape=[1]))
#增加乘法操作
my_output=tf.multiply(x_data,A)
#增加L2正则损失函数
loss=tf.square(my_output-y_target)
#在运行优化器之前,需要初始化变量
init=tf.global_variables_initializer()
sess.run(init)
#声明变量的优化器
my_opt=tf.train.GradientDescentOptimizer(0.02)
train_step=my_opt.minimize(loss)
#训练算法
foriinrange(100):
rand_index=np.random.choice(100)
rand_x=[x_vals[rand_index]]
rand_y=[y_vals[rand_index]]
sess.run(train_step,feed_dict={x_data:rand_x,y_target:rand_y})
if(i+1)%25==0:
print('Step#'+str(i+1)+'A='+str(sess.run(A)))
print('Loss='+str(sess.run(loss,feed_dict={x_data:rand_x,y_target:rand_y})))
#分类算法例子
#Wewillcreatesampledataasfollows:
#x-data:sample50randomvaluesfromanormal=N(-1,1)
#+sample50randomvaluesfromanormal=N(1,1)
#target:50valuesof0+50valuesof1.
#Theseareessentially100valuesofthecorrespondingoutputindex
#Wewillfitthebinaryclassificationmodel:
#Ifsigmoid(x+A)<0.5->0else1
#Theoretically,Ashouldbe-(mean1+mean2)/2
#重置计算图
ops.reset_default_graph()
#Creategraph
sess=tf.Session()
#生成数据
x_vals=np.concatenate((np.random.normal(-1,1,50),np.random.normal(3,1,50)))
y_vals=np.concatenate((np.repeat(0.,50),np.repeat(1.,50)))
x_data=tf.placeholder(shape=[1],dtype=tf.float32)
y_target=tf.placeholder(shape=[1],dtype=tf.float32)
#偏差变量A(onemodelparameter=A)
A=tf.Variable(tf.random_normal(mean=10,shape=[1]))
#增加转换操作
#Wanttocreatetheoperstionsigmoid(x+A)
#Note,thesigmoid()partisinthelossfunction
my_output=tf.add(x_data,A)
#由于指定的损失函数期望批量数据增加一个批量数的维度
#这里使用expand_dims()函数增加维度
my_output_expanded=tf.expand_dims(my_output,0)
y_target_expanded=tf.expand_dims(y_target,0)
#初始化变量A
init=tf.global_variables_initializer()
sess.run(init)
#声明损失函数交叉熵(crossentropy)
xentropy=tf.nn.sigmoid_cross_entropy_with_logits(logits=my_output_expanded,labels=y_target_expanded)
#增加一个优化器函数让TensorFlow知道如何更新和偏差变量
my_opt=tf.train.GradientDescentOptimizer(0.05)
train_step=my_opt.minimize(xentropy)
#迭代
foriinrange(1400):
rand_index=np.random.choice(100)
rand_x=[x_vals[rand_index]]
rand_y=[y_vals[rand_index]]
sess.run(train_step,feed_dict={x_data:rand_x,y_target:rand_y})
if(i+1)%200==0:
print('Step#'+str(i+1)+'A='+str(sess.run(A)))
print('Loss='+str(sess.run(xentropy,feed_dict={x_data:rand_x,y_target:rand_y})))
#评估预测
predictions=[]
foriinrange(len(x_vals)):
x_val=[x_vals[i]]
prediction=sess.run(tf.round(tf.sigmoid(my_output)),feed_dict={x_data:x_val})
predictions.append(prediction[0])
accuracy=sum(x==yforx,yinzip(predictions,y_vals))/100.
print('最终精确度='+str(np.round(accuracy,2)))
输出:
Step#25A=[6.12853956] Loss=[16.45088196] Step#50A=[8.55680943] Loss=[2.18415046] Step#75A=[9.50547695] Loss=[5.29813051] Step#100A=[9.89214897] Loss=[0.34628963] Step#200A=[3.84576249] Loss=[[0.00083012]] Step#400A=[0.42345378] Loss=[[0.01165466]] Step#600A=[-0.35141727] Loss=[[0.05375391]] Step#800A=[-0.74206048] Loss=[[0.05468176]] Step#1000A=[-0.89036471] Loss=[[0.19636908]] Step#1200A=[-0.90850282] Loss=[[0.00608062]] Step#1400A=[-1.09374011] Loss=[[0.11037558]] 最终精确度=1.0
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。