zoukankan      html  css  js  c++  java
  • 【学习笔记】tensorflow基础

    认识Tensorflow

    TensorFlow是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor)。它灵活的架构让你可以在多种平台上展开计算,例如台式计算机中的一个或多个CPU(或GPU),服务器,移动设备等等。TensorFlow 最初由Google大脑小组(隶属于Google机器智能研究机构)的研究员和工程师们开发出来,用于机器学习和深度神经网络方面的研究,但这个系统的通用性使其也可广泛用于其他计算领域。

    Tensorflow特点

    • 真正的可移植性
      引入各种计算设备的支持包括CPU/GPU/TPU,以及能够很好地运行在移动端,如安卓设备、ios、树莓派等等
    • 多语言支持
      Tensorflow 有一个合理的c++使用界面,也有一个易用的python使用界面来构建和执行你的graphs,你可以直接写python/c++程序。
    • 高度的灵活性与效率
      TensorFlow是一个采用数据流图(data flow graphs),用于数值计算的开源软件库能够灵活进行组装图,执行图。随着开发的进展,Tensorflow的效率不算在提高
    • 支持
      TensorFlow 由谷歌提供支持,谷歌投入了大量精力开发 TensorFlow,它希望 TensorFlow 成为机器学习研究人员和开发人员的通用语言

    下载以及安装

    必须选择以下类型的TensorFlow之一来安装:

    • TensorFlow仅支持CPU支持。如果您的系统没有NVIDIA®GPU,则必须安装此版本。请注意,此版本的TensorFlow通常会更容易安装(通常在5或10分钟内),因此即使您有NVIDIA GPU,我们建议先安装此版本。
    • TensorFlow支持GPU。TensorFlow程序通常在GPU上比在CPU上运行得更快。因此,如果您的系统具有满足以下所示先决条件的NVIDIA®GPU,并且您需要运行性能关键型应用程序,则应最终安装此版本。

    如果要安装GPU版本的,需要安装一大堆NVIDIA软件:

    • CUDA®Toolkit 8.0。有关详细信息,请参阅 NVIDIA的文档。确保您将相关的Cuda路径名附加到 LD_LIBRARY_PATH环境变量中,如NVIDIA文档中所述。 与CUDA Toolkit 8.0相关的NVIDIA驱动程序。
    • cuDNN v5.1。有关详细信息,请参阅 NVIDIA的文档。确保CUDA_HOME按照NVIDIA文档中的描述创建环境变量。
    • 具有CUDA Compute Capability 3.0或更高版本的GPU卡。有关支持的GPU卡的列表,请参阅 NVIDIA文档。
    • libcupti-dev库,即NVIDIA CUDA Profile Tools界面。此库提供高级分析支持。

    参考地址:http://docs.nvidia.com/cuda/cuda-installation-guide-linux/#axzz4VZnqTJ2A

    在windows下执行命令:

    $ pip3 install tensorflow
    

    Tensorflow初体验

    在python中写一个简单的加法运算如下:

    a = 1
    b = 2
    print(a + b)
    

    但是在Tensorflow中如何完成这个加法运算呢?

    a = tf.constant(1)
    b = tf.constant(2)
    result = tf.add(a, b)
    
    with tf.Session() as sess:
        print(sess.run(result))
    

    a和b是两个张量,result是加法操作,需要在session下运行。

    数据流图:

    Tensorflow进阶

    TensorFlow程序通常被组织成一个构建阶段和一个执行阶段. 在构建阶段, op的执行步骤被描述成一个图. 在执行阶段, 使用会话执行执行图中的op。我们来构建一个简单的计算图。每个节点采用零个或多个张量作为输入,并产生张量作为输出。一种类型的节点是一个常数。像所有TensorFlow常数一样,它不需要任何输入,它输出一个内部存储的值。

    获取调用:

    • tf.get_default_graph()
    • op、session或者tensor 的graph属性

    构建图

    tf.Graph()创建一张图,在with g.as_default()块内的代码都是属于它所创建的图。

    g = tf.Graph()
    
    print(g)
    
    with g.as_default():
        a = tf.constant(1)
        print(a.graph)
    

    op

    计算图中的每个节点可以有任意多个输入和任意多个输出,每个节点描述了一种运算操作(operation, op),节点可以算作运算操作的实例化(instance)。一种运算操作代表了一种类型的抽象运算,比如矩阵乘法、加法。tensorflow内建了很多种运算操作,如下表所示:

    类型 示例
    标量运算 Add、Sub、Mul、Div、Exp、Log、Greater、Less、Equal
    向量运算 Concat、Slice、Splot、Constant、Rank、Shape、Shuffle
    矩阵运算 Matmul、MatrixInverse、MatrixDeterminant
    带状态的运算 Variable、Assign、AssignAdd
    神经网络组件 SoftMax、Sigmoid、ReLU、Convolution2D、MaxPooling
    存储、恢复 Save、Restore
    队列及同步运算 Enqueue、Dequeue、MutexAcquire、MutexRelease
    控制流 Merge、Switch、Enter、Leave、NextIteration

    会话

    tf.Session()

    运行TensorFlow操作图的类,使用默认注册的图(可以指定运行图)

    a = tf.constant(1)
    b = tf.constant(2)
    result = tf.add(a, b)
    
    sess = tf.Session()
    print(sess.run(result))
    

    在开启会话的时候指定图

    with tf.Session(graph=g) as sess:
    

    资源释放:

    会话可能拥有很多资源,如 tf.Variable,tf.QueueBase和tf.ReaderBase。在不再需要这些资源时,重要的是释放这些资源。要做到这一点,既可以调用tf.Session.close会话中的方法,也可以使用会话作为上下文管理器。以下两个例子是等效的:

    # 使用close手动关闭
    sess = tf.Session()
    sess.run(...)
    sess.close()
    
    # 使用上下文管理器
    with tf.Session() as sess:
      sess.run(...)
    

    配置:config=tf.ConfigProto(log_device_placement=True)

    a = tf.constant(1)
    b = tf.constant(2)
    result = tf.add(a, b)
    
    with tf.Session(config=tf.ConfigProto(log_device_placement=True)) as sess:
        print(sess.run(result))
    

    交互式session:tf.InteractiveSession()

    run方法

    run(fetches, feed_dict=None, options=None, run_metadata=None)

    运行ops和计算tensor

    • fetches 可以是单个图形元素,或任意嵌套列表,元组,namedtuple,dict或OrderedDict
    • feed_dict 允许调用者覆盖图中指定张量的值

    异常

    • RuntimeError:如果它Session处于无效状态(例如已关闭)。
    • TypeError:如果fetches或feed_dict键是不合适的类型。
    • ValueError:如果fetches或feed_dict键无效或引用 Tensor不存在。

    as_default()方法:

    返回使此对象成为默认会话的上下文管理器。获取当前的默认会话,请使用 tf.get_default_session

    c = tf.constant(..)
    sess = tf.Session()
    
    with sess.as_default():
      assert tf.get_default_session() is sess
      print(c.eval())
    

    注意: 使用这个上下文管理器并不会在退出的时候关闭会话,还需要手动的去关闭

    c = tf.constant(...)
    sess = tf.Session()
    with sess.as_default():
      print(c.eval())
    # ...
    with sess.as_default():
      print(c.eval())
    
    sess.close()
    

    Feed操作

    TensorFlow还提供了feed机制, 该机制可以临时替代图中的任意操作中的tensor可以对图中任何操作提交补丁,直接插入一个 tensor。feed 使用一个 tensor 值临时替换一个操作的输入参数,从而替换原来的输出结果.

    feed 只在调用它的方法内有效, 方法结束,feed就会消失。最常见的用例是将某些特殊的操作指定为"feed"操作, 标记的方法是使用 tf.placeholder() 为这些操作创建占位符.并且在Session.run方法中增加一个feed_dict参数

    意义:在程序执行的时候,不确定输入的是什么,提前“占个坑”

    语法:placeholder提供占位符,run时候通过feed_dict指定参数

    ph = tf.placeholder(tf.float32, [None, 2])
    
    print(ph)
    
    with tf.Session() as sess:
        print(sess.run(ph, feed_dict={ph: [[1, 2], [3, 4], [5, 6]]}))
    

    张量

    TensorFlow用张量这种数据结构来表示所有的数据.你可以把一个张量想象成一个n维的数组或列表.一个张量有一个静态类型和动态类型的维数.张量可以在图中的节点之间流通.其实张量更代表的就是一种多位数组。

    张量的阶

    在TensorFlow系统中,张量的维数来被描述为阶.但是张量的阶和矩阵的阶并不是同一个概念.张量的阶(有时是关于如顺序或度数或者是n维)是张量维数的一个数量描述.比如,下面的张量(使用Python中list定义的)就是2阶.

    t = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    

    你可以认为一个二阶张量就是我们平常所说的矩阵,一阶张量可以认为是一个向量.

    数学实例 Python 例子
    0 纯量 (只有大小) s = 483
    1 向量 (大小和方向) v = [1.1, 2.2, 3.3]
    2 矩阵 (数据表) m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    3 3阶张量 (数据立体) t = [[[2], [4], [6]], [[8], [10], [12]], [[14], [16], [18]]]
    n n阶 (自己想想看) ....

    数据类型

    Tensors有一个数据类型属性.你可以为一个张量指定下列数据类型中的任意一个类型:

    数据类型 Python 类型 描述
    DT_FLOAT tf.float32 32 位浮点数.
    DT_DOUBLE tf.float64 64 位浮点数.
    DT_INT64 tf.int64 64 位有符号整型.
    DT_INT32 tf.int32 32 位有符号整型.
    DT_INT16 tf.int16 16 位有符号整型.
    DT_INT8 tf.int8 8 位有符号整型.
    DT_UINT8 tf.uint8 8 位无符号整型.
    DT_STRING tf.string 可变长度的字节数组.每一个张量元素都是一个字节数组.
    DT_BOOL tf.bool 布尔型.
    DT_COMPLEX64 tf.complex64 由两个32位浮点数组成的复数:实数和虚数.
    DT_QINT32 tf.qint32 用于量化Ops的32位有符号整型.
    DT_QINT8 tf.qint8 用于量化Ops的8位有符号整型.
    DT_QUINT8 tf.quint8 用于量化Ops的8位无符号整型.

    张量的属性

    • graph:张量所属的默认图
    • op:张量的操作名
    • name:张量的字符串描述
    • shape:张量形状

    张量的动态形状与静态形状

    TensorFlow中,张量具有静态形状和动态形状。

    静态形状:创建一个张量或者由操作推导出一个张量时,初始状态的形状

    • tf.Tensor.get_shape:获取静态形状

    • tf.Tensor.set_shape():更新Tensor对象的静态形状,通常用于在不能直接推断的情况下

    动态形状:一种描述原始张量在执行过程中的一种形状

    • tf.reshape:创建一个具有不同动态形状的新张量
    # 静态形状和动态形状
    ph = tf.placeholder(tf.float32, [None, 2])
    
    print(ph)
    
    ph.set_shape([3, 2])
    print(ph)
    
    # ph.set_shape([2, 3])
    
    ph = tf.reshape(ph, [2, 3])
    print(ph)
    

    张量操作

    在tensorflow中,有很多操作张量的函数,有生成张量、创建随机张量、张量类型与形状变换和张量的切片与运算

    固定值张量

    tf.zeros(shape, dtype=tf.float32, name=None)

    创建所有元素设置为零的张量。此操作返回一个dtype具有形状shape和所有元素设置为零的类型的张量。

    tf.zeros_like(tensor, dtype=None, name=None)

    给tensor定单张量(),此操作返回tensor与所有元素设置为零相同的类型和形状的张量。

    tf.ones(shape, dtype=tf.float32, name=None)

    创建一个所有元素设置为1的张量。此操作返回一个类型的张量,dtype形状shape和所有元素设置为1。

    tf.ones_like(tensor, dtype=None, name=None)

    给tensor定单张量(),此操作返回tensor与所有元素设置为1 相同的类型和形状的张量。

    tf.fill(dims, value, name=None)

    创建一个填充了标量值的张量。此操作创建一个张量的形状dims并填充它value。

    tf.constant(value, dtype=None, shape=None, name='Const')

    创建一个常数张量。

    一个张量包含了一下几个信息

    • 一个名字,它用于键值对的存储,用于后续的检索:Const: 0
    • 一个形状描述, 描述数据的每一维度的元素个数:(2,3)
    • 数据类型,比如int32,float32
    创建随机张量

    一般我们经常使用的随机数函数 Math.random() 产生的是服从均匀分布的随机数,能够模拟等概率出现的情况,例如 扔一个骰子,1到6点的概率应该相等,但现实生活中更多的随机现象是符合正态分布的,例如20岁成年人的体重分布等。

    假如我们在制作一个游戏,要随机设定许许多多 NPC 的身高,如果还用Math.random(),生成从140 到 220 之间的数字,就会发现每个身高段的人数是一样多的,这是比较无趣的,这样的世界也与我们习惯不同,现实应该是特别高和特别矮的都很少,处于中间的人数最多,这就要求随机函数符合正态分布。

    tf.truncated_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)

    从截断的正态分布中输出随机值,和 tf.random_normal() 一样,但是所有数字都不超过两个标准差

    tf.random_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)

    从正态分布中输出随机值,由随机正态分布的数字组成的矩阵

    # 正态分布的 4X4X4 三维矩阵,平均值 0, 标准差 1
    normal = tf.truncated_normal([4, 4, 4], mean=0.0, stddev=1.0)
    
    a = tf.Variable(tf.random_normal([2,2],seed=1))
    b = tf.Variable(tf.truncated_normal([2,2],seed=2))
    init = tf.global_variables_initializer()
    with tf.Session() as sess:
        sess.run(init)
        print(sess.run(a))
        print(sess.run(b))
    
    输出:
    [[-0.81131822  1.48459876]
     [ 0.06532937 -2.44270396]]
    [[-0.85811085 -0.19662298]
     [ 0.13895047 -1.22127688]]
    

    tf.random_uniform(shape, minval=0.0, maxval=1.0, dtype=tf.float32, seed=None, name=None)

    从均匀分布输出随机值。生成的值遵循该范围内的均匀分布 [minval, maxval)。下限minval包含在范围内,而maxval排除上限。

    a = tf.random_uniform([2,3],1,10)
    
    with tf.Session() as sess:
      print(sess.run(a))
    

    tf.random_shuffle(value, seed=None, name=None)

    沿其第一维度随机打乱

    tf.set_random_seed(seed)

    设置图级随机种子

    张量变换

    TensorFlow提供了几种操作,您可以使用它们在图形中改变张量数据类型。

    • tf.string_to_number(string_tensor, out_type=None, name=None)
    • tf.to_double(x, name='ToDouble')
    • tf.to_float(x, name='ToFloat')
    • tf.to_bfloat16(x, name='ToBFloat16')
    • tf.to_int32(x, name='ToInt32')
    • tf.to_int64(x, name='ToInt64')
    • tf.cast(x, dtype, name=None)
    形状和变换
    • tf.shape(input, name=None)
    • tf.size(input, name=None)
    • tf.rank(input, name=None)
    • tf.reshape(tensor, shape, name=None)
    • tf.squeeze(input, squeeze_dims=None, name=None)
    • tf.expand_dims(input, dim, name=None)
    切片与扩展

    TensorFlow提供了几个操作来切片或提取张量的部分,或者将多个张量加在一起

    • tf.slice(input_, begin, size, name=None)
    • tf.split(split_dim, num_split, value, name='split')
    • tf.tile(input, multiples, name=None)
    • tf.pad(input, paddings, name=None)
    • tf.concat(concat_dim, values, name='concat')
    • tf.pack(values, name='pack')
    • tf.unpack(value, num=None, name='unpack')
    • tf.reverse_sequence(input, seq_lengths, seq_dim, name=None)
    • tf.reverse(tensor, dims, name=None)
    • tf.transpose(a, perm=None, name='transpose')
    • tf.gather(params, indices, name=None)
    • tf.dynamic_partition(data, partitions, num_partitions, name=None)
    • tf.dynamic_stitch(indices, data, name=None)
    张量复制与组合
    • tf.identity(input, name=None)
    • tf.tuple(tensors, name=None, control_inputs=None)
    • tf.group(*inputs, **kwargs)
    • tf.no_op(name=None)
    • tf.count_up_to(ref, limit, name=None)
    逻辑运算符
    • tf.logical_and(x, y, name=None)
    • tf.logical_not(x, name=None)
    • tf.logical_or(x, y, name=None)
    • tf.logical_xor(x, y, name='LogicalXor')
    比较运算符
    • tf.equal(x, y, name=None)
    • tf.not_equal(x, y, name=None)
    • tf.less(x, y, name=None)
    • tf.less_equal(x, y, name=None)
    • tf.greater(x, y, name=None)
    • tf.greater_equal(x, y, name=None)
    • tf.select(condition, t, e, name=None)
    • tf.where(input, name=None)
    判断检查
    • tf.is_finite(x, name=None)
    • tf.is_inf(x, name=None)
    • tf.is_nan(x, name=None)
    • tf.verify_tensor_all_finite(t, msg, name=None) 断言张量不包含任何NaN或Inf
    • tf.check_numerics(tensor, message, name=None)
    • tf.add_check_numerics_ops()
    • tf.Assert(condition, data, summarize=None, name=None)
    • tf.Print(input_, data, message=None, first_n=None, summarize=None, name=None)

    变量

    其实变量的作用在语言中相当,都有存储一些临时值的作用或者长久存储。在Tensorflow中当训练模型时,用变量来存储和更新参数。变量包含张量(Tensor)存放于内存的缓存区。建模时它们需要被明确地初始化,模型训练后它们必须被存储到磁盘。值可在之后模型训练和分析是被加载。

    变量的创建

    tf.Variable.init(initial_value, trainable=True, collections=None, validate_shape=True, name=None)

    创建一个带值的新变量initial_value

    • initial_value:A Tensor或Python对象可转换为a Tensor.变量的初始值.必须具有指定的形状,除非validate_shape设置为False.
    • trainable:如果True,默认值也将该变量添加到图形集合GraphKeys.TRAINABLE_VARIABLES,该集合用作Optimizer类要使用的变量的默认列表
    • collections:图表集合键列表,新变量添加到这些集合中.默认为[GraphKeys.VARIABLES]
    • validate_shape:如果False允许使用未知形状的值初始化变量,如果True,默认形状initial_value必须提供.
    • name:变量的可选名称,默认'Variable'并自动获取

    创建当一个变量时,将你一个张量作为初始值传入构造函数Variable().TensorFlow提供了一系列操作符来初始化张量,值初始的英文常量或是随机值。像任何一样Tensor,创建的变量Variable()可以用作图中其他操作的输入。此外,为Tensor该类重载的所有运算符都被转载到变量中,因此您也可以通过对变量进行算术来将节点添加到图形中。

    调用tf.Variable()向图中添加了几个操作:

    • 一个variable op保存变量值。
    • 初始化器op将变量设置为其初始值。这实际上是一个tf.assign操作。
    • 初始值的ops,例如 示例中biases变量的zeros op 也被添加到图中。
    var = tf.Variable(tf.random_normal([3, 3], mean=0, stddev=1.0), name="variable")
    
    print(var)
    

    变量的初始化

    • 变量的初始化必须在模型的其它操作运行之前先明确地完成。最简单的方法就是添加一个给所有变量初始化的操作,并在使用模型之前首先运行那个操作。最常见的初始化模式是使用便利函数 initialize_all_variables()将Op添加到初始化所有变量的图形中。

      init_op = tf.global_variables_initializer()
      
      with tf.Session() as sess:
        sess.run(init_op)
      
    • 还可以通过运行其初始化函数op来初始化变量,从保存文件还原变量,或者简单地运行assign向变量分配值的Op。实际上,变量初始化器op只是一个assignOp,它将变量的初始值赋给变量本身。assign是一个方法,后面方法的时候会提到

    with tf.Session() as sess:
        sess.run(w.initializer)
    

    可视化学习Tensorboard

    数据序列化-events文件:TensorBoard 通过读取 TensorFlow 的事件文件来运行

    tf.summary.FileWriter('/tmp/tensorflow/summary/model/', graph=
    default_graph)
    返回filewriter,写入事件文件到指定目录(最好用绝对路径),以提供给tensorboard使用

    开启:tensorboard --logdir=/tmp/tensorflow/summary/model/

    一般浏览器打开为127.0.0.1:6006

    图中的符号意义

  • 相关阅读:
    vector
    codeforces 1453D. Checkpoints
    [ICPC2019 WF]Hobson's Trains
    [ICPC2019 WF]Circular DNA
    计算几何板子
    CSP-S2020 贪吃蛇(洛谷民间数据)
    CSP-S2020 函数调用(洛谷民间数据)
    [NOI Online #3 提高组]魔法值
    [NOI Online #1 提高组]冒泡排序
    佳能m62套机5500 佳能EOS M50 M6 MARK2 II二代 最低到过5800
  • 原文地址:https://www.cnblogs.com/zhangfengxian/p/10625314.html
Copyright © 2011-2022 走看看