cs224n_Lecture7_TensorFlow框架及线性回归实现

Introduction to TensorFlow

深度学习框架简介

为什么要用成熟的框架,而不是从头写一个:

  • 这些深度学习框架有助于扩展机器学习代码
  • 可以自动计算梯度(Gradients)!(使得我们可以把重点放在高层次的数学上)
  • 标准化机器学习应用,方便共享交流
  • 多种算法、理念、抽象、编程语言等的融合
  • 提供GPU并行运算的接口

TF是什么?

Tenorflow是谷歌开发的一个使用流式图进行数值计算的开源软件库。

It’s just a deep learning framework, an open source software library for numerical computation using flow graphs from Google.

TF的工作原理和基本范例

  • 最核心的思想

    将数值计算表示为图的形式(express a numeric computation as a graph)

    • 图的节点是某种运算,支持任意数量的输入和输出
    • 图的边是tensor(张量,n维数组),在节点之间流动
  • 拥有一个隐藏层的神经网络的例子

    其在TensorFlow中的计算图如下:

h = R e L U ( W x + b ) h=ReLU(Wx+b) h=ReLU(Wx+b)

  • 其中ReLU是一个表示修正线性单元的激活函数,我们在线性输入上加入一些非线性函数,能够赋予神经网络一定的表达能力。ReLU表示在你的输入和0之间取最大值,即max(input,0)。
  • x x x只是一个placeholder(占位符),只在执行的时候填充输入,编程的时候指定大小即可。

构建运算图

要描述这样的graph flow,只需要编写代码:

import tensorflow as tf

# 定义一个变量b初始化为0 大小为100维; w是一个服从[-1,1]的均匀分布
b = tf.Varable(tf.Zeros((100,))) 
w = tf.Varable(tf.random_uniform((784,100),-1,1))

# x是一个占位符,并没有被初始化为任何值,编程时只需要指定它:仅接收32位浮点数的数据类型,接收一个(100,784)的shape
x = tf.placeholder(tf.float32,(100,784))

# actually build our flow graph
h = tf.nn.relu(tf.matmul(x,w) +b)

这段代码只是构建了运算图,连输入都没有,自然无法马上获取h的值。上述代码并没有显式地声明节点和边,TensorFlow根据数学表达式自动构造了运算图。

如何得到输出(Getting output)

到目前为止,我们只定义了一张图,如何执行它呢?我们可以通过session将这张图部署到某个执行环境(CPU、GPU、Google的TensorProcessingUnit……)上去。session就是支持图中所有操作的执行的硬件环境。

sess.run(fetches,feeds)

  • 建立一个会话对象(session object)

  • 调用两个参数fetches和feeds

    • fetches:图结点列表,返回这些结点的输出结果
    • feeds:将图结点映射至具体值的字典(Dictionary)
    # 创建一个会话对象
    sess = tf.Session()
    # sess.run 初始化所有变量
    sess.run(tf.initialize_all_variables())
    sess.run(h,{x: np.random.random(100,784)})
    

如何训练模型

  1. 对于优化过程而言,如何定义损失?

    # prediction是在网络结束时的预测值,是对神经网络顶层进行softmax函数计算,输出一个概率向量,这是一个回归过程
    prediction = tf.nn.softmax(...)
    # label是我们真实标记的占位符,我们的模型根据它来训练
    label = tf.placeholder(tf.float32,[100,10])
    
    # 创建交叉熵结点
    cross_entropy = -tf.reduce_sum(label * tf.log(prediction), axis=1)
    
  2. 如何计算梯度

    # 创建一个优化器
    train_step = tf.teain.GradientDescentOptimizer(0.5).minimize(cross_entropy)
    

    Tensorflow中有一个通用的抽象类叫优化器(optimizer),在这个类中的每一个子类都是针对特定学习算法的优化器。

    train_step这一步骤实际上在模型上对所有的变量进行梯度的计算,因为.minimize函数在这里做了两件事:

    • 第一件是计算参数的梯度,本案例中参数为交叉熵,它和我们图中定义的所有变量相关。然后它会对这些变量根据梯度进行更新。
      • Q:我们是如何计算梯度的呢?
      • A:TensorFlow的工作方式是:每一个图节点都有一个附加的梯度操作,都有相对于输入预先构建的输出梯度。因此,当我们在计算交叉熵相对于所有参数的梯度时,通过图使用链式法则利用反向传播计算是非常简单的。

创建一个迭代的学习计划(Building training schedule)

# 建立一个字典,将值传给我们之前定义好的两个占位符,x和label是图中的结点,即字典中的关键字是图中的结点,对应的项是Numpy数据
for i in range(1000):
    batch_x, batch_label = data.next_batch()
    sess.run(train_step,feed_dict={x: batch_x,
                                label: batch_label })

