TensorFlow基础

一、基础概念

1. 从Hello World开始

    import tensorflow as tf
    #创建一个常量运算,将作为一个节点加入到默认计算图中
    hello = tf.constant("Hello, World!")
    #创建一个TF对话
    sess = tf.Session()
    #运行并获得结果
    print(sess.run(hello))
    # b'Hello, World!'  
    #输出前面的'b'表示Bytes literals(字节文字)

2. TensorFlow的概念

  • Tensor 张量
    数据结构:多维数组
  • Flow 流
    计算模型:张量之间通过计算而转换的过程

TensorFlow是一个通过计算图的形式表述计算的编程系统
每一个计算都是计算图上的一个节点,节点之间的边描述了计算之间的关系

3. 计算图(数据流图)的概念

计算图是一个有向图,由以下内容构成

  • 一组节点,每个节点都代表一个操作,是一种运算
  • 一组有向边,每条边代表节点之间的关系( 数据传递控制依赖 )

TensorFlow有两种边

  • 常规边(实线):代表数据依赖关系。一个节点的运算输出成为另一个节点的输入,两个节点之间有tensor流动( 值传递 )
  • 特殊边(虚线):不携带值,表示两个节点之间的控制相关性。比如,happens-before关系,源节点必须在目的节点执行前完成执行

4. 计算图的实例

计算图节点输出的结果不是一个具体的数字,而是一个张量的结构

    #一个简单计算图
    node1 = tf.constant(3.0, tf.float32, name = "node1")
    node2 = tf.constant(4.0, tf.float32, name = "node2")
    node3 = tf.add(node1, node2)
    print(node3)
    # Tensor("Add:0", shape=(), dtype=float32)

创建计算图就是建立计算模型,执行对话才能提供数据并获得结果

    #建立对话并显示运行结果
    sess = tf.Session()
    #更新变量并返回计算结果
    print("运行sess.run(node3)的结果:", sess.run(node3))
    #关闭session 
    sess.close()
    # 运行sess.run(node3)的结果: 7.0

5. 张量的概念

  • 在TensorFlow中,所有的数据都通过张量的形式来表示
  • 从功能的角度,张量可以简单理解为多维数组
    零阶张量表示标量(scalar),也就是一个
    一阶张量向量(vector),也就是 一维数组
    n阶张量可以理解为一个n维数组
  • 张量并没有真正保存数字,它保存的是计算过程

6. 张量的属性

    Tensor("Add:0", shape=(), dtype=float32)
  • 名字(name)
    "node:src_output":node 节点名称,src_output 来自节点的第几个输出
  • 形状(shape)
    张量的维度信息,shape=(),表示是标量
  • 类型(type)
    每一个张量会有一个唯一的类型
    TensorFlow会对参与运算的所有张量进行类型检查,发现类型不匹配时会报错

7. 张量的形状

三个术语描述张量的维度,阶(rank)、形状(shape)、维数(dimension number)

形状 维数 例子
0 () 0-D 4
1 (D0) 1-D [2,3,5]
2 (D0,D1) 2-D [[2,3],[3,4]]
3 (D0,D1,D2) 3-D [[[7],[3]],[[2],[4]]]
N (D0,D1,...,Dn-1) n-D 形为(D0,D1,...,Dn-1的张量)
    tens1 = tf.constant([[[1,2,2],[2,2,3]],
                        [[3,5,6],[5,4,3]],
                        [[7,0,1],[9,1,9]],
                        [[11,12,7],[1,3,14]]], name="tens1")
    print(tens1)
    #Tensor("tens1:0", shape=(4, 2, 3), dtype=int32)
    #shape,4表示最外维有4个元素,2表示中间维度有2个元素,3表示最里维有3个元素
    
    #查看张量的形状
    scalar = tf.constant(100)
    vector = tf.constant([1, 2, 3, 4, 5])
    matrix = tf.constant([[1, 2, 3],[4, 5, 6]])
    cube_matrix = tf.constant([[[1],[2],[3]], [[4],[5],[6]], [[7],[8],[9]]])
    
    print(scalar.get_shape())
    print(vector.get_shape())
    print(matrix.get_shape())
    print(cube_matrix.get_shape())
    # ()
    # (5,)
    # (2, 3)
    # (3, 3, 1)

