005Tensorflow基础补充

计算图的使用

Tensorflow中的每一个计算都是计算图上的一个节点,而节点之间的边描述了计算之间的依赖关系。

Tensorflow程序一般分为两个阶段,第一阶段是定义计算图中的所有的计算,第二阶段是执行阶段。

定义:

import tensorflow as tf

a = tf.constant([1.0,2.0],name = "a")
b = tf.constant([2.0,3.0],name = "b")
result = a+b

Tensorflow会自动将定义的计算转化为计算图上的节点,有默认的计算图,通过a.graph可查看计算图

import tensorflow as tf

a = tf.constant([1.0,2.0],name="a")
b = tf.constant([2.0,3.0],name="b")
result = a+b

print(a.graph)#a的计算图:<tensorflow.python.framework.ops.Graph object at 0x113c2f6d8>

print(a.graph is tf.get_default_graph)#false,表明a的计算图不是默认的计算图


可以通过tf.Graph生成新的计算图,不同计算图上的张量和运算都不会共享

g1 = tf.Graph()
with g1.as_default():
    v = tf.get_variable("v", shape=[1], initializer=tf.zeros_initializer)#定义变量v,初始值全部为0

g2 = tf.Graph()
with g2.as_default():
    v = tf.get_variable("v", shape=[1],initializer=tf.ones_initializer)#定义变量v,初始值全部为1

#g1的计算图中,变量值为0
with tf.Session(graph=g1) as sess:
    tf.global_variables_initializer().run()
    with tf.variable_scope("",reuse=True):
        print(sess.run(tf.get_variable("v")))#[0.]
        #get_variable("v"):获取变量v

#g2的计算图中,变量值为1
with tf.Session(graph=g2) as sess:
    tf.global_variables_initializer().run()
    with tf.variable_scope("",reuse=True):
        print(sess.run(tf.get_variable("v")))#[1.]
        

在一个计算图中,可以通过集合来管理不同类别的资源,如通过tf.add_to_collection将资源加入一个或多个集合中,再通过tf.get_collection获取一个集合里的所有资源。

下面是常用集合:

集合名称集合内容使用场景
tf.GraphKeys.VARIABLES所有变量持久化Tensorflow模型
tf.GraphKeys.TRAINABLE_VARIABLES可学习的变量(一般指神经网络中的参数)模型训练、生成模型可视化内容
tf.GraphKeys.SUMMARIES日志生成的相关张量Tensorflow计算可视化
tf.GraphKeys.QUEUE_RUNNERS处理输入的QueueRunner输入处理
tf.GraphKeys.MOVING_AVERAGE_VARIABLES所有计算里滑动平均值的变量计算变量的滑动平均值
张量

Tensorflow程序中,所有的数据都可以通过张量的形式来表示,可以将张量理解为多维数组,零阶张量为标量(一个数),一阶张量为向量(一维数组),n阶张量为n维数组。张量中没有真正保存数字,保存的是数字的运算过程,而不是数字。

import tensorflow as tf

a = tf.constant([1.0,2.0],name="a")
b = tf.constant([2.0,3.0],name="b")
result = a+b

print(result)#Tensor("add:0", shape=(2,), dtype=float32)

上面得到的就是张量的结构,张量中主要保存了三个属性:名字name,维度shape,类型type,其中名字属性name是张量的唯一标识符。计算图中每一个节点表示一个计算,计算的结果存储在张量中。

“Node:src_output”:node为节点的名称,src_output表示张量来自节点的第几个输出,add:0表示add输出的第一个节点(从0开始)

shape维度,这里表示一维数组,长度为2

dtype类型,张量有唯一的类型,计算时如果类型不匹配将会报错,不带小数点默认int32,带小数点默认float32

print(result)#Tensor("add:0", shape=(2,), dtype=float32)

print(result.get_shape)#<bound method Tensor.get_shape of <tf.Tensor 'add:0' shape=(2,) dtype=float32>>

会话

Tensorflow中使用会话session执行定义好的运算,会话拥有并管理tensorflow程序运行时的所有资源。

使用会话有两种模式,第一种要明确调用会话生成函数和会话关闭函数。

import tensorflow as tf

a = tf.constant([1.0,2.0],name="a")
b = tf.constant([2.0,3.0],name="b")
result = a+b

sess = tf.Session()
print(sess.run(result))#[3. 5.],使用session得到result的取值
sess.close()#关闭会话,运行使用的资源会被释放

第二种使用python上下文管理器来使用会话,不需要使用会话关闭函数,上下文退出时自动关闭和释放资源

