Tensorflow XOR门问题
网络结构

源代码
import tensorflow as tf
import numpy as np
"""
准备数据
用numpy.array格式准备XOR的输入和输出,即训练数据
X和Y是4个数据的矩阵,X[i]和Y[i]的值始终对应。
数据类型:用python使用tensorflow时,输入到网络中的训练数据需要以np.array的类型存在。并且要限制dtype为32bit以下。变量后跟着“.astype('float32')”总可以满足要求。
"""
X=[0,0],[0,1],[1,0],[1,1](/juedaiyuer/researchNote/wiki/0,0],[0,1],[1,0],[1,1)
Y=[0],[1],[1],[0](/juedaiyuer/researchNote/wiki/0],[1],[1],[0)
X=np.array(X).astype('int16')
Y=np.array(Y).astype('int16')
"""
# 网络结构:2维输入 --> 2维隐藏层 --> 1维输出
# 学习速率(learning rate):0.0001
"""
D_input = 2
D_label = 1
D_hidden = 2
lr = 1e-4
"""
#控制tensorboard生成图中的名字,也会方便debug。
"""
x = tf.placeholder(tf.float32, [None, D_input], name="x")
t = tf.placeholder(tf.float32, [None, D_label], name="t")
# 初始化W
W_h1 = tf.Variable(tf.truncated_normal([D_input, D_hidden], stddev=0.1), name="W_h")
# 初始化b
b_h1 = tf.Variable(tf.constant(0.1, shape=[D_hidden]), name="b_h")
# 计算Wx+b
pre_act_h1 = tf.matmul(x, W_h1) + b_h1
# 计算a(Wx+b)
act_h1 = tf.nn.relu(pre_act_h1, name='act_h')
# 输出层,输出层的输入,就是有隐藏层的输出
W_o = tf.Variable(tf.truncated_normal([D_hidden, D_label], stddev=0.1), name="W_o")
b_o = tf.Variable(tf.constant(0.1, shape=[D_label]), name="b_o")
pre_act_o = tf.matmul(act_h1, W_o) + b_o
y = tf.nn.relu(pre_act_o, name='act_y')
# 反向传播,计算误差值来更新网络权值的结构
# 定义损失函数
loss = tf.reduce_mean((self.output-self.labels)**2)
# 更新方法,选择想要用于更新权重的训练方法和每次更新步伐(lr)
train_step = tf.train.AdamOptimizer(lr).minimize(loss)
# 加载训练
# 将建好的网络加载到session中执行操作
# 创建session
sess = tf.InteractiveSession()
# 初始化权重
tf.initialize_all_variables().run()
#训练网络
#sess.run()接受两个参数:
# 前一个参数的类型是list,表示所有想要执行的操作(op)或者想要获取的值。
#GD(Gradient Descent):X和Y是4组不同的训练数据。上面将所有数据输入到网络,算出平均梯度来更新一次网络的方法叫做GD。效率很低,也容易卡在局部极小值,但更新方向稳定。
T=10000 #训练几次
for i in range(T):
sess.run(train_step,feed_dict={x:X,t:Y})
#SGD(Gradient Descent):一次只输入一个训练数据到网络,算出梯度来更新一次网络的方法叫做SGD。效率高,适合大规模学习任务,容易挣脱局部极小值(或鞍点),但更新方向不稳定
"""
T=10000 #训练几epoch
for i in range(T):
for j in range(X.shape[0]): #X.shape[0]表示样本个数
sess.run(train_step,feed_dict={x:X[j],t:Y[j]})
"""
#batch-GD:这是上面两个方法的折中方式。每次计算部分数据的平均梯度来更新权重。部分数据的数量大小叫做batch_size,对训练效果有影响。一般10个以下的也叫mini-batch-GD
"""
T=10000 #训练几epoch
b_idx=0 #batch计数
b_size=2 #batch大小
for i in range(T):
while b_idx<=X.shape[0]:
sess.run(train_step,feed_dict={x:X[b_idx:b_idx+b_size],t:Y[b_idx:b_idx+b_size]})
b_idx+=b_size #更新batch计数
"""
#shuffle:SGD和batch-GD由于只用到了部分数据。若数据都以相同顺序进入网络会使得随后的epoch影响很小。shuffle是用于打乱数据在矩阵中的排列顺序,提高后续epoch的训练效果。
#预测
sess.run(y,feed_dict={x:X})
source