TensorFlow零基础入门教程(一)

TensorFlow入门(一)

da9d6629fbaad81c1b2bc35526990404.jpg


Github主页:https://linxid.github.io/
知乎:https://www.zhihu.com/people/dong-wen-hui-90/activities
CSDN:https://blog.csdn.net/linxid

1.计算图

首先解释什么是计算图,了解TensorFlow的计算模型.

image.png

和我们常见的程序计算框架不同,并不是赋值,或者计算后,TensorFlow立马完成这些操作,而是将这些操作,赋予在一个图中,这个图可以简单地认为是我们常见的流程图,只不过更加的详细,包括每一步操作(op)和变量的名字.

因为神经网络的运行,需要很大的计算量,如果循环往复的赋值计算,将会带来很大的麻烦,所以TensorFlow采用计算图模型,包括其他很多框架都是采用同样的模型.

比如说,我们建立一个神经网络,那我们首先,定义好变量(参数),然后每一步计算,包括输出.当定以好之后,我们建立一个会话(Session),在这个会话中运行图模型.

# tf.get_default_graph()获取默认的计算图
# a.graph可以查看张量所属的计算图
print(a.graph is tf.get_default_graph())

# 建立两个不同的计算图,然后分别输出两个变量
g1 = tf.Graph()
with g1.as_default():
    v = tf.get_variable(
        'v', initializer=tf.zeros([2,3],tf.float32)
    )

g2 = tf.Graph()
with g2.as_default():
    v = tf.get_variable(
        'v',initializer=tf.ones([2,3],tf.float32)
    )

2. TensorFlow中的数据类型

2.1 tf.constant():常量

TensorFlow中的张量模型,也就是我们所说的Tensor的意思.

在TensorFlow中完成的是一步赋值过程,将定义的一个张量保存在变量a或b中.a和b保存的不是张量的值,而是这些数字的运算过程.

注意:

  • 1.张量三属性:名字,维度,类型(一般为tf.float32);
  • 2.运算时,维度和类型要保持一直;
  • 3.名字给出了张量的唯一标识符,同事给出变量是如何计算的;
  • 4.张量的计算和普通计算是不同的,保存的不是数值,而是计算过程!!!!

张量的作用:

  • 1.对中间计算结果的引用,增加代码的可读性
  • 2.计算图构造完成后,用来获得计算结果
import tensorflow as tf
a = tf.constant([1.0, 2.0], name='a')
b = tf.constant([2.0, 3.0], name='b')
# 不管是张量直接相加,还是tf.add二者的作用是一致的
result1 = a + b
result2 = tf.add(a,b,name='add')
print(result1)
print(result2)

2.2 tf.Variable()

专门用来,保存和更新神经网络中的参数,所以我们在建立神经网络模型参数的时候,使用tf.Variable()类型.

常用的常数生成函数:
  • tf.zeros()
  • tf.ones()
  • tf.fill()
常用的随机数生成函数:
  • tf.random_normal(维度,标准差,类型)
  • tf.truncated_normal()
  • tf.random_uniform()
w1 = tf.Variable(tf.random_normal([2,3], stddev=1, seed=1))
# 与上类似,维度([3,1])
w2 = tf.Variable(tf.random_normal([3,1], stddev=1, seed=1))

2.3 tf.placeholder()

在前面定义张量时,我们使用的是tf.constant().我们都知道神经网络的训练需要上千上万,甚至几百万的循环迭代,而每次循环迭代,每次生成一个常量,TensorFlow就会在计算图中增加一个节点,最后就会使得,图异常复杂.所以TensorFlow引入tf.placeholder机制.

tf.placeholder相当于提前为变量,定义,开拓了一个位置,这个位置的数据在程序运行时被指定.也就是在计算图中,我们只有一个位置,这个位置的值会不断改变,这样就避免了重复生成.

三个属性:

  • 类型
  • 维度
  • 名字

运行时,使用feed_dict来定义输入.

x = tf.placeholder(tf.float32, shape=(None, 2), name='x-input')
y_ = tf.placeholder(tf.float32, shape=(None, 1), name='y-input')

3.会话(Session)

前面我们已经提到了计算图模型,在TensorFlow中,我们使用会话(Session)来执行定义好的计算.会话拥有并管理TensorFlow中的所有资源,运行结束后,需要及时回收资源.