import tensorflow as tf

a = tf.constant([1.0,2.0],name="a")
b = tf.constant([2.0,3.0],name="b")
result = a+b

with tf.Session() as sess:
    print(sess.run(result))#[3. 5.]

tensorflow会生成默认的计算图,但不会生成默认的会话,需要手动指定,默认会话指定后可以通过tf.Tensor.eval函数来计算一个张量的取值

import tensorflow as tf

a = tf.constant([1.0,2.0],name="a")
b = tf.constant([2.0,3.0],name="b")
result = a+b

sess = tf.Session()
with sess.as_default():#指定默认会话
    print(result.eval())#使用eval得到最终结果
import tensorflow as tf

a = tf.constant([1.0,2.0],name="a")
b = tf.constant([2.0,3.0],name="b")
result = a+b

sess = tf.Session()

print(sess.run(result))#[3. 5.]
print(result.eval(session=sess))#[3. 5.],指定默认会话

sess.close()

也可在交互式环境下直接构造默认会话

import tensorflow as tf

a = tf.constant([1.0,2.0],name="a")
b = tf.constant([2.0,3.0],name="b")
result = a+b

sess = tf.InteractiveSession()
print(result.eval())#[3. 5.]
sess.close()
神经网络参数与Tensorflow变量

tensorflow中,变量tf.Variable的作用是保存和更新神经网络中的参数,随机变量要赋初始值

weights = tf.Variable(tf.random_normal([2,3],stddev=2))

变量的声明函数是tf.Variable,可以设置成随机数、常数或通过其他变量的初始值得到,上面式子生成了2 * 3的矩阵,均值为0,标准差stddev为2,通过mean指定平均值,未指定时为0

随机数生成函数:

函数名称随机数分布主要参数
tf.random_normal正态分布平均值,标准差,取值类型
tf.truncated_normal正态分布,如果随机出来的值偏离平均值超过2,这个数会被重新随机平均值,标准差,取值类型
tf.random_uniform均匀分布最小、最大取值,取值类型
tf.random_gammagamma分布形状参数alpha、尺度参数beta,取值类型

常数生成函数

函数名称功能样例
tf.zeros产生全是0的数组tf.zeros([2,3],int32)
tf.ones产生全是1的数组tf.ones([2,3],int32)
tf.fill产生一个全部为给定数字的数组tf.fill([2,3],7)—>[[7,7,7],[7,7,7]]
tf.constant产生一个给定值的常量tf.constant([1,2,3])—>[1,2,3]

偏置项bias通常使用常数来设置初始值

bias = tf.Variable(tf.zeros([3]))#初始值为0,长度为3的变量

w1 = tf.Variable(weights.initialized_value())#初始值为weights
w2 = tf.Variable(weights.initialized_value()*2.0)#初始值为weights的两倍
通过变量实现神经网络的参数并实现前向传播的过程:
import tensorflow as tf

#定义变量w1,w2,还通过seed参数设置随机种子
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)
y = tf.matmul(a,w2)

sess = tf.Session()
#变量初始化
sess.run(w1.initializer)
sess.run(w2.initializer)

#打印y值
print(sess.run(y))#[[3.957578]]
sess.close()

在计算y之前,需要将所有的变量初始化,使用w.initializer初始化,但当变量过多时,一个一个初始化很麻,可以使用函数实现初始化所有变量。

init_op = tf.global_variables_initializer()
sess.run(init_op)
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))#[[3.957578]]
sess.close()

变量是一种特殊的张量,变量的声明tf.Variable是一个运算,运算的输出结果是一个张量,这个张量就是这里面的变量。

所有的变量都会被自动加入GraphKeys.VARIABLES这个集合中,通过tf.global_variables()函数可以得到当前计算图中所有变量,当构建机器学习模型时,可以通过trainable参数来区分需要优化的参数,声明trainable为True,参数会加入GraphKeys.TRAINABLE_VARIABLES集合,通过tf.trainable_variables得到所有需要优化的参数。

变量的属性维度和类型中,类型不可改变,维度可以改变但一般不改变。

通过Tensorflow训练神经网络模型

Tensorflow计算图很大,每生成一个常量,计算图增加一个节点,神经网络训练经过几百万轮甚至更多的迭代,利用率低,数量巨大,所以Tensorflow提供了placeholder机制用于提供输入数据,placeholder相当于定义了一个位置,这个位置的数据在程序运行时再指定,不需要生成大量常量来提供输入数据,只需要将数据通过placeholder传入计算图。定义placeholder时,其传入的数据类型需要指定。

