TensorFlow入门--Chapter01

TensorFlow入门

1. TensorFlow的计算模型 图计算

1.1 概念

TensorFlow是一个通过计算图的形式来表达计算的编程系统


1.2 使用

主要分为两个阶段:

  • 一 是定义计算图中所有计算
  • 二 是执行计算

1.3 计算图常用函数

函数名 函数作用
tf.get_default_graph 获取当前默认的计算图 在TensorFlow中系统可以自动维护一个默认的计算图
a.graph 可以查看张量所属的计算图
tf.Graph 生成新的计算图
tf.Graph.device 指定运行计算的设备

2. TensorFlow的数据模型 张量

2.1 概念

含义
:张量可以简单的理解为数组,一个张量主要保存三个属性名字(name),维度(shape),类型(type).
① 0 阶张量表示标量(scalar)也就是一个数
② 1 阶张量表示相量(vector)也就是一维数组
③ n 阶张量表示n维数组
注:张量不是直接采用数组形式实现,它只是对TensorFlow中运算结果的引用。在张量中并没有保存真正的数字,而是数字的计算过程


命名
张量通过node:src_output命令 node为节点名称,src_output为当前张量来自节点的第几个输出

#add:代表张量名字也是的唯一标识符即计算节点的名字为add
#add:0 :是代表计算节点add输出第一个结果,(从0开始算)
#shape=(2,)说明了张量 result 是一个一维数组, 这个数组的长度为 2
#dtype是类型为float32,每一个张量会有一个唯一的类型
Tensor("add:0", shape=(2,), dtype=float32) 

2.2 使用

张量的使用主要可以总结两大类

    1. 是对中间计算结果的引用
    1. 是党计算图构造完成之后,张量可以获得计算结果,虽然不能直接存储具体数字,但是可以通过会话来得到具体数字
#使用张量计算中间结果
a = tf.constant([1.0,2.0],name='a')
b = tf.constant([2.0,3.0],name='b')
result = a+b
#直接计算向量的和,可读性比较差
result = tf.constant([1.0,2.0],name="a") + tf.constant([2.0,3.0],name="b")

3. TensorFlow的运行模型 会话

注:会话拥有并管理TensorFlow程序运行时的所有资源,所有计算完成之后需要关闭会话来帮助系统回收资源。否则可能会出现资源泄露

3.1 TensorFlow通常两种模式的会话

  • 第一种:就是顺序执行完毕最后释放资源,缺点就是对程序异常退出时,不能执行释放。
#创建一个会话
sess = tf.Session()
#用创建好的会话sess来运行结果
sess.run(result)
#关闭会话,释放本次占用的资源
sess.close()
  • 第二种:就是用with像打开文件一样,自动释放
#创建一个会话
with tf.Session() as sess:
	sess.run(result)#运行
#此处不需要调用sess.close()来释放资源了。

3.2 默认会话

默认会话被指定后可以用tf.Tensor.eval函数计算张量的值

sess = tf.Session()
with sess.as_default():
	print(result.eval())
 #输出[3. 5.]

#以下代码也可以完成相同的功能
sess = tf.Session()
print(sess.run(result)) #非默认
print(result.eval(session=sess)) #默认

4. TensorFlow实现简单神经网络

4.1 TensorFlow游乐场


神经网络结构包括输入层,隐藏层,输出层,

  • 输入层:代表特征向量中每一个特征的取值,特征向量就是神经网络的输入。
  • 隐藏层:就是具体算法实现部分,例如输入值通过激活函数等获得输出值,激活函数就属于隐藏层内的。
  • 输出层:就是预测结果的输出,用这个结合真实值,就可以得最后结果
  • 特征向量:机器学习中说所有用于描述实体数字的组合就是一个实体的特征向量

在这里插入图片描述

4.2 前向传播算法

神经元:构成神经网络的最小单元,一个神经元有多个输入一个输出
神经网络的神经元可以称之为节点


计算神经网络的前向传播结果需要三个部分信息

  1. 神经网络的输入,输入就是从实体汇总提取特征向量
  2. 神经网络的连接结构
  3. 每个神经元中的参数

在这里插入图片描述
以上的过程可以用矩阵表示输入层的x组织成1x2的矩阵x=[x1,x2],W组织成2x3的矩阵

4.3 神经网络参数与TensorFlow变量

在TensorFlow中,变量(tf.Variable)的作用就是保存和更新神经网络中的参数


  • 变量
  1. 声明变量
    weights = tf.Variable(tf.random_normal([2,3],stddev=2))
    TensorFlow变量声明函数:tf.Variable()
    并给出了初始化这个变量的方法:tf.random_normal([2,3],stddev=2)
    TensorFlow变量的初始值可以设置成随机值,常量等,
    上面的样例中产生一个2x3的矩阵,矩阵元素均值为0(因为没有给mean设值,默认为0),标准差为2的随机数,满足正态分布的随机数,这是神经网络中的参数初始化的一个常用方法。

  1. TensorFlow目前支持的所有随机数生成器
函数名称 随机数分布 主要参数
tf.random_normal 正态分布 平均值,标准差,取值类型
tf.random_uniform 均匀分布 最大,最小值,取值类型
tf.random_gamma Gamma分布 形状参数alpha,尺度参数beta,取值类型
tf.truncated_normal 正态分布,如果随机值偏离平均值超过2个标准差,这个数就会被重写随机 平均值,标准差,取值类型
  1. TensorFlow中常用的常量声明方法
函数名称 功能 样例
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]

注:在 TensorFlow 中, 一个变量的值在被使用之前,这个变量的初始化过程需要 被明确地调用,通常使用tf.global_variables_ initializer 函数实现初始化所有的变量

