美文网首页
机器学习:TensorFlow 简例

机器学习:TensorFlow 简例

作者: moon_light_ | 来源:发表于2020-04-08 00:34 被阅读0次
    # -*- coding:utf-8 -*-
    
    import tensorflow as tf
    
    
    
    '''
    出现以下 Warning
        Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX
    原因
        tensorflow 觉得你电脑 cpu 还行,支持 AVX(Advanced Vector Extensions),运算速度还可以提升,所以可以开启更好更快的模式
    解决方案
        Just disables the warning, doesn’t enable AVX/FMA
        import os
        os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
    '''
    import os
    os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
    
    
    
    '''
    主要 3 种类型的张量
        tf.constant
            常数, 值不可改变, 会在图中创建节点, 不依赖于其他节点, 可被其他节点依赖
            一般作为输入节点
        tf.Variable
            变量, 值可变, 会在图中创建节点, 可依赖其他节点, 也可被其他节点依赖, 需要初始化值
            一般用于可训练的参数, 比如 w 和 b, 运行过程中(包括训练前和训练后), 这些值一直存在
        tf.placeholder
            占位符, 值不可改变, 不会在图中创建节点, 不需要初始化, 可在运行时再赋值
            一般用于临时数据, 比如学习速度, 这个参数不需要在图中有节点表示, 而且训练结束后就不再使用, 又比如样本数据
            
    Graph 图
        有默认图,也可以自己创建图,张量都是在图里面创建的,不同的图可以有相同名字的张量
        
        使用默认图创建张量
            c = tf.Variable(tf.fill([2], 2.0))
    
        自己创建图,并创建张量
            g1 = tf.Graph()
            with g1.as_default():
                 v = tf.get_variable("v", initializer=tf.zeros_initializer()(shape=[3]))
    
        获取默认图
            g = tf.get_default_graph()
                 
    运行 Session
        通过会话 session 执行定义好的运算, session 拥有并管理 TensorFlow 运行时的所有资源
        
        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)              ## 输出计算结果
            print result.eval(session=sess)     ## 结果一样
            sess.close()
            
            或
            
            with tf.Session() as sess:
                print sess.run(result)
                print result.eval(session=sess)
        
        设置默认会话
            sess = tf.Session()
            with sess.as_default():
                print result.eval()
                
            或
    
            sess = tf.InteractiveSession()
            print result.eval()
            sess.close()
            
        session 使用默认图,也可以自己指定图
            sess = tf.Session(graph=g1)
            
    变量管理
        ## 下面两个定义等价
        ## 区别: Variable 的 name 是可选的, 而 get_variable 是必须指定的
        ##       get_variable 如果发现已有同名变量存在, 会报错, 而 Variable 不会
        v = tf.get_variable("v", shape=[1], initializer=tf.constant_initializer(1.0))
        v = tf.Variable(tf.constant(1.0, shape=[1]), name="v")
        
        ## 在名字为 foo 的空间内创建 v 变量, 如果该空间已存在 v 变量则报错
        with tf.variable_scope("foo"):
            v = tf.get_variable("v", shape=[1], initializer=tf.constant_initializer(1.0))
        
        ## 将 reuse 设为 True, 这样 get_variable 只获取已经创建过的变量, 如果变量不存在则报错
        with tf.variable_scope("foo", reuse=True):
            v1 = tf.get_variable("v", [1])
            print v == v1
                    
        ## 使用变量管理的一个好处是不用在函数间传递大量参数
        
    初始化变量
        需要初始化所有的 Variable
            tf.global_variables_initializer().run(session=sess)
        
        如果有指定默认 session 则
            tf.global_variables_initializer().run()
            
        旧函数
            tf.initialize_all_variables()
    
    '''
    
    
    
    sess = tf.Session()
    
    hello = tf.constant('Hello, TensorFlow!')
    print sess.run(hello)
    
    a = tf.constant(10)
    b = tf.constant(32)
    print sess.run(a + b)
    
    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_1:0", shape=(2,), dtype=float32)
    print sess.run(result)      ## 显示 [3. 5.]
    
    c = tf.Variable(tf.fill([2], 2.0))                      ## diff with tf.fill([1, 2], 2.0)
    d = tf.Variable(tf.fill([1,2], 2.0))
    tf.global_variables_initializer().run(session=sess)     ## need to init all var
    
    print sess.run(result - c)
    print sess.run(result - d)
    
    print a.graph is tf.get_default_graph()     ## 获取张量 a 所在的 graph, 并判断其是否默认图
    
    sess.close()
    
    
    g1 = tf.Graph()
    with g1.as_default():
         v = tf.get_variable("v", initializer=tf.zeros_initializer()(shape=[3]))
    
    g2 = tf.Graph()
    with g2.as_default():
         v = tf.get_variable("v", initializer=tf.ones_initializer()(shape=[3]))
    
    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"))
    
    with tf.Session(graph=g2) as sess:
         tf.global_variables_initializer().run()
         with tf.variable_scope("", reuse=True):
              print tf.get_variable("v").eval()         ## 似乎 with 语句自动把 sess 设为默认会话所以可以直接使用 eval()
    
    
    sess = tf.InteractiveSession()
    x = tf.Variable(tf.random_normal([5,3]))
    w = tf.Variable(tf.random_normal([3,2]))
    b = tf.Variable(tf.fill([1,2], 0.5))
    y = tf.matmul(x,w) + b
    tf.global_variables_initializer().run()
    print y.eval()
    sess.close()
    
    
    '''
    w = tf.Variable(tf.fill([2,3], 3.0))                    ## 产生全 3 的 2*3 矩阵作为变量
    w2 = tf.Variable(w.initialized_value()) 
    w3 = tf.Variable(w.initialized_value()*2)               ## 用其他变量来初始化新的变量    
    w5 = w2.assign(w3)                                      ## 将 w3 赋给 w2, 运行 w5 后才生效
    '''
    
            
    ''' 
    ## 指定计算设备
    g = tf.Graph()
    with g.device('/gpu:0'):
        result = a + b
    '''
    
    
    '''
    ## 通过集合管理不同资源如张量, 变量, 队列资源等
    tf.add_to_collection
    tf.get_collection       
    '''
    
    
    
    ############
    ## 神经网络
    ############
    from numpy.random import RandomState
            
    batch_size = 8      ## 训练数据 batch 的大小
            
    ## 定义权值
    ## w1 是输入层和隐藏层之间的权值
    ## w2 是隐藏层和输出层之间的权值
    ## 输入有 2 个特征
    ## 隐藏层有 3 个节点
    ## 输出层有 1 个节点
    w1 = tf.Variable(tf.random_normal([2,3], stddev=1)) 
    ## tf.random_normal([3,1], stddev=1) 产生 3*1 矩阵, 元素是均值为 0, 标准差为 1 的随机数
    ## 如果加上 seed=1 会导致每次的随机数一样    
    w2 = tf.Variable(tf.random_normal([3,1], stddev=1)) 
            
    ## 偏移值, 产生全为 0.5 的 1*3 矩阵作为变量
    b1  = tf.Variable(tf.fill([3], 0.5))
    b2  = tf.Variable(tf.fill([1], 0.5))
            
    ## 定义输入
    ## 由于输入是常量表示, 如果每轮迭代选取的数据都要通过常量来表示, 那么 TensorFlow 的计算图将会太大
    ## 为避免这个问题, TensorFlow 提供了 placeholder
    ## placeholder 相当于定义了一个位置, 这个位置中的数据在程序运行时再指定, 所以不会产生太多的图    
    x  = tf.placeholder(tf.float32, shape=(None, 2), name='x-input')
    ## 赋值的时候可以自动判断 shape
    y_ = tf.placeholder(tf.float32, shape=(None, 1), name='y-input')
        
    ## 定义神经网络前向传播, 假设激活函数是 f(x) = x
    a = tf.matmul(x, w1) + b1
    y = tf.matmul(a, w2) + b2
            
    ## 定义损失函数(交叉熵)
    cross_entropy = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(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]
    
    print "X=\n" + str(X)
    print "Y=\n" + str(Y)
            
    with tf.Session() as sess:
        tf.global_variables_initializer().run()     ## 一次性初始化所有变量
                
        print "\n"
        print sess.run(w1)      ## 训练之前神经网络的参数值
        print sess.run(w2)
        print sess.run(b1)
        print sess.run(b2)
        print "\n"
                
        STEPS = 5000    ## 迭代次数
        for i in range(STEPS):
            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})
    
                ## 隔一段时间计算所有数据的交叉熵输出, 理想情况是最终变成 0, 但有时似乎不行
                print("after " + str(i) + " training step(s), cross entropy on all data is " + str(total_cross_entropy))
                        
        print "\n"
        print sess.run(w1)      ## 训练之后神经网络的参数值
        print sess.run(w2)
        print sess.run(b1)
        print sess.run(b2)
        print "\n"
    
        result = sess.run(y, feed_dict={x: X})
        print result
        print result - Y
    
    



    相关文章

      网友评论

          本文标题:机器学习:TensorFlow 简例

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