机器学习笔记4-Tensorflow线性模型示例及TensorBoard的使用

2023-11-05

前言

在上一篇中,我简单介绍了一下Tensorflow以及在本机及阿里云的PAI平台上跑通第一个示例的步骤。在本篇中我将稍微讲解一下几个基本概念以及Tensorflow的基础语法。

本文代码都是基于API版本r1.4。本文中本地开发环境为Pycharm,在文中不再赘述。


名词解释

核心概念

和很多开发语言设计一样,Tensorflow提供了多个级别的客户端API,其中最底层叫Tensorflow Core,使用这一层API可以完全控制Tensorflow,但是使用难度上也相对较大。在Tensorflow Core之上创建的更高级别的API,对开发者更友好,更易于使用、学习起来也更简单。

Tensorflow中该数据的核心单位是张量(Tensor)张量就是将一组基础数值,组织成形态(Shape)为一个任意维度的数组,张量阶(Rank)就是维度的数量。概念还是挺拗口的,举个例子就非常明了了:

[1., 2., 3.] # Rank=1, Shape=[3]
[[1., 2., 3.], [4., 5., 6.]] # Rank=2; Shape=[2, 3]: 代表第一层数组里包含2个子数组,每个子数组里包含3个值
[[[1., 2., 3.]], [[7., 8., 9.]]] # Rank=3; Shape=[2, 1, 3] : 代表第一层数组里包含2个数组,每个子数组里又包含1个子数组,子数组里包含3个元素

Tensorflow其实就是针对张量的计算图,计算图中的每个节点(Node)之间是有向连接的,看起来像张量的流动图(即从输入开始,流过一系列的节点,最终输出结果),Tensorflow也由此得名。官方原话是:

What is a Data Flow Graph?
Data flow graphs describe mathematical computation with a directed graph of nodes & edges. Nodes typically implement mathematical operations, but can also represent endpoints to feed in data, push out results, or read/write persistent variables. Edges describe the input/output relationships between nodes. These data edges carry dynamically-sized multidimensional data arrays, or tensors. The flow of tensors through the graph is where TensorFlow gets its name. Nodes are assigned to computational devices and execute asynchronously and in parallel once all the tensors on their incoming edges becomes available.

tensors_flowing.gif


基础语法

Tensorflow Core编程,有点像画设计稿(构建流图)->按图施工(执行流图)这样的过程,执行流图必须使用tf.run()方法。计算图中的节点将接受0-N个张量作为输入值并产生一个输出值。在我的理解中,节点可以分为数值型运算型两种。


数值型

Constant

常量是一种没有输入,只有一个输出值的节点,常量在定义的时候就将其值存储在Tensorflow内部了,一旦定义则无法修改其值。

示例代码:

# 定义常量c1,并将其数值类型定义为tf.float32,默认值为1.0
c1 = tf.constant(1., dtype=tf.float32)
# 定义常量c2,并将其数值类型定义为tf.float32,默认值为2.0
c2 = tf.constant(2., dtype=tf.float32)

# 执行流图: c1 + c2
with tf.Session() as sess:
    print(sess.run(tf.add(c1, c2)))


Placeholder

占位符也是数值型节点的一种定义方式,占位符是一种Promise,就是承诺在执行tf.run()的时候一定会在参数feed_dict中提供其值。相比常量,占位符更像是一种参数,使用起来更灵活。

用占位符改写上面的示例代码如下:

# 定义占位值p1,并将其数值类型定义为tf.float32
p1 = tf.placeholder(tf.float32)
# 定义占位值p2,并将其数值类型定义为tf.float32
p2 = tf.placeholder(tf.float32)

# 执行流图: p1 + p2
with tf.Session() as sess:
    # 既然承诺过,因此在run的时候必须提供p1,p2的值,否则代码将报错
    print(sess.run(tf.add(p1, p2), {p1: 1., p2: 2.}))


Variable

比起占位符,变量就更灵活了,可以随时赋值,这样就可以将某些节点的输出值赋值到指定的变量中,以便后续节点使用。这种模式在机器学习中是非常必要的,因为机器学习就是一个调参的过程,在运行的时候就希望能随时改变某些值以达到预期。

变量在使用的时候需要注意的是,在执行tf.run()方法之前,必须将变量进行初始化,初始化语句是:

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

依旧是上述代码用变量改写:

# 定义变量v1,并将其数值类型定义为tf.float32,默认值为1.0
v1 = tf.Variable(1., tf.float32)
# 定义变量v2,并将其数值类型定义为tf.float32,默认值为1.0
v2 = tf.Variable(2., tf.float32)

