神经网络的前向传播过程在计算中表示为矩阵相乘的过程
具体内容在书上3.4.2
实现神经网络的前向传播过程
输入层两个节点,隐藏层3个,输出层一个
# 声明w1,w2两个变量,通过seed参数设定随机种子,保证每次运行结果一样
# stddev=1 表示随机数标准差为一
w1 = tf.Variable(tf.random_normal((2, 3), stddev=1, seed=1))
w2 = tf.Variable(tf.random_normal((3, 1), stddev=1, seed=1))
# 将输入的特征向量定义为一个常量。注意是1x2矩阵
x = tf.constant([[0.7, 0.9]])
##前向传播算法
a=tf.matmul(x,w1) #得到1x3
y=tf.matmul(a,w2)
with tf.Session() as sess:
#进行w1,w2的初始化
sess.run(w1.initializer)
sess.run(w2.initializer)
print(sess.run(y))
在以上代码实例中,直接调用了w1,w2的初始化过程,但是如果变量数目很多,或者变量之间存在依赖关系,显然单个调用的方案就太麻烦了。要使用以下初始化方法
sess.run(tf.global_variables_initializer())
##上面的代码在会话中表示为
with tf.Session() as sess:
#进行w1,w2的初始化
sess.run(tf.global_variables_initializer())
print(sess.run(y))
placeholder的使用
相当于定义了一个位置,这个位置中的数据在程序运行时再指定。在定义时,这个位置上的数据类型是需要指定的,而维度信息不一定要给出。
下面给出通过placeholder实现前向传播算法的代码
import tensorflow as tf
# 声明w1,w2两个变量,通过seed参数设定随机种子,保证每次运行结果一样
# stddev=1 表示随机数标准差为一
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位置
x = tf.placeholder(tf.float32)
##前向传播算法
a=tf.matmul(x,w1) #得到1x3
y=tf.matmul(a,w2)
with tf.Session() as sess:
#进行w1,w2的初始化
sess.run(tf.global_variables_initializer())##global意思为整体的
#sess.run(w1.initializer)
#sess.run(w2.initializer)
print(sess.run(y,feed_dict={x:[[0.7,0.9]]}))
feed_dict是一个map,需要给出每个用到的placeholder的取值,如果没有就会报错
在训练神经网络时需要每次提供一个batch的训练样例,placeholder也可以很好的支持
将输入的1x2矩阵改为n x 2矩阵,就可以了。这样前向传播的结果就为n x 1,每一行代表一个结果。
代码中并没有表明矩阵的大小,以为placeholder可以根据输入的数据维度自动计算。与上个代码区别只在于feed的数据维度不同。
import tensorflow as tf
# 声明w1,w2两个变量,通过seed参数设定随机种子,保证每次运行结果一样
# stddev=1 表示随机数标准差为一
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位置
x = tf.placeholder(tf.float32)
##前向传播算法
a=tf.matmul(x,w1) #得到1x3
y=tf.matmul(a,w2)
with tf.Session() as sess:
#进行w1,w2的初始化
sess.run(tf.global_variables_initializer())##global意思为整体的
#sess.run(w1.initializer)
#sess.run(w2.initializer)
print(sess.run(y,feed_dict={x:[[0.7,0.9],[0.1,0.4],[0.5,0.8]]}))
简单的损失函数
作用:在得到一个batch的前向传播结果后,需要定义一个损失函数来刻画预测值和真实答案之间的差距,然后再通过反向传播算法来调整神经网络参数。
y_代表真值
# sigmoid函数将y转换为0-1之间的数值。转换后y代表预测是正样本概率,1-y代表负样本概率
y = tf.sigmoid(y)
# 定义损失函数刻画预测值与真实值的差距,交叉熵
cross_entropy = -tf.reduce_mean(
y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0))
+ (1 - y_) * tf.log(tf.clip_by_value(1-y, 1e-10, 1.0)))
# 学习率
learning_rate = 0.001
# 定义反向传播算法来优化神经网络中的参数
train_step = \
tf.train.AdamOptimizer(learning_rate).minimize(cross_entropy)
完整神经网络样例程序
import tensorflow as tf
from numpy.random import RandomState
batch_size = 8
w1 = tf.Variable(tf.random_normal((2, 3), stddev=1, seed=1))
w2 = tf.Variable(tf.random_normal((3, 1), stddev=1, seed=1))
# 在shape的一个维度上使用None可以方便使用不同的batch大小。
x = tf.placeholder(tf.float32, shape=(None, 2), name="x-input")
y_ = tf.placeholder(tf.float32, shape=(None, 1), name="y-input")
# 神经网络的前向传播
a = tf.matmul(x, w1) # 得到1x3
y = tf.matmul(a, w2)
# 定义损失函数和反向传播算法
# sigmoid函数将y转换为0-1之间的数值。转换后y代表预测是正样本概率,1-y代表负样本概率
y = tf.sigmoid(y)
# 定义损失函数刻画预测值与真实值的差距,交叉熵
#通过tf.clip_by_value可以将一个张量中的数值限制在一个范围之内,可以避免一些运算错误,比如log0是
#无效的,但是这里的非线性函数是sigmoid也无所谓,不会出现0
cross_entropy = -tf.reduce_mean(
y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0))
+ (1 - y_) * tf.log(tf.clip_by_value(1-y, 1e-10, 1.0)))
learning_rate = 0.001
train_step = tf.train.AdamOptimizer(learning_rate).minimize(cross_entropy)
# 通过随机数生成一个模拟数据集
rdm = RandomState(1) # 1为随机种子seed,只要随机种子seed相同,产生的随机数序列就相同
dataset_size = 128
X = rdm.rand(dataset_size, 2)
#x1+x2<1为1,否则为0
Y = [[int(x1 + x2 < 1)] for (x1, x2) in X]
with tf.Session() as sess:
# 变量的初始化
sess.run(tf.global_variables_initializer()) ##global意思为整体的
# 训练之前的神经网络参数的值
print(sess.run(w1))
print(sess.run(w2))
# 设定训练的轮数
STEPS = 5000
for i in range(STEPS):
start = (i * batch_size) % dataset_size
end = min(start + batch_size, dataset_size)
sess.run(train_step, feed_dict={x: X[start:end], y_: Y[start:end]})
if i % 1000 == 0:
total_cross_entropy = sess.run(cross_entropy, feed_dict={x: X, y_: Y})
print("%d STEP ,cross entropy on all data is %g"% (i, total_cross_entropy))