样例:了如何通过变量实现神经网络的参数并实现前向传播的过程

import tensorflow as tf
#声明w1,w2变量,通过seed参数设置随机种子,tf.random_normal函数是使随机数服从正态分布
w1 = tf.Variable(tf.random_normal((2,3),stddev=1,seed=1)) #产生2x3矩阵,标准差为1 种子数1
w2 = tf.Variable(tf.random_normal((3,1),stddev=1,seed=1)) #产生3x1矩阵,标准差为1 种子数1

#将输入的特征向量x定义为一个常量
x = tf.constant([[0.7,0.9]])

#用前向传播算法获得神经网络的输出
a = tf.matmul(x,w1)
y = tf.matmul(a,w2)

#初始化所有的变量
init = tf.global_variables_initializer()

#创建会话
sess = tf.Session()

#激活所有初始化的操作
sess.run(init)

#输入y值
print(sess.run(y))

#关闭资源
sess.close()

4.4 通过TensorFlow训练神经网络模型


训练神经网络模型:主要就是合理地设置参数取值
常用的优化算法:反向传播算法


  • 反向传播算法优化流程图
    在这里插入图片描述

  • placeholder :放置数据的机制

为了解决由于常量表示样例当计算图非常大,利用率低的问题,引入placeholder机制

placeholder相当于定义了一个位置,这个位置的数据在程序运行时再指定。

在placeholder定义时,这个位置上的数据类型是需要指定的,和张量一样,placeholder的类型不可改变,维度可推导出。可以不用给出,


import tensorflow as tf
 
w1 = tf.Variable(tf.random_normal([2,3], stddev=1))
w2 = tf.Variable(tf.random_normal([3,1], stddev=1))

#定义placeholder用于存放输入数据 维度给定降低出错率
x = tf.placeholder(tf.float32, shape=(1, 2), name="input")
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)

#创建会话
sess = tf.Session()

#初始化所有Variable变量 用Variable声明的变量必须进行初始化
init = tf.global_variables_initializer()

#运行(激活)初始化操作
sess.run(init)

#注意用placeholder必须向里面喂数据 feed_dict 是字典,不能直接输出print(sess.run(y))
print(sess.run(y, feed_dict={x:[[0.7,0.9]]}))

>>> #输出:[[-1.668653]]


  • 损失函数
    一个batch前向传播得结果之后,需要一个损失函数,描述真实值与预测值的差距
    然后通过反向传播算法来调整神经网络参数的取值使得真实与预测差距缩小。

  • 反向传播算法
    使用sigmoid函数将y转换为0~1之间值,转换后y代表预测是正样本的概率 1-y则相反
# 使用sigmoid函数变换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)))
    
#定义学习率 取值0-1之间常量
learning_rate = 0.001

#定义反向传播算法来优化神经网络中的参数
train_step = tf.train.AdamOptimizer(0.001).minimize(cross_entropy)

cross_entropy:定义了真实值与预测值直接的交叉熵。(分类问题中常用损失函数)


train_step :定义了方向传播的优化方法。TensorFlow目前支持10种优化器,比较常用的是tf.train.GradientDescentOptimizer、tf.train.AdamOptimizer、tf.train.MomentumOptimizer


在定义了反向传播算法之后,通过运行 sess.run(train_ step)就 可以对所有在 GraphKeys.TRAINABLE_VARIABLES 集合中的变量进行优化,使得当前batch损失函数更小


4.5 完整神经网络程序

本示例是训练神经网络解决二分类问题

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

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)

#定义规则得标签
Y = [[int(x1+x2<1)] for (x1, x2) in X]

#创建会话
with tf.Session() as sess:
    #初始化
    init = tf.global_variables_initializer()
    
    sess.run(init)
    
    #位训练时w1和w2数据
    print(sess.run(w1))
    print(sess.run(w2))

    #训练:
    for i in range(5000):
        #每次选取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("经过第 %d 次训练,交叉熵在所有数据上为 %g" %(i,total_cross_entropy))

    #训练后的w1和w2
    print(sess.run(w1))
    print(sess.run(w2))
'''
输出

w1和w2 没训练之前数
[[-0.8113182   1.4845988   0.06532937]
 [-2.4427042   0.0992484   0.5912243 ]]
[[-0.8113182 ]
 [ 1.4845988 ]
 [ 0.06532937]]

经过第 0 次训练,交叉熵在所有数据上为 0.314006
经过第 1000 次训练,交叉熵在所有数据上为 0.0684551
经过第 2000 次训练,交叉熵在所有数据上为 0.033715
经过第 3000 次训练,交叉熵在所有数据上为 0.020558
经过第 4000 次训练,交叉熵在所有数据上为 0.0136867


w1和w2训练之后的数
[[-2.548655   3.0793087  2.8951712]
 [-4.1112747  1.6259071  3.3972702]]
[[-2.3230937]
 [ 3.3011687]
 [ 2.4632082]]

'''

5 总结

本节主要学到图计算,了解了神经网络结构的层次,以及二分类模型的参数训练的神经网络,同时了解了张量的含义,一下列表是对本节设计的变量即概念总结

  • 变量
变量名 变量含义
x Variable / placeholder存入的特征向量即输入值
y_ Variable / placeholder 声明的真实值
y 通过隐藏层激活函数等计算得到的预测值
w Variable随机生成 神经网络中的参数
X 输入值的矩阵
Y 按规则得到的标签矩阵
sess 创建的会话
train_step 优化参数时优化方法
batch 训练集中一小部分训练集
cross_entropy 真实值与预测值的误差损失函数,即交叉熵
init 变量初始化后返回的值,注意所有Variable声明的变量都要初始化

猜你喜欢

转载自blog.csdn.net/qq_38558834/article/details/84583321