with tf.Session() as sess:
    init = tf.global_variables_initializer()
    sess.run(init)
    print(sess.run(tf.add(v1, v2)))


运算型

其实上面的代码中已经用到了加法tf.add()方法,减法是tf.subtract(),乘法是tf.multiply(),除法是tf.divide()等等。所有的方法可以在官方API文档中找到:https://www.tensorflow.org/api_docs/python/tf,这里就不赘述了。


TensorBoard

这里再简单介绍下Tensorflow自带的非常强大的可视化工具TensorBoardTensorBoard完全可以单独写一篇博文,本文先抛砖引玉,主要是为了直观的展示上述代码产生的图。

最简单的TensorBoard的使用方法如下:

# 保存计算图
with tf.summary.FileWriter(logdir='logs', graph=tf.get_default_graph()) as writer:
    writer.flush()

执行上述代码之后,Tensorflow会将生成图所需的数据序列化到本地文件中,我指定了生成到当前同级目录logs中,生成成功之后,可以在PyCharm的控制台(使用快捷键ALT+F12可调出)中输入:

tensorboard --logdir=logs

等待几秒钟之后,控制台输出类似于如下内容则表示TensorBoard已经启动成功:

TensorBoard 0.4.0rc3 at http://localhost:6006 (Press CTRL+C to quit)

在本地浏览器(推荐使用Chrome)地址栏中,输入http://localhost:6006打开TensorBoard,大致效果如下:

tensorboard.jpg


复杂点的示例——线性模型

真正的机器学习过程中,我们当然是不知道变量的,我们真正的目的就是去习得这些变量,以达到模型能够尽可能准确预测样本的期望,也就是所谓的损失(loss)最小化。Tensorflow提供了优化器(optimizers)来做这个工作。最简单的优化器算法叫梯度下降,这是在线性模型中最常用的一种优化算法。优化器底层会调用Tensorflow Core中的tf.gradients方法来实现梯度下降

coordinate.jpg

如上图所示,假设现在已知4个蓝色的点(1,0),(2,-1),(3,-2),(4,-3),我们需要推导出代表红色直线的系数Wb(公式为y = Wx + b),当然这个例子很简单,用肉眼看一下就知道W=-1b=1,用Tensorflow实现的完整代码如下:

import tensorflow as tf

# y = Wx + b, 初始化的时候随便定义一个初始值
W = tf.Variable([.3], dtype=tf.float32)
b = tf.Variable([-.3], dtype=tf.float32)
# 输入值 x, 定义为占位符, 便于在学习过程中换成不同的值
x = tf.placeholder(tf.float32)
# 定义线性模型
linear_model = W*x + b
# 输出值 y, 定义为占位符, 便于在学习过程中换成不同的值
y = tf.placeholder(tf.float32)

# 损失loss,线性模型中以欧式距离来衡量损失值
loss = tf.reduce_sum(tf.square(linear_model - y))
# 定义优化器optimizer
optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)

# 4个蓝色点的训练数据,分解成x和y的数组为
x_train = [1, 2, 3, 4]
y_train = [0, -1, -2, -3]

# 初始化Session
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

# 循环1000次,训练模型
for i in range(1000):
  sess.run(train, {x: x_train, y: y_train})

# 评估准确率
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))

# 保存计算图
with tf.summary.FileWriter(logdir='logs_linear_regression', graph=tf.get_default_graph()) as writer:
    writer.flush()

我本机的输出结果为:

W: [-0.9999969] b: [ 0.99999082] loss: 5.69997e-11

W的值无限接近-1,b的值无限接近1,而loss无限接近0,这个就是我们设计的函数y=-x+1

TensorBoard中查看结果如图所示:

linear_regression.jpg

这个图就看起来就比较像这么回事了。


在阿里云PAI上运行

本系列教程我尽量在阿里云的PAI平台上也运行一次,虽然目前公测阶段还是有很多问题,但是也是让很多人对机器学习变得触手可及的一种非常好的方案。

上一篇中,我用web版的OSS管理工具上传了源代码文件,本用例将使用OSS Browser客户端上传和管理文件,下载地址在阿里云后台如下位置:

ossbrowser-downloading.jpg

下载客户端的同时,可以开通阿里云的Access Key(用来登录OSS Browser),开通位置如下:

access-key-management.jpg

开通之后,在管理界面看到如下内容:

access-key-management2.jpg

打开并解压缩刚才下载的OSS Browser,双击打开oss-browser.exe文件,使用刚才开通的Access Key登录:

