美文网首页
TensorFlow自学第1篇——基础知识

TensorFlow自学第1篇——基础知识

作者: 锅底一盆面 | 来源:发表于2019-01-15 22:58 被阅读0次

    声明


    机缘巧合下,如雷贯耳了TensorFlow框架。略览后欣喜,遂决心深入研究。文章是本人在自研人工智能的道路上,通过阅读、视频、博客等形式记录的所见所闻。介于小白鼠属性满格,难免漏洞,请诸位大神不吝赐教,也请其他小白不要纠结。若涉及侵权,烦请告知,必删;若阅完有点滴心得,定窃喜不枉辛劳。

    计算机自发明以来,一直扮演人类祖先的角色:以自我为中心(计算密集型,涉及CPU计算、GPU计算等,比如TensorFlow),疯狂攫取外界资源(IO密集型——涉及HTTP请求、磁盘操作等,比如Django、Scrapy)。直至现今,疯狂到想让电脑直接变成人脑。哎,技术无罪,有罪的是掌握技术的人。为什么要写这段呢,因为我也不知道。

    TensorFlow简单三步骤:使用 tensor 表示数据;使用图 (graph) 来表示计算任务;在会话(session)中运行图。TensorFlow字面意思是由Tensor(张量)和Flow(流)组成。实际上还包括:
    1、Operation,专门运算的操作节点;
    2、Graph图,整个程序的结构,包括输入,输入的流向,输出等;
    3、Session会话,专门用于运行程序所建立的图。

    TensorFlow分为前端系统和后端系统,前端系统(Tensor、Operation、Graph)负责定义程序的图的结构,后端系统(Session)负责运算图的结构。TensorFlow程序通常被组织成一个构建阶段和一个执行阶段。在构建阶段,op的执行步骤被描述成一个图。在执行阶段,使用会话执行执行图中的op。


    Tensor

    张量,重要概念。类型是对numpy的ndarray类型的封装,类似于数组;阶,类似于数组的维。张量有如下属性:operation、name、shape(0维表示为(),1维表示为(2),2维表示为(?,2))、graph。在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')
    创建一个常数张量。
    
    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)
    从正态分布中输出随机值,由随机正态分布的数字组成的矩阵
    
    tf.random_uniform(shape, minval=0.0, maxval=1.0, dtype=tf.float32, seed=None, name=None)
    从均匀分布输出随机值。生成的值遵循该范围内的均匀分布 [minval, maxval)。下限minval包含在范围内,而maxval排除上限。
    
    tf.random_shuffle(value, seed=None, name=None)
    沿其第一维度随机打乱
    
    tf.set_random_seed(seed)
    设置图级随机种子
    
    tf.string_to_number(string_tensor, out_type=None, name=None)
    将输入Tensor中的每个字符串转换为指定的数字类型。注意,int32溢出导致错误,而浮点溢出导致舍入值
    
    tf.shape(input, name=None)
    返回张量的形状
    
    tf.squeeze(input, squeeze_dims=None, name=None)
    这个函数的作用是将input中维度是1的那一维去掉。但是如果你不想把维度是1的全部去掉,那么你可以使用squeeze_dims参数,来指定需要去掉的位置
    
    tf.expand_dims(input, dim, name=None)
    该函数作用与squeeze相反,添加一个指定维度
    

    张量频繁用到的操作是形状的改变,即维度的变化(一维变二维,或者两列变三列)。涉及静态改变形状和动态改变形状。

    静态形状的改变指:不改变维度,只改变维度中的行列数;一旦张量形状固定,不能再次进行修改。
    动态形状的改变指改变维度。动态形状和静态形状的区别:有没有生成一个新的张量。两种形状的改变都不能改变张量的总大小。

    如果你定义了一个没有标明具体维度的占位符,即用None表示维度,那么当你将值输入到占位符时,这些无维度就是一个具体的值,并且任何一个依赖这个占位符的变量,都将使用这个值。

    注意:
    1、转换静态形状的时候,1-D到1-D,2-D到2-D,不能跨阶数改变形状;
    2、对于已经固定或者设置静态形状的张量/变量,不能再次设置静态形状;
    3、tf.reshape()动态创建新张量时,元素个数不能不匹配;
    4、运行时候,动态获取张量的形状值,只能通过tf.shape(tensor)[]。

    Operation

    只要使用TensorFlow框架的API定义的函数都是Operation,Tensor也是Operation,指代的是数据。

    Graph

    图由整个程序构造,可用系统默认的图,也可自定义。一个Session只能运行一个图。

    Session

    相当于中间件,对上解析并运行定义的图结构,对下分配CPU或者GPU资源进行计算,掌握资源(变量、队列、线程等)。如果不与图绑定,那会话使用默认的图。

    Session可能返回错误:RuntimeError、TypeError、ValueError。

    Feed机制

    将某些特殊的操作指定为"feed"操作,标记的方法是使用 tf.placeholder() 为这些操作创建占位符,并且在Session.run方法中增加一个feed_dict参数。突然感觉灭霸还是个心细的紫叔叔,让矮人族打造无限手套的时候特意留了六个位置,因为他知道,早晚要用到这六个位置,跟TensorFlow里的占位符简直异曲同工。如果没有正确提供feed参数,placeholder() 操作将会产生错误。

    tf.placeholder(tf.float32, [None, 3])# 行数不固定,列数固定
    run(fetches, feed_dict = None, graph = None):训练模型时实时提供数据进行训练,用placeholder占位符和feed_dict结合使用
    

    举个栗子

    import tensorflow as tf
    import os
    # 忽略不必要的警告信息
    os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
    # 创建一张图包含Operation和Tensor,两个图之间互不干扰
    g = tf.Graph()
    with g.as_default():
        c = tf.constant(11.0)
        print(g)
        print(c.graph)
    # 实现一个加法运算,定义两个Tensor和一个Operation
    a = tf.constant(5.0)
    b = tf.constant(6.0)
    sum = tf.add(a, b)
    # 不是Operation不能运行,但是有重载机制,默认会给运算符重载成op类型(var + a可执行)
    # var = 2
    # 默认的图,相当于给程序分配内存
    graph = tf.get_default_graph()
    print(graph)
    # 一个会话只能运行一个图,可在会话中指定图运行
    # 上下文管理器with默认会释放资源
    with tf.Session(graph=graph) as sess:
        print(sum) # Tensor("Add:0", shape=(), dtype=float32),分别为op名字,张量形状,张量数据类型
        print(a.graph)
        print(sum.graph)
        print(sess.graph)
        print(sess.run(sum)) # run()执行图
    # 静态形状和动态形状
    # 对于静态形状而言,一旦张量形状固定,不能再次进行修改
    # 动态形状可新增一个,进行修改,但是元素数量要相同
    # 如果需要维度修改,必须用动态形状修改
    plt = tf.placeholder(tf.float32, [None, 2])
    print(plt)
    plt.set_shape([3, 2])
    print(plt)
    # plt.set_shape([4, 2]) # 不能修改
    plt_reshape = tf.reshape(plt, [1, 6])
    print(plt_reshape)
    with tf.Session() as sess:
        pass
    # 变量op
    # 1、变量op可持久化保存,普通张量op不能
    # 2、当定义一个变量op时,一定要在会话中取运行初始化
    # 3、name参数在tensorboard中使用显示,防止冲突
    a = tf.constant([1, 2, 3, 4, 5], name="a")
    var = tf.Variable(tf.random_normal([1, 2], mean=0, stddev=1.0))
    print(a, var)
    # 必须做一步显示的初始化op
    init_op = tf.global_variables_initializer()
    with tf.Session() as s:
        s.run(init_op)
        # 把程序的图结构写入事件,把指定的图写入事件中
        filewriter = tf.summary.FileWriter("./summary", graph=s.graph)
        print(s.run([a, var]))
    

    相关文章

      网友评论

          本文标题:TensorFlow自学第1篇——基础知识

          本文链接:https://www.haomeiwen.com/subject/zdgudqtx.html