通过placeholder实现前向传播:
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))

#定义placeholder作为存放数据的地方,这里维度也不一定要定义
x = tf.placeholder(tf.float32,shape=(1,2),name="input")

a = tf.matmul(x,w1)
y = tf.matmul(a,w2)

init_op = tf.global_variables_initializer()

sess = tf.Session()
sess.run(init_op)

print(sess.run(y,feed_dict={x:[[0.7,0.9]]}))#[[3.957578]]

sess.close()

在计算前向传播结果时,需要提供一个feed_dict来指定x的取值,如果没有指定程序会报错。

训练神经网络需要每次提供一个batch的训练样例,如果需要输入多个,可将shape=(1,2)改为n x 2的矩阵,就可以得到 n 个样例的前向传播结果,n x 2 矩阵的每一行为一个样例数据。

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))

#定义placeholder作为存放数据的地方,这里维度也不一定要定义
x = tf.placeholder(tf.float32,shape=(3,2),name="input")

a = tf.matmul(x,w1)
y = tf.matmul(a,w2)

init_op = tf.global_variables_initializer()

sess = tf.Session()
sess.run(init_op)

print(sess.run(y,feed_dict={x:[[0.7,0.9],[0.1,0.4],[0.5,0.8]]}))
"""[[3.957578 ]
 [1.1537654]
 [3.1674924]]"""

sess.close()

在得到前向传播的结果后,要定义一个损失函数来刻画当前的预测值和真实值之间的差距,通过反向传播算法调整神经网络参数的取值使得差距可以被缩小。

sigmoid函数:

取值0-1,转换后y代表预测是正样本的概率,1-y代表预测是负样本的概率
在这里插入图片描述
在这里插入图片描述

完整神经网络样例程序
import tensorflow as tf

#通过numpy工具包生成模拟数据集
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大小,在训练时需要把数据分成比较小的batch,但是在测试时,可以一次性使用全部数据。当训练集比较小的时候比较方便测试,但是当数据集比较大时,将大量数据放入一个batch可能会导致当前内存溢出"""
x = tf.placeholder(dtype=tf.float32, shape=(None, 2),name="x-input")
y_ = tf.placeholder(tf.float32,(None, 1),name="y-input")

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

#定义损失函数和前向传播算法
y = tf.sigmoid(y)

#损失函数
#cross_entropy定义了真实值和预测值之间的交叉熵,是分类问题常用的损失函数
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.train.MomentumOptimizer
tf.train.AdamOptimizer
tf.train.GradientDescentOptimizer
定义了反向传播算法之后运行sess.run(train_step)就可以对所有在GraphKeys.TRAINABLE_VARIABLES中的变量进行优化,使得当前batch下的损失函数更小
"""
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]
"""定义规则给出样本标签,这里使用0表示负样本,1表示正样本,这里所有x1+x2<1认为是正样本"""



#创建会话运行tensorflow程序
with tf.Session() as sess:
    init_op = tf.global_variables_initializer()
    sess.run(init_op)
    """训练之前神经网络参数:
    [[-0.8113182   1.4845988   0.06532937]
     [-2.4427042   0.0992484   0.5912243 ]]
    [[-0.8113182 ]
     [ 1.4845988 ]
     [ 0.06532937]]"""
    print(sess.run(w1))
    print(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:
          #隔一段时间计算交叉熵并输出
            total_cross_entropy = sess.run(
                cross_entropy,feed_dict={x:X,y_:Y}
            )
            print("After %d training step(s),cross entropy on all data is %g" % (i, total_cross_entropy))
            """After 0 training step(s),cross entropy on all data is 1.89805
After 1000 training step(s),cross entropy on all data is 0.655075
After 2000 training step(s),cross entropy on all data is 0.626172
After 3000 training step(s),cross entropy on all data is 0.615096
After 4000 training step(s),cross entropy on all data is 0.610309

训练之后交叉熵逐渐变小,即真实值和预测值之间的差距减小

"""

    print(sess.run(w1))
    print(sess.run(w2))
    #结果
    """
[[ 0.02476986  0.5694868   1.6921942 ]
 [-2.1977346  -0.23668909  1.1143898 ]]
[[-0.4554471 ]
 [ 0.4911093 ]
 [-0.98110336]]"""


https://blog.csdn.net/sinat_29957455/article/details/78324082

神经网络训练步骤
  • 定义神经网络的结构和前向传播的输出结果
  • 定义损失函数已经选择反向传播优化的算法
  • 生成会话并在训练数据上反复运行反向传播优化算法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值