oss-browser-login.jpg

我依旧在上一篇相同的目录oss://danielfu-oss-tf-test/tensorflowtest/下,创建了一个放summary文件夹,并上传了代码文件tensorflow-demo2.py

tensorflow-demos.jpg

在阿里云上使用Tensorflow需要将上述的demo示例代码进行少量的改造,格式基本也都是固定的,改造完之后的完整代码如下:

# 指定文件的编码格式,这个不加在PAI里运行会报错
#!/usr/bin/python
# -*-coding:utf-8 -*-

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

import sys
import argparse

import tensorflow as tf

# 定义FLAGS用来传递全局参数
FLAGS = None


def main(_):
    # y = Wx + b, 初始化的时候随便定义一个初始值
    W = tf.Variable([.3], dtype=tf.float32)
    b = tf.Variable([-.3], dtype=tf.float32)
    # 输入值 x, 定义为占位符, 便于在学习过程中换成不同的值
    x = tf.placeholder(tf.float32)
    # 定义线性模型
    linear_model = tf.multiply(W, x) + b
    # 输出值 y, 定义为占位符, 便于在学习过程中换成不同的值
    y = tf.placeholder(tf.float32)

    # 损失loss,线性模型中以欧式距离来衡量损失值
    loss = tf.reduce_sum(tf.square(linear_model - y))
    # 定义优化器optimizer
    optimizer = tf.train.GradientDescentOptimizer(0.01)
    train = optimizer.minimize(loss)

    # 4个蓝色点的训练数据,分解成x和y的数组为
    x_train = [1, 2, 3, 4]
    y_train = [0, -1, -2, -3]

    # 初始化Session
    init = tf.global_variables_initializer()
    with tf.Session() as sess:
        sess.run(init)

        # 循环1000次,训练模型
        for i in range(1000):
            sess.run(train, {x: x_train, y: y_train})

        # 评估准确率
        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))

        # 保存计算图
        with tf.summary.FileWriter(FLAGS.summaryDir + 'train', sess.graph) as writer:
            writer.flush()


# 在运行main程序的时候,将参数传入执行代码中
# 本例中就指定了summaryDir参数
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--summaryDir', type=str, default='',
                        help='Summaries log directory')
    FLAGS, unparsed = parser.parse_known_args()
    tf.app.run(main=main)

PAI中,下图中1的位置指定为tensorflow-demo2.py文件,2的位置指定为summary目录,然后点击3处的按钮:

execute.jpg

可能是PAI的BUG,该示例在执行的时候,输出结果永远是报错,但是在OSS中,summary文件也已经成功生成,而且如果点击查看Tensorblaord按钮,其实是可以启动TensorBoard的:

summaryfile.jpg

view-tensorboard.jpg

view-tensorboard2.jpg

3.jpg

如上图所示,可以成功运行PAI端的TensorBoard(URL是阿里云的,不是本机localhost的)。而且生成的图和本地运行生成的图也是一模一样的(废话)。


参考文档

官方文档:https://www.tensorflow.org/get_started/get_started



本文在我的博客园我的个人博客上同步发布,作者保留版权,转载请注明来源。

转载于:https://www.cnblogs.com/wushangjue/p/8287369.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

机器学习笔记4-Tensorflow线性模型示例及TensorBoard的使用 的相关文章

