Tensorflow简单神经网络

2020-07-09  本文已影响0人  策马踏清风

神经网络参数与Tensorflow变量

tf.Variable作用是保存和更新神经网络中的参数

#声明2 X 3的矩阵变量,元素均值为0,标准差为2的随机数
weights = tf.Variable(tf.random_normal([2,3], stddev=2))

其它生成器

函数 随机数分布 主要参数
tf.random_normal 正太分布 平均值、标准差、取值类型
tf.truncated_normal 正太分布,但如果随机出来的值偏离平均值超过2个标准差,那么值会重新随机 平均值、标准差、取值类型
tf.random_uniform 拼接分布 最小、最大取值,取值类型
tf.random_gamma Gamma分布 形状参数alpha、尺度参数beta、取值类型

使用常数初始化

函数名 功能 样例
tf.zeros 产生全0的数组 tf.zeros([2,3], int32) -> [[0,0,0], [0,0,0]]
tf.ones 产生全1的数组 tf.ones([2,3], int32) ->[[1,1,1], [1,1,1]]
tf.fill 产生指定数字的数组 tf.fill([2,3], 9) -> [[9,9,9], [9,9,9]]
tf.constant 给定值的 tf.constant([1,2,3]) -> [1,2,3]

变量使用的例子

import tensorflow as tf

#初始化两个变量
w1 = tf.Variable(tf.random_normal((2,3), stddev=1, seed=1))
w2 = tf.Variable(tf.random_normal((3,1), stddev=1, seed=1))

#输入的特征向量
x = tf.constant([[0.7, 0.9]])

#前向传播
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)

sess = tf.Session()
#初始化变量
init_op = tf.global_variables_initializer()
sess.run(init_op)

print(sess.run(y))
sess.close()

#输出:[[3.957578]]

变量和张量的区别

  1. tf.Variable是一个运算,运算的结果也是一个张量,变量本质是特殊的张量
  2. tf.Variable里包含的就是一个张量
  3. tf.constant声明的是一个常量,tf.Variable是变量,后续会进行模型参数调整
    4.tf.Variable会加入到GraphKeys.VARIABLES中,trainable参数可以区分优化参数(神经网络参数)和其它参数(迭代参数)

训练神经网络

import tensorflow as tf

# 声明两个参数,即神经网络的层
w1 = tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
w2 = tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))

# 给出维度可以降低出错率
# 声明占位符(入口)
x = tf.placeholder(tf.float32, shape=(1, 2), name='input')

# 使用全加,将层连接,形成网络
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)

sess = tf.Session()
# 调用初始化参数
init_go = tf.global_variables_initializer()
sess.run(init_go)

# 给入口占位符值,并运算
print(sess.run(y, feed_dict={x: [[0.7, 0.9]]}))   #feed_dict是个字典
# 输出: [[3.957578]]

上面的是运行一个神经网络的代码,输入feed_dict根据神经网络运算得出结果。
神经网络可以通过大量样本调整变量的值,以提高预测结果准确性。

交叉熵和反向传播

  1. 交叉熵:用于表示预测值和实际值差距的值,通过特定公式得出
  2. 反向传播:根据交叉熵反向调整神经网络参数的过程
#使用sigmoid函数将y转换为0~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)))
# 上面操作中的这个方法是为了将值限定在一定范围内
# tf.clip_by_value(A,min,max)
# 学习率
learning_rate = 0.001
# 定义反向传播算法来优化神经网络参数
train_step = tf.train.AdamOptimizer(learning_rate).minimize(cross_entropy)

Tensorflow提供的优化算法有10种,常用的有:tf.train.GradientDescentOptimizer, tf.train.AdamOptimizer, tf.train.MomentumOptimizer。定义反向传播之后,通过运行sess.run(train_step)就可以对所有在GraphKeys.TRAINABLE_VARIABLES集合中的变量来进行优化,使当前batch下损失函数更小。

完整神经网络

import tensorflow as tf
from numpy.random import RandomState

#定义训练数据batch的大小
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)
y = tf.matmul(a, w2)

#损失函数和反向传播
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)))
train_step = tf.train.AdamOptimizer(0.001).minimize(cross_entropy)

#随机生成一个模拟数据集
rdm = RandomState(1)
dataset_size = 128
X = rdm.rand(dataset_size, 2)
#定义规则来给出样本标签,x1+x2<1的样例都认为是正样本,其他为负,
Y = [[int(x1 + x2 < 1)] for (x1, x2) in X]

#创建一个会话来运行Tensorflow程序
with tf.Session() as sess:
    init_go = tf.global_variables_initializer()
    #初始化变量
    sess.run(init_go)

    #训练之前的参数
    print('parameter w1 before train: ', sess.run(w1))
    print('parameter w2 before train: ', sess.run(w2))

    STEPS = 5000
    for i in range(STEPS):
        #每次迭代取batch_size个样本进行训练
        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:
            #每隔1000步计算所有数据集上的交叉熵并输出
            total_cross_entropy = sess.run(cross_entropy, feed_dict={x: X, y_: Y})
            print('After %d training_steps, cross entropy on all data is %g'%(i, total_cross_entropy))

    print('parameter w1 after train: ', sess.run(w1))
    print('parameter w2 after train: ', sess.run(w2))
parameter w1 before train:  [[-0.8113182   1.4845988   0.06532937]
 [-2.4427042   0.0992484   0.5912243 ]]
parameter w2 before train:  [[-0.8113182 ]
 [ 1.4845988 ]
 [ 0.06532937]]
After 0 training_steps, cross entropy on all data is 1.89805
After 1000 training_steps, cross entropy on all data is 0.655075
After 2000 training_steps, cross entropy on all data is 0.626172
After 3000 training_steps, cross entropy on all data is 0.615096
After 4000 training_steps, cross entropy on all data is 0.610309
parameter w1 after train:  [[ 0.02476983  0.56948674  1.6921941 ]
 [-2.1977348  -0.23668921  1.1143895 ]]
parameter w2 after train:  [[-0.45544702]
 [ 0.49110925]
 [-0.98110336]]

clip_by_value

  1. 可以将一个张量中的数值限制在一个范围之内。(可以避免一些运算错误:可以保证在进行log运算时,不会出现log0这样的错误或者大于1的概率)
  2. tf.clip_by_value(1-y,1e-10,1.0)

交叉熵

主要有两个表达式

  1. 二分类(预测的结果只有两种,0/1)


    image.png
  1. 多分类


    image.png
上一篇下一篇

猜你喜欢

热点阅读