3.1 模式一:

调用会话生成函数,然后关闭会话函数.

sess = tf.Session()
with sess.as_default():
    print(result2.eval())
    print('\n')

# 这两个有同样的功能
print(sess.run(result2))
print('\n')
print(result2.eval(session=sess))
print('\n')

3.2 模式二:

利用上下文管理器,来使用会话,自动释放资源.


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(sess.run(tf.get_variable('v')))

print('\n')

3.3 模式三:

交互式会话模式,尤其是在Ipython(Jupyter Notebook),这种交互式的环境中,使用非常方便.

# 使用交互式会话模式
sess1 = tf.InteractiveSession()
print(sess1.run(result2))
sess1.close()

4.TensorFlow实现神经网络

# 导入tensorflow库
import  tensorflow as tf
# 导入Numpy工具包,生成一个模拟数据集
from numpy.random import  RandomState

# 采用Mini-batch训练方法,速度快,准确率高
batch_size = 8

# 首先定义两个权重(变量),满足正太随机分布,维度([2,3]),标准差是1, seed使用随机种子,保证每次运行的结果一样
w1 = tf.Variable(tf.random_normal([2,3], stddev=1, seed=1))
# 与上类似,维度([3,1])
w2 = tf.Variable(tf.random_normal([3,1], stddev=1, seed=1))

# 设置x变量,使用placeholder,为变量提供一个位置.若使用variable等格式,每次赋值,都会在计算图中
# 增加一个结点,训练几百万轮,会使得计算图非常复杂,所以引入placeholder机制.
# 维度([None,2]),
x = tf.placeholder(tf.float32, shape=(None, 2), name='x-input')
y_ = tf.placeholder(tf.float32, shape=(None, 1), name='y-input')

# matmul实现矩阵相乘,这里tensorflow使用计算图方式,与numpy的矩阵相乘是不一样的.
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)

# 通过极力函数sigmoid(),实现非线性化
y = tf.sigmoid(y)

# 定义损失函数,此处使用交叉熵,以后讨论,用来表征预测数据和真实数据的误差
cross_entropy = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0))
                                + (1 - y) * tf.log(tf.clip_by_value(1-y, 1e-10, 1.0)))

# 定义反向传播算法,来优化NN中的参数,此处使用AdamOptimizer
# 学习率:0.001,优化目标:cross_entropy
train_step = tf.train.AdamOptimizer(0.001).minimize(cross_entropy)

# 通过随机数生成模拟数据集
rdm = RandomState(1)

# 训练数据X:数据集大小[128,2]
# 128个样例,2个属性
dataSet_size = 128
X = rdm.rand(dataSet_size, 2)

# 标签数据Y:使用布尔变量,如果x1 + x2 < 1则认为是正样本,也就是为1
# 否则认为是负样本,也就是0.
Y = [[int(x1 + x2 < 1)] for (x1,x2) in X]

# 创建一个回话,来运行计算图
with tf.Session() as sess:
    # 对所有变量进行初始化
    init_op = tf.global_variables_initializer()
    sess.run(init_op)

    # 输出w1和w2值,在训练之前
    print(sess.run(w1))
    print(sess.run(w2))

    # 设置迭代次数为5000次
    Steps = 5000
    # 循环
    for i in range(Steps):
        # 选取batch_size个样本,取余
        start = (i*batch_size)%dataSet_size
        # 避免超出训练集的范围
        end = min(start + batch_size, dataSet_size)

        # 对选取的样本进行训练,因为是placeholder,使用字典对其赋值,并迭代更新参数
        sess.run(train_step, feed_dict={x : X[start:end], y_ : Y[start:end]})

        # 当迭代次数为100的倍数的时候,输出所有数据上的交叉熵
        if i%100 == 0:
            total_cross_entropy = sess.run(cross_entropy, feed_dict={x:X, y_ : Y})
            print("After %d training step(s), cross entropy on all data is %g" % (i, total_cross_entropy))

    # 输出训练过后的参数(权重)
    print(sess.run(w1))
    print(sess.run(w2))
阅读更多

扫码向博主提问

linxid

学无止境
去开通我的Chat快问
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页