8. 获取张量的元素

  • 阶为1的张量等价于向量
  • 阶为2的张量等价于矩阵,通过t[i, j]获取元素
  • 阶为3的张量,通过t[i, j, k]获取元素
    tens2 = tf.constant([[[1,2],[2,3]],[[3,4],[5,6]]])
    sess = tf.Session()
    print(sess.run(tens2)[1, 1, 0])
    sess.close()
    # 5

9. 张量的类型

TensorFlow支持14种不同的类型

  • 实数 tf.float32, tf.float64
  • 整数 tf.int8, tf.int16, tf.int32, tf.int64, tf.uint8
  • 布尔 tf.bool
  • 复数 tf.complex64, tf.complex128
    默认类型:
  • 不带小数点的数会被默认为int32
  • 带小数点的会被默认为float32
    import tensorflow as tf
    a = tf.constant([1, 2], name = "a")
    b = tf.constant([2.0, 3.0], name = "b")
    result = a + b
    # 类型不匹配而报错:Tensor conversion requested dtype int32 for Tensor with dtype float32: 'Tensor("b:0", shape=(2,), dtype=float32)'

10. 操作

  • 计算图中的节点就是操作
    加减乘除运算、变量初始赋值都是操作
  • 每个运算操作都有属性,它在构建图的时候需要确定下来
  • 操作可以和计算设备绑定,指定操作在某个设备上执行
  • 操作之间存在顺序关系,这些操作之间的依赖就是“边”
  • 如果操作A的输入是操作B执行的结果,那么这个操作A就依赖于操作B
    import tensorflow as tf
    tf.reset_default_graph() #清除default graph和不断增加的节点
    #定义变量a
    a = tf.Variable(1, name = "a")
    b= tf.add(a, 1, name = "b")
    c = tf.multiply(b, 4, name = "c")
    d = tf.subtract(c, b, name = "d")
    logdir = 'D:\ForPython\log'
    #生成一个写日志的writer,并将当前的TensorFlow计算图写入日志
    writer = tf.summary.FileWriter(logdir, tf.get_default_graph())
    writer.close()

二、基本运算

1. TensorFlow运行模型——会话

