机器学习:TensorFlow 简例

2020-04-08  本文已影响0人  moon_light_
# -*- 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



上一篇下一篇

猜你喜欢

热点阅读