变量共享

Q:有时候我们想要生成一张图的多个实例,或者在多机多个GPU上训练同一个模型,就会带来同一个变量在不同位置出现。如何在不同位置共享同一个变量呢?

A:

  • 一种朴素的想法是:

    在代码顶端创建这个变量的字典。把一些字符串的字典放到它们所代表的变量中。

variable_dict = {
    "weights":tf.Variable(tf.random_normal([782,100])),
    "biases":tf.Variable(tf.zeros([100]),name="biases")
}

这种做法的缺点在于:破坏了封装性!(No good for encapsulation!)

  • 更成熟一些的做法:

    • Variable_scope()提供了一个简单的命名空间方案来避免冲突

    • Get_variable() 如果一个具备特定名字的向量不存在的话,该函数会为你创建一个变量

      ​ 否则,如果发现它存在,将访问该变量

总结

TF的用法总结如下:

  1. 创建图
    a 前向传播/预测
    b 优化操作
  2. 初始化session
  3. 在session中执行

从线性回归来熟悉TensorFlow

现场vim敲代码环节[撒花?]

首先初始程序框架如下,我们需要完成linear_regression()函数来拟合我们的数据分布

# linear regression
# Author: Nishith Khandwala (nishith@stanford.edu)
# Adapted from https://github.com/hans/ipython-notebooks/

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import numpy as np
import tensorflow as tf
import matplotlib
matplotlib.use('TKAgg')
from matplotlib import pyplot as plt

'''
Good ole linear regression: find the best linear fit to our data
'''

def generate_dataset():
    # data is generated by y = 2x + e
    # where 'e' is sampled from a normal distribution
    x_batch = np.linspace(-1, 1, 101)
    y_batch = 2 * x_batch + np.random.randn(*x_batch.shape) * 0.3
    return x_batch, y_batch
    
def linear_regression():
    return NotImplementedError

def run():
    pass
    x_batch, y_batch = generate_dataset()

    plt.figure(1)
    plt.scatter(x_batch, y_batch)
    plt.plot(x_batch, y_pred_batch)
    plt.savefig('plot.png')
        
if __name__ == '__main__':
    run()

小哥几乎是敲一句解释一句,把之前对tensorflow编程流程的讲解很好地融入了进来,代码的完成版如下:

# linear regression
# Author: Nishith Khandwala (nishith@stanford.edu)
# Adapted from https://github.com/hans/ipython-notebooks/

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import numpy as np
import tensorflow as tf
import matplotlib
matplotlib.use('TKAgg')
from matplotlib import pyplot as plt

'''
Good ole linear regression: find the best linear fit to our data
'''

def generate_dataset():
    # data is generated by y = 2x + e
    # where epsilon 'e' is sampled from a normal distribution :e是从正态分布采样得到的
    x_batch = np.linspace(-1, 1, 101)
    y_batch = 2 * x_batch + np.random.randn(*x_batch.shape) * 0.3
    return x_batch, y_batch

# 我们将用图来实现线性回归    
def linear_regression():
    # 首先定义流式图 flow graph -> 第一步创建占位符
    # 我们创建x类型为浮点数,希望形状更通用,设置shape为(None),意味着你可以动态改变每一批次数据的数量,然后把它们送进网络中
    
    x = tf.placeholder(tf.float32, shape=(None,), name="x")
    y = tf.placeholder(tf.float32, shape=(None,), name="y")

    # 定义变量作用域
    with tf.variable_scope("lreg") as scope:
        w = tf.Variable(np.random.normal(),name="w")
        y_pred = tf.multiply(w,x)

        loss = tf.reduce_mean(tf.square(y_pred - y))    
    return x, y, y_pred, loss

def run():
    x_batch, y_batch = generate_dataset()

    x,y,y_pred, loss=linear_regression()
    #优化器 定义学习率为0.1,最小化模型的损失
    optimizer = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

    init = tf.global_variables_initializer()
    with tf.Session() as session:
        session.run(init)

        feed_dict = {x: x_batch,y: y_batch}
        for _ in range(30):
            loss_val, _= session.run([loss,optimizer], feed_dict)
            print('loss_val:',loss_val.mean())

        y_pred_batch = session.run(y_pred,{x: x_batch})

    plt.figure(1)
    plt.scatter(x_batch, y_batch)
    plt.plot(x_batch, y_pred_batch)
    plt.savefig('plot.png')
    plt.show()
    
if __name__ == '__main__':
    run()

实验运行结果:

在terminal打印loss值:

loss_val: 0.6620599
loss_val: 0.587803
loss_val: 0.5233017

loss_val: 0.10778806
loss_val: 0.10634918

绘制出图形如下:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值