随机推荐

  • 通过反射获取一个对象的属性值三种方法比较

    这里写目录标题 为何要写这篇博客 数据准备 方法实践 总结 为何要写这篇博客 反射机制的用途非常多 比如获取方法 属性名和属性值等 甚至可以获取标签等标签属性 今天来比较几种获取实例化对象的属性值方法 数据准备 Builder FieldD
  • C++的cout高阶格式化操作

    敬告 当您的浏览器以非默认字体浏览本文时 段落格式可能会出现偏差 这篇文章主要讲解如何在C 中使用cout进行高级的格式化输出操作 包括数字的各种计数法 精度 输出 左或右对齐 大小写等等 通过本文 您可以完全脱离scanf printf
  • 攻防世界-WEB新手练习区教程(二)

    目录 攻防世界 WEB新手练习区教程 二 simple js xff referer weak auth command execution simple php 攻防世界 WEB新手练习区教程 二 simple js 进入场景 需要输入密
  • 记忆化搜索 Memorization Search

    记忆化搜索 Memorization Search 什么是记忆化搜索 记忆化搜索函数的三个特点 记忆化搜索 vs 动态规划 三种适用于DP的场景 三种不适用于DP的场景 Examples Leetcode 140 单词拆分 II Leetc
  • print.js 打印的网页单页内容,多出第二页空白页面

    问题如上图 解决过程 给table外嵌套的div设置了样式page break after也没有效果 最后索性给打印区域添加加边框 准备看看预览时空白页里有什么 结果后一页的空白页就这么没了 o 观察发现 加上边框后 table的宽度确实有
  • 【js】用正则实现一串数字用逗号隔开千分位

    此方法适用于正整数 负整数 浮点数 const formatNumberWithCommas number any gt 兼容一下传进来的number字段有可能是null undefined NaN 0的情况 当number为null un
  • .NET基础概念解释及主要体系结构

    一 NET概念详解 1 NET NET就是微软用来实现XML Web Services SOA 面向服务的体系结构service orientedarchitecture 和敏捷性的技术 NET是微软的新一代技术平台 为敏捷商务构建互联互通
  • python无web框架接口通信

    1 发送 def image to base64 image np image cv2 imencode jpg image np 1 tobytes base64 data base64 b64encode image base64 da
  • Java解析txt文件

    Java解析txt文件 package com wb test import java io BufferedReader import java io File import java io FileInputStream import
  • mysql和c#在类型转换的问题

    1 char 36 和string mysql在将char 36 类型的会转成System GUID 如果char 36 字段里存的不是guid 最好不要用char 36 改成char 37 这样的就没事了 在 net开放中 asp net
  • 李晓波

    一 大败局 第一部 这套书 真的写出来改革开放以来 中国比较出名的企业的生存与失败 这套书可以指导我十年吧 这几本书应该每两年翻阅一遍 1 秦池酒的成功与失败 中国标王 广告对普通人的影响 公关 品牌营销 2013 11 20 二 中国经济
  • cygwin环境编译 致命错误:stddef.h:can not found

    最近需要在linux下运行代码 为了省去搭建环境的时间 就使用了cygwin这一工具 但它在编译过程中 出现了can not found stddef h的问题 原因是库文件sttdef h没有找到 上网查了一下 有的博客写到需要对g 降级
  • 使用MongoDB命令连接远程服务器的MongoDB数据库

    使用MongoDB命令连接远程服务器的MongoDB数据库 MongoDB连接远程服务器的命令格式如下 mongo 远程主机ip或DNS MongoDB端口号 数据库名 u user p password MongoDB连接远程服务器的命令
  • LeetCode 每日一题 2023/9/11-2023/9/17

    记录了初步解题思路 以及本地实现代码 并不一定为最优 也希望大家能一起探讨 一起进步 目录 9 11 630 课程表 III 9 12 1462 课程表 IV 9 13 2596 检查骑士巡视方案 9 14 1222 可以攻击国王的皇后 9
  • AcWing167. 木棒(DFS+剪枝)

    输入样例 9 5 2 1 5 2 1 5 2 1 4 1 2 3 4 0 输出样例 6 5 解析 DFS 搜索顺序 根据木棒的长度从小到大枚举每根木棒 对于每根木棒 枚举可以由哪些木棍拼成 如果所有的木棍拼成了长度相等的多个木棒 说明找到了
  • PGSQL(学习与操作)

    PGSQL操作手册 1 Navicat连接数据库 192 168 31 0 密码 123456 port 5432 2 PGSQL数据库基础学习 1 创建数据库 CREATE DATABASE runoobdb 创建数据库 数据库名为run
  • ubuntu 18 OpenCV 4.5.3 cuda 源码编译

    目录 opencv453 build build sh opencv 4 5 3 opencv contrib 4 5 3 编译命令 创建 build sh 文件 pwd cmake D CMAKE BUILD TYPE RELEASE D
  • 基于蚁群算法求解运钞车路径规划问题(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 Matlab代码实现 4 参考文献 1 概述 车辆路径规划问题 Vehicle Rout
  • 【factoryio】虚拟工厂 的安装和使用

    文章目录 目录 文章目录 前言 一 factoryio是什么 二 factoryio的安装和使用 1 安装 2 激活 3 使用 三 factoryio和西门子PLC进行仿真连接 1 在博途软件中打开工程模板 2 进行仿真连接 3 点动实例
  • 机器学习笔记4-Tensorflow线性模型示例及TensorBoard的使用

    前言 在上一篇中 我简单介绍了一下Tensorflow以及在本机及阿里云的PAI平台上跑通第一个示例的步骤 在本篇中我将稍微讲解一下几个基本概念以及Tensorflow的基础语法 本文代码都是基于API版本r1 4 本文中本地开发环境为Py