会话拥有并管理TensorFlow程序运行时的所有资源,当所有计算完成后需要关闭会话帮助系统回收资源

  • 会话的典型模式1
    #定义计算图
    tens1 = tf.constant([1, 2, 3])
    #创建一个会话
    sess = tf.Session()
    try:
        #使用这个创建好的会话来得到关心的运算的结果,比如盗用 sess.run(result)
        #来得到张量result的值
        print(sess.run(tens1))
    except:
        print("Exception")
    finally:
        #关闭会话使得本次运行中使用到的资源可以被释放
        sess.close()
    # [1 2 3]    
  • 会话的典型模式2
    node1 = tf.constant(3.0, tf.float32, name = "node1")
    node2 = tf.constant(4.0, tf.float32, name = "node2")
    result = tf.add(node1, node2)
    #创建一个会话,并通过Python中的上下文管理器来管理这个会话
    with tf.Session() as sess:
        #使用这创建好的会话来计算关心的结果
        print(sess.run(result))
    #不需要再调用Session.close()函数来关闭会话
    #当上下文退出时会话关闭和资源释放也自动完成了
    # 7.0    
  • 指定默认的会话
    node1 = tf.constant(3.0, tf.float32, name = "node1")
    node2 = tf.constant(4.0, tf.float32, name = "node2")
    result = tf.add(node1, node2)
    sess = tf.Session() 
    with sess.as_default(): #指定sess为默认的会话,故可直接调用result.eval()
        print(result.eval())
    # 7.0    
    #未指定时,result.eval()必须说明会话参数
    print(result.eval(session = sess)
    # 7.0
    #用sess.run()同样可以完成相同功能
    print(sess.run(result))
    # 7.0
    
  • 交互式环境下设置默认会话
    交互式环境下,Python脚本或者Jupyter编辑器下,通过设置默认会话来获取张量的取值更加方便,tf.InteractiveSession 使用这个函数会自动将生成的会话注册为默认会话
    node1 = tf.constant(3.0, tf.float32, name = "node1")
    node2 = tf.constant(4.0, tf.float32, name = "node2")
    result = tf.add(node1, node2)
    #定义交互式的session,同时注册为默认会话
    sess = tf.InteractiveSession()
    print(result.eval())
    sess.close()
    # 7.0

2. 常量与变量

常量:在运行过程中不会改变的单元,在TensorFlow中无须进行初始化操作

    #创建语句
    constant_name = tf.constant(value)
    #示例
    a = tf.constant(1.0, name = "a")

变量:在运行过程中值会改变的单元,在TensorFlow中须进行初始化操作

    #创建语句
    name_variable = tf.Variable(value, name)  #注意V是大写字母
    #个别变量初始化
    init_op = name_variable.initializer()
    #所有变量初始化
    init_op = tf.global_variables_initializer()
    
    #示例
    node1 = tf.Variable(3.0, tf.float32, name = "node1")
    node2 = tf.Variable(4.0, tf.float32, name = "node2")
    result = tf.add(node1, node2, name = "add")
    sess = tf.Session()
    #变量初始化
    init = tf.global_variables_initializer()
    sess.run(init)
    print(sess.run(result))
    # 7.0

3. 变量赋值

与传统编程语言不同,TensorFlow中的变量定义后,一般无需人工赋值,系统会根据算法模型,训练优化过程中自动调整变量对应的数值

    #如果需要人工赋值,并且不希望训练模型自动更改它
    epoch = tf.Variable(0, name = 'epoch', trainable = False) #指明不参加训练
    #特殊情况需要人工更新,可用变量赋值语句
    update_op = tf.assign(variable_to_be_updated, new_value) #被更新变量,新值
    
    #示例:通过变量赋值1、2、3...5
    import TensorFlow as tf
    value = tf.Variable(0, name = "value")
    one = tf.constant(1)
    new_value = tf.add(value, one)
    update_value = tf.assign(value, new_value)
    
    init = tf.global_variables_initializer()
    
    with tf.Session() as sess:
        sess.run(init)
        for _ in range(5):    #执行5次
            sess.run(update_value) #每一次更新值(+1)
            print(sess.run(value))
    # 1
    # 2
    # 3
    # 4
    # 5

4. 占位符、Feed数据填充和Fetch数据获取

TensorFlow中的Variable变量类型,在定义时需要初始化,但有些变量定义时并不知道其数值,只有当真正开始运行程序时,才由外部输入,比如训练数据,这时候需要用到占位符
tf.placeholder占位符,是TensorFlow中特有的一种数据结构,类似动态变量,函数的参数、或者C语言或者Python语言中格式化输出的“%”占位符。

  • 占位符 placeholder
    #函数接口:先定义一种数据,参数为数据的 Type和 Shape
    tf.placeholder(dtype, shape = None, name = None)
    x = tf.placeholder(tf.float32, [2, 3], name = 'tx')
    #生成一个2x3的二维数组,矩阵中每个元素类型为tf.float32,内部对应的符号名称是tx
  • Feed数据填充

如果构建了一个包含placeholder操作的计算图,当在session中调用run方法时,placeholder占用的变量必须通过feed_dict参数传递进去

    #定义变量a、b
    a = tf.placeholder(tf.float32, name = 'a')
    b = tf.placeholder(tf.float32, name = 'b')
    #定义a*b的操作 c
    c = tf.multiply(a, b, name ='c')
    #定义初始化所有变量的操作init
    init = tf.global_variables_initializer()
    #创建一个会话,并通过Python中的上下文管理器来管理这个会话
    with tf.Session() as sess:
        sess.run(init) #使用的是占位符,因此这里不进行变量初始化也可以 
        #通过feed_dict 的参数传递,按字典格式
        result = sess.run(c, feed_dict = {a : 8.0, b : 3.5})
        print(result)
    # 28.0    
  • 多个操作可以通过一次Feed完成执行
    #定义变量 a、b
    a = tf.placeholder(tf.float32, name = "a")
    b = tf.placeholder(tf.float32, name = "b")
    #定义操作 c、d
    c = tf.multiply(a, b, name ="c")    
    d = tf.subtract(a, b, name = 'd')
    
    init = tf.global_variables_initializer()
    
    with tf.Session() as sess:
        sess.run(init)
        result = sess.run([c,d],feed_dict = {a:[8.0, 2.0, 3.5], b:[1.5, 2.0, 4.]})
        print(result)
        #取结果中的第一个
        print(result[0])    
        # [array([ 12.,   4.,  14.], dtype=float32), array([ 6.5,  0. , -0.5], dtype=float32)]
        # [ 12.   4.  14.] 
        
        #一次返回多个值分别赋给多个变量
        rc, rd = sess.run([c,d],feed_dict = {a:[8.0, 2.0, 3.5], b:[1.5, 2.0, 4.]})
        print("value of c = ", rc, "value of d = ", rd)
        # value of c =  [ 12.   4.  14.] value of d =  [ 6.5  0.  -0.5]

三、TensorBoard 可视化初步

TensorBoard是TensorFlow的可视化工具,通过TensorFlow程序运行过程中输出的日志文件可视化TensorFlow程序的运行状态,TensorBoard和TensorFlow程序跑在不同的进程中。

    import tensorflow as tf
    
    #清除default graph 和不断增加的节点
    tf.reset_default_graph()
    
    #日志
    logdir = 'D:\ForPython\log'
    
    #定义一个简单的计算图,实现向量加法的操作
    input1 = tf.constant([1.0, 2.0, 3.0], name = "input1")
    input2 = tf.Variable(tf.random_uniform([3]), name = "input2")
    output = tf.add_n([input1, input2], name = "add")
    
    #生成一个写日志的writer, 并将当前的TensorFlow计算图写入日志
    writer = tf.summary.FileWriter(logdir, tf.get_default_graph())
    writer.close()

启动TensorBoard

  • 在Anaconda Prompt 中先进入日志存放的目录
  • 再运行TensorBoard,并将日志的地址指向程序日志输出的地址
  • 命令:tensorboard --logdir=D:\ForPython\log
  • 启动服务的端口默认为6006,使用 --port 参数可以改编启动服务的端口
启动TensorBoard
计算图
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容

  • @Deprecated让我们拥抱tensorflow2.0吧 0. 概述 TensorFlow提供了实现机器学习算...
    音符纸飞机阅读 741评论 0 11
  • TensorFlow采用声明式编程范式,其优势包括: 代码可读性强 支持引用透明,声明式编程没有内部状态,不依赖于...
    林逸凡_lyf阅读 793评论 0 0
  • 之前发过了几篇关于机器学习的帖子,使用的框架多为TensorFlow。TensorFlow 是一个用于人工智能的开...
    BlackBlog__阅读 1,068评论 0 4
  • 要事第一,养好身体,才能更好的工作 ! 今天运气好 用半天的时间完成了一天的工作 开熏......晚安.........
    仙女本仙吖阅读 136评论 1 1
  • 姓名:葛咪霞 公司:宁波伟大联盟国际货运代理有限公司 【日精进打卡第29天】 【知~学习】看书 听广播 【经典名句...
    格格8阅读 275评论 0 0