tensorflow学习笔记(一)基础

一年前写了python学习系列,持续大约一个月。现在回想起来,当时确实是打下了一定的python基础,现在写代码都是在用python,而很少用c++了。

最近要做的研究方向与深度学习很相关,所以在学这方面的内容。之前学了一段时间tensorflow,但很散乱,断断续续的。前两天突然想到以前写的python学习系列,可以用写文章的方式来整理,于是就有了此系列文章。希望在暑假期间可以更完吧。

还是老规矩,因为是整理自己思路用的,所以有的部分简略,如有不理解的内容请留言。

准备环境

Anaconda 3
tensorflow 1.90
pycharm 2018.1.4

基本概念

张量

张量(tensor)是tensorflow(以下简称tf)中的一个最基本的数据结构。张量可以想象为一个n维的数组 1 1 。n称为张量的阶数。
下面是创建一个一阶张量的代码。

arr = tf.random_uniform([4])

代码的本意是产生一个长为4的、填充值为均匀分布随机数的一阶张量,但在输入执行后,会发现输出类似如下结果:

<tf.Tensor 'random_uniform_1:0' shape=(4,) dtype=float32>

而且不能通过通常意义上的变量获取方法来修改或者访问,是怎么回事?

会话

在tf中的基本单元都需要在“会话”中完成运行,而不是直接在python的环境下。
会话的创建和使用如下:

sess = tf.session()
sess.run(arr)

然后就会发现输出了张量arr的值。

占位符与变量

张量和一般的变量容易混淆,但实际上是完全不同的概念。可以这么认为,tf中的变量和一般程序的变量是一个含义,而张量是其变量应有的值。
就如在c++中声明了一个int变量a,然后赋值2,那么a就是变量,2就是张量(0阶张量),它充当的是一个字面量,是一个右值。所以变量是有值的。

而对于占位符来说,一般变量又相当于它的右值。通过占位符可以规定输入变量的格式、类型。但占位符本身是没有值的,只是起一个接口的作用。如下示例:

var1 = tf.Variable(arr)
sess.run(tf.global_variables_initializer())
var2 = np.random.rand(4,4)
x = tf.placeholder(tf.float32, shape=(4,4))
sess.run(x, feed_dict={x: var2})

x是一个占位符,var2是一个符合其形状的数组变量,因此在运行时将其“填充”到占位符上,从而运行出结果。
var1是一个变量,通过输入张量arr作为初始值,再运行初始化算子进行初始化。注意:这里的var1是不能通过feed_dict输入给x的,为什么?因为占位符所接受的变量是“外界变量”,不是在其会话体系内的;而tf内部的变量是定义在会话体系内的,不会被占位符识别。

流与计算图

流(flow)是对张量的一个形象描述,即张量在图中流动。这个图就是计算图 2 2

计算图的创建和使用如下:

g = tf.Graph()
with g.as_default():
    v=tf.get_variable('v',initializer=tf.zeros_initializer()(shape = [1]))

with tf.Session(graph=g) as sess:
    tf.global_variables_initializer().run()
    with tf.variable_scope('', reuse=True):
        print(sess.run(tf.get_variable('v')))

这段代码通过Graph()函数创建计算图g,然后在该计算图中定义了一个一维变量v。然后再在会话中使用该计算图,调用其变量。

注意到其中的variable_scope 和 get_variable是与我们之前提到的变量相关的方法,在变量繁多时,需要对变量进行管理。

变量的管理

get_variable()是一种创建变量的方法,与Variable()不同的是,它具有对变量名的管理能力。如下代码 3 3

w_1 = tf.Variable(3, name="w_1")
w_2 = tf.Variable(1, name="w_1")
print(w_1.name)
print(w_2.name)
w_1 = tf.get_variable(name="w_1",initializer=1)
w_2 = tf.get_variable(name="w_1",initializer=2)# 报错

使用get_variable()方法创建的变量,会在其所在变量空间中注册其变量名,使得这个变量名在该区域唯一。而Varible()是每一次调用都会创建一个新的变量,并且不保留其记录,不利于变量管理。

get_variable的参数如下:

参数说明举例
name唯一标识符‘var1’
shape变量的形状[2,3]
initializer初始化方法tf.random_normal_initializer

variable_scope就是之前提到的用来注册变量名的变量空间,它有些类似命名空间,但与 name_scope 又有所不同 4 4 ,在后面也会提到。它的最大的用处是实现变量共享。

使用方法如下:

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    with tf.variable_scope('scp1', reuse=True):
        print(sess.run(tf.get_variable('v1')))
    with tf.variable_scope('scp1', reuse=True):
        print(sess.run(tf.get_variable('v1')))

其中有一个参数reuse,用以标记变量是否共享,标为True后,相同变量域下同名变量可以共享数据。

可视化

事实上,在刚刚计算图的部分中,并没有涉及到操作数之间的运算。下面是一个有运算过程的例子。

g = tf.Graph()
with g.as_default():
    v1 = tf.get_variable('v', shape=[2, 3], initializer=tf.random_normal_initializer)

with tf.Session(graph=g) as sess:
    writer = tf.summary.FileWriter(r"tsbd",sess.graph)
    mr = tf.random_uniform([3, 2])
    tf.global_variables_initializer().run()
    with tf.variable_scope('', reuse=True):
        v = tf.get_variable('v')
        op_mat = tf.matmul(v, mr)
        print(sess.run(op_mat))
writer.close()

使用tensorboard可视化这个过程 5 5
这里写图片描述

实践

根据已学的内容来实现一个单层神经网络,不涉及训练过程,只是描述出其结构。

import tensorflow as tf
import numpy as np

hidden_nodes = 5
input_size = 3

g = tf.Graph()
with g.as_default():
    with tf.variable_scope('input_layer'):
        input_x = tf.placeholder(tf.float32, shape=[None, input_size])

    with tf.variable_scope('hidden_layer'):
        Wh = tf.get_variable('W', shape=[input_size, hidden_nodes])
        bh = tf.get_variable('b', shape=[hidden_nodes])
        hout = tf.nn.relu(tf.add(tf.matmul(input_x, Wh), bh))

    with tf.variable_scope('output_layer'):
        Wo = tf.get_variable('W', shape=[hidden_nodes, 1])
        bo = tf.get_variable('b', shape=[1])
        out = tf.nn.sigmoid(tf.add(tf.matmul(hout, Wo), bo))

    with tf.Session() as sess:
        writer = tf.summary.FileWriter(r"C:\tsbd", sess.graph)
        tf.global_variables_initializer().run()
        print(sess.run(out, feed_dict={input_x: np.random.random((3, 3))}))

    writer.close()

总结

本次学习了tensorflow的一些基本概念和数据结构。张量是tf中的基本数据结构,占位符是定义了结构而未填充数值的接口,变量有两种定义方式,其中一种方式可以进行变量共享,在变量域下能够对变量进行管理并且有利于可视化,要使用tf提供的运算作用于张量。
最后,利用这些基础知识实现了一个单层神经网络。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值