美文网首页我爱编程
TensorFlow实战-started

TensorFlow实战-started

作者: mov觉得高数好难 | 来源:发表于2017-11-09 15:12 被阅读0次

    Tensors,长量,数据在TensorFlow里面的基础但是就是tensor。长量的秩就是他的维数。这是一些tonsors的例子:

    3 # a rank 0 tensor; a scalar with shape []
    [1., 2., 3.] # a rank 1 tensor; a vector with shape [3]
    [[1., 2., 3.], [4., 5., 6.]] # a rank 2 tensor; a matrix with shape [2, 3]
    [[[1., 2., 3.]], [[7., 8., 9.]]] # a rank 3 tensor with shape [2, 1, 3]
    

    computational graph是一系列由节点图组成的TensorFlow操作。节点的一种类型是常量。下面我们建立两个浮点型的长量:

    In [3]: node1 = tf.constant(3.0, dtype=tf.float32)
       ...: node2 = tf.constant(4.0) # also tf.float32 implicitly
       ...: print(node1, node2)
       ...: 
    Tensor("Const:0", shape=(), dtype=float32) Tensor("Const_1:0", shape=(), dtype=float32)
    

    但是输出的值并不是3.0和4.0。其实,他在计算的时候会产生对应的值。session封装了TensorFlow runtime的控制和状态:

    In [8]: sess = tf.Session()
       ...: print(sess.run([node1, node2]))
       ...: 
    [3.0, 4.0]
    

    placeholder可以参数化的接受一个外部的输入值:

    a = tf.placeholder(tf.float32)
    b = tf.placeholder(tf.float32)
    adder_node = a + b  # + provides a shortcut for tf.add(a, b)
    
    In [10]: print(sess.run(adder_node, {a: 3, b: 4.5}))
        ...: print(sess.run(adder_node, {a: [1, 3], b: [2, 4]}))
        ...: 
    7.5
    [ 3.  7.]
    

    Variables(变量)使我们可以给一个图加入限制条件:

    W = tf.Variable([.3], dtype=tf.float32)
    b = tf.Variable([-.3], dtype=tf.float32)
    x = tf.placeholder(tf.float32)
    linear_model = W*x + b
    

    初始化变量前必须明确进行如下操作:

    init = tf.global_variables_initializer()
    sess.run(init)
    

    下面测试一下结果:

    In [13]: print(sess.run(linear_model, {x: [1, 2, 3, 4]}))
    [ 0.          0.30000001  0.60000002  0.90000004]
    

    我们使用placeholder来提供一个期望值,下面写一个损失函数。损失值度量了当前值和所提供值的差距。linear_model - y衡量了误差面积。

    In [14]: y = tf.placeholder(tf.float32)
        ...: squared_deltas = tf.square(linear_model - y)
        ...: loss = tf.reduce_sum(squared_deltas)
        ...: print(sess.run(loss, {x: [1, 2, 3, 4], y: [0, -1, -2, -3]}))
        ...: 
    23.66
    

    变量的值可以通过tf.Variable方法:

    In [15]: fixW = tf.assign(W, [-1.])
        ...: fixb = tf.assign(b, [1.])
        ...: sess.run([fixW, fixb])
        ...: print(sess.run(loss, {x: [1, 2, 3, 4], y: [0, -1, -2, -3]}))
        ...: 
    0.0
    

    tf.train API
    TensorFlow提供了优化器来缓慢的改变变量来最小化损失函数。最简单的例子就是梯度下降。他根据损失倒数的大小修改每一个变量。

    In [16]: optimizer = tf.train.GradientDescentOptimizer(0.01)
        ...: train = optimizer.minimize(loss)
        ...: 
    
    In [17]: sess.run(init) # reset values to incorrect defaults.
        ...: for i in range(1000):
        ...:   sess.run(train, {x: [1, 2, 3, 4], y: [0, -1, -2, -3]})
        ...: 
        ...: print(sess.run([W, b]))
        ...: 
    [array([-0.9999969], dtype=float32), array([ 0.99999082], dtype=float32)]
    

    一个完整的可训练线性回归模型如下:

    import tensorflow as tf
    
    # Model parameters
    W = tf.Variable([.3], dtype=tf.float32)
    b = tf.Variable([-.3], dtype=tf.float32)
    # Model input and output
    x = tf.placeholder(tf.float32)
    linear_model = W*x + b
    y = tf.placeholder(tf.float32)
    
    # loss
    loss = tf.reduce_sum(tf.square(linear_model - y)) # sum of the squares
    # optimizer
    optimizer = tf.train.GradientDescentOptimizer(0.01)
    train = optimizer.minimize(loss)
    
    # training data
    x_train = [1, 2, 3, 4]
    y_train = [0, -1, -2, -3]
    # training loop
    init = tf.global_variables_initializer()
    sess = tf.Session()
    sess.run(init) # reset values to wrong
    for i in range(1000):
      sess.run(train, {x: x_train, y: y_train})
    
    # evaluate training accuracy
    curr_W, curr_b, curr_loss = sess.run([W, b, loss], {x: x_train, y: y_train})
    print("W: %s b: %s loss: %s"%(curr_W, curr_b, curr_loss))
    

    结果可能不尽相同,因为初始化是用的伪随机数。这个稍加复杂的程序可以被TensorBoard以图的形式展现出来:


    tf.estimator
    这是一个高级别的TensorFlow库,用来简化如下的机器学习技术:
    -运行训练循环
    -运行评估循环
    -管理数据集
    注意tf.estimator是回归程序变得如何简单:
    # NumPy is often used to load, manipulate and preprocess data.
    import numpy as np
    import tensorflow as tf
    
    # Declare list of features. We only have one numeric feature. There are many
    # other types of columns that are more complicated and useful.
    feature_columns = [tf.feature_column.numeric_column("x", shape=[1])]
    
    # An estimator is the front end to invoke training (fitting) and evaluation
    # (inference). There are many predefined types like linear regression,
    # linear classification, and many neural network classifiers and regressors.
    # The following code provides an estimator that does linear regression.
    estimator = tf.estimator.LinearRegressor(feature_columns=feature_columns)
    
    # TensorFlow provides many helper methods to read and set up data sets.
    # Here we use two data sets: one for training and one for evaluation
    # We have to tell the function how many batches
    # of data (num_epochs) we want and how big each batch should be.
    x_train = np.array([1., 2., 3., 4.])
    y_train = np.array([0., -1., -2., -3.])
    x_eval = np.array([2., 5., 8., 1.])
    y_eval = np.array([-1.01, -4.1, -7, 0.])
    input_fn = tf.estimator.inputs.numpy_input_fn(
        {"x": x_train}, y_train, batch_size=4, num_epochs=None, shuffle=True)
    train_input_fn = tf.estimator.inputs.numpy_input_fn(
        {"x": x_train}, y_train, batch_size=4, num_epochs=1000, shuffle=False)
    eval_input_fn = tf.estimator.inputs.numpy_input_fn(
        {"x": x_eval}, y_eval, batch_size=4, num_epochs=1000, shuffle=False)
    
    # We can invoke 1000 training steps by invoking the  method and passing the
    # training data set.
    estimator.train(input_fn=input_fn, steps=1000)
    
    # Here we evaluate how well our model did.
    train_metrics = estimator.evaluate(input_fn=train_input_fn)
    eval_metrics = estimator.evaluate(input_fn=eval_input_fn)
    print("train metrics: %r"% train_metrics)
    print("eval metrics: %r"% eval_metrics)
    
    train metrics: {'loss': 7.2587181e-10, 'average_loss': 1.8146795e-10, 'global_step': 1000}
    eval metrics: {'loss': 0.010104778, 'average_loss': 0.0025261946, 'global_step': 1000}
    

    评估数据集损失更高,但是仍然接近于0。
    A custom model
    假设我们要创建一个TensorFlow里没有的自定义模型。我们将演示如何使用底层API创建一个和LR等效的模型。

    import numpy as np
    import tensorflow as tf
    
    # Declare list of features, we only have one real-valued feature
    def model_fn(features, labels, mode):
      # Build a linear model and predict values
      W = tf.get_variable("W", [1], dtype=tf.float64)
      b = tf.get_variable("b", [1], dtype=tf.float64)
      y = W*features['x'] + b
      # Loss sub-graph
      loss = tf.reduce_sum(tf.square(y - labels))
      # Training sub-graph
      global_step = tf.train.get_global_step()
      optimizer = tf.train.GradientDescentOptimizer(0.01)
      train = tf.group(optimizer.minimize(loss),
                       tf.assign_add(global_step, 1))
      # EstimatorSpec connects subgraphs we built to the
      # appropriate functionality.
      return tf.estimator.EstimatorSpec(
          mode=mode,
          predictions=y,
          loss=loss,
          train_op=train)
    
    estimator = tf.estimator.Estimator(model_fn=model_fn)
    # define our data sets
    x_train = np.array([1., 2., 3., 4.])
    y_train = np.array([0., -1., -2., -3.])
    x_eval = np.array([2., 5., 8., 1.])
    y_eval = np.array([-1.01, -4.1, -7., 0.])
    input_fn = tf.estimator.inputs.numpy_input_fn(
        {"x": x_train}, y_train, batch_size=4, num_epochs=None, shuffle=True)
    train_input_fn = tf.estimator.inputs.numpy_input_fn(
        {"x": x_train}, y_train, batch_size=4, num_epochs=1000, shuffle=False)
    eval_input_fn = tf.estimator.inputs.numpy_input_fn(
        {"x": x_eval}, y_eval, batch_size=4, num_epochs=1000, shuffle=False)
    
    # train
    estimator.train(input_fn=input_fn, steps=1000)
    # Here we evaluate how well our model did.
    train_metrics = estimator.evaluate(input_fn=train_input_fn)
    eval_metrics = estimator.evaluate(input_fn=eval_input_fn)
    print("train metrics: %r"% train_metrics)
    print("eval metrics: %r"% eval_metrics)
    

    结果如下:

    train metrics: {'loss': 1.7678869e-11, 'global_step': 1000}
    eval metrics: {'loss': 0.010100719, 'global_step': 1000}
    

    MNIST(Mixed National Institute of Standard and Technology database)是一个非常简单的机器视觉数据集。
    直接使用在线下载的命令失败:

    from tensorflow.examples.tutorials.mnist import input_data
    mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
    

    http://yann.lecun.com/exdb/mnist/自行下载数据集后放在py文件的同一个目录以后成功:

    from tensorflow.examples.tutorials.mnist import input_data
    mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
    
    print(mnist.train.images.shape, mnist.train.labels.shape)
    print(mnist.test.images.shape, mnist.test.labels.shape)
    print(mnist.validation.images.shape, mnist.validation.labels.shape)
    
    In [3]: runfile('D:/test/1/1.py', wdir='D:/test/1')
    Extracting MNIST_data/train-images-idx3-ubyte.gz
    Extracting MNIST_data/train-labels-idx1-ubyte.gz
    Extracting MNIST_data/t10k-images-idx3-ubyte.gz
    Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
    (55000, 784) (55000, 10)
    (10000, 784) (10000, 10)
    (5000, 784) (5000, 10)
    

    可以看出训练集测试机和验证机分别有55000,10000,5000个样本。同时每一个样本都有对应的标签信息
    10个种类是one-hot编码,Label是一个10维的向量,只有一个值维1,其余为0
    这里使用一个叫做Softmax Regression的算法训练手写数字识别的分类模型。原理很简答,将可以判定为某类的特征加权相加。我们可以将这些特征写成如下公式:i代表第i类,j代表一张图片第j个像素。bi就是bias,顾名思义就是数据本身的倾向,比如大部分数字都是0,则0
    的bias就会很大:



    接下来计算softmax,简单说就是计算exp函数,然后标准化(让所有类别输出的概率值和为1):



    其中判定为第i类的概率就可以:

    如果将整个计算过程可视化:

    接着,变成公式,最后将元素相乘变成矩阵乘法,结果如图所示:


    接下来使用TensorFlow实现一个Soft Regression。首先载入TensorFlow库,并创建一个新的InteractiveSession,之后的运算默认跑在整个session里,不同的session之间的数据和运算都是相互独立的。None代表不限制条数的输入:

    import tensorflow as tf
    sess = tf.InteractiveSession()
    x = tf.placeholder(tf.float32, [None, 784])
    

    下面将weights和biases全部初始化为0:

    W = tf.Variable(tf.zeros([784, 10]))
    b = tf.Variable(tf.zeros([10]))
    

    然后构建SR算法(y=softmax(Wx+b)):

    y = tf.nn.softmax(tf.matmul(x, W) + b)
    

    Softmax是tf.nn下面的一个函数,而tf.nn则包含了大量神经网络组件。tf.matmul是TensorFlow中的矩阵乘法函数。
    这里使用cross-entropy作为loss function,定义如下:y是预测的概率分布,y'是真实的概率分布(label的one-shot编码),他通常可以用来判断模型对真实概率分布估计的准确程度:



    在TensorFlow中定义如下:

    y_ = tf.placeholder(tf.float32, [None, 10])
    cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))
    

    tf.reduce_sum是求和,tf.reduce_mean则是用来每个batch数据结果求平均值
    我们采用常见的随机梯度下降(SGD)。定义好算好以后,TensorFlow就可以根据我们定义的整个计算图自动求导,并根据反向传播算法进行训练,在每一轮迭代时更新参数来减小loss。我们直接调用tf.train.GradientDesentOptimizer,并设置学习速率为0.5,优化目标设定为cross-entropy,得到进行训练的操作train_step:

    train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
    

    下一步就是使用TensorFlow的全局参数初始化器并直接执行它的run方法:

    tf.global_variables_initializer().run()
    

    这里每一次都随机从训练集中抽取100条样本构成一个mini-batch,并feed给placeholder,然后调用train_step对这些样本进行训练:

    for _ in range(1000):
      batch_xs, batch_ys = mnist.train.next_batch(100)
      sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})
    

    下面进行验证。tf.argmax是从tensor中寻找最大值的序号:

    correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
    

    然后用tf.cast将bool值全部换成float32,再求平均值:

    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    

    打印准确率:

    print(accuracy.eval({x: mnist.test.images, y_: mnist.test.labels}))
    
    In [6]: runfile('D:/test/1/1.py', wdir='D:/test/1')
    Extracting MNIST_data/train-images-idx3-ubyte.gz
    Extracting MNIST_data/train-labels-idx1-ubyte.gz
    Extracting MNIST_data/t10k-images-idx3-ubyte.gz
    Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
    0.9174
    

    通过上面简单的例子,我们使用TensorFlow实现了一个简单的机器学习算法Softmax Regression,这可以算做一个没有隐含层的最浅的神经网络,分为4个部分:
    (1)定义算法公式,也就是神经网络forward时的计算;
    (2)定义loss,选定优化器,并指定优化器优化loss;
    (3)迭代地对数据进行训练;
    (4)在测试集或者验证集对准确率进行评测

    相关文章

      网友评论

        本文标题:TensorFlow实战-started

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