tensorflow

1. tensor是tensorflow基础的一个概念——张量。

Tensorflow用到了数据流图,数据流图包括数据(Data)、流(Flow)、图(Graph)。Tensorflow里的数据用到的都是tensor,所以谷歌起名为tensorflow。这里写图片描述

Tensor的属性

1.数据类型dtype d是data的首字母,type是类型的意思。tensor里每一个元素的数据类型是一样的。类似于Numpy中ndarray.dtype,tensorflow里的数据类型可以有很多种,比方说tf.float32就是32位的浮点数,tf.int8就是8位的整型,tf.unit8就是8位的无符号整型,tf.string为字符串,tf.bool等等。
2.形状Shape 类似于Numpy中ndarray.shape,比方说一个2行3列的二维矩阵,他的形状就是2行3列。
3.其他属性
device是tensor在哪个设备上被计算出来的,graph是tensor所属的图,name是tensor的名字,op是operation的缩写是产生这个tensor的操作运算,对应图上的结点,这些结点接收一些tensor作为输入并输出一些tensor。还有等等属性,可以查阅官网。
tensor和Numpy有很多共同的性质,tensorflow的作者应该参考了numpy(个人臆测)

####几种Tensor
1.Constant(常量) 是值不能改变的一种tensor,定义在tf.constant这个类里。
这里写图片描述

constant中有几个属性:
value就是constant的数值,我们可以给他赋值,比方说0维的scalar,1维的Vector,2维的matrix或者是3维的张量。
dtype、shape、name刚都有写过。
verify_shape是布尔值,用于验证值的形状。
除了value外都不一定要指定,可以有默认的值但是必须要有一个value。

2.Variable(变量) 是值可以改变的一种tensor,定义在tf.Variable这个类中。构造函数如下图
这里写图片描述

3.Placeholder(占位符) 先占住一个固定的位置,之后在往里面添加值的一种Tensor。定义在tf.placeholder中。这里只有三个属性如下图。并没有value,因为赋值后就不是占位符了。只有dtype,shape,name三个属性。赋值的机制用到了python中字典,即feed_dict。
这里写图片描述

x = tf.placeholder(tf.float32, shape=(1024, 1024))
y = tf.matmul(x, x)
with tf.Session() as sess:
    rand_array = np.random.rand(1024, 1024)
    print(sess.run(y, feed_dict={x: rand_array}))

比如说官网的例子定义了x占位符,数值类型是tf.float32,形状是1024*1024的二维矩阵。在用会话正式运行图的时候用feed_dict,首先给一个键后加真实的值。

4.SparseTensor(稀疏张量) 是一种稀疏的Tensor,类似线代中稀疏矩阵。定义时只需要定义非0的数,其他的数会自动填充。
这里写图片描述

2. padding

The TensorFlow Convolution example gives an overview about the difference between SAME and VALID :

  • For the SAME padding, the output height and width are computed as:

    • out_height = ceil(float(in_height) / float(strides[1]))
    • out_width = ceil(float(in_width) / float(strides[2]))
  • For the VALID padding, the output height and width are computed as:

    • out_height = ceil(float(in_height - filter_height + 1) / float(strides[1]))
    • out_width = ceil(float(in_width - filter_width + 1) / float(strides[2]))

3. tf.get_variable()和tf.Variable()的区别

tf.Variable(initial_value, trainable=True, collections=None, validate_shape=True, name=None)
##initial_value为变量的初始值
tf.get_variable(name,  shape, initializer) #name就是变量的名称,shape是变量的维度,initializer是变量初始化的方式

initializer初始化的方式有以下几种:

tf.constant_initializer :常量初始化函数

tf.random_normal_initializer:正态分布

tf.truncated_normal_initializer:截取的正态分布

tf.random_uniform_initializer:均匀分布

tf.zeros_initializer:全部是0

tf.ones_initializer:全是1

tf.uniform_unit_scaling_initializer:满足均匀分布,但不影响输出数量级的随机值

tf.contrib.layers.xavier_initializer()

4. tf.nn,tf.layers, tf.contrib模块

我们在使用tensorflow时,会发现tf.nntf.layerstf.contrib模块有很多功能是重复的,尤其是卷积操作,在使用的时候,我们可以根据需要现在不同的模块。但有些时候可以一起混用。 下面是对三个模块的简述:
(1)tf.nn :提供神经网络相关操作的支持,包括卷积操作(conv)、池化操作(pooling)、归一化、loss、分类操作、embedding、RNN、Evaluation。
(2)tf.layers:主要提供的高层的神经网络,主要和卷积相关的,个人感觉是对tf.nn的进一步封装,tf.nn会更底层一些。
(3)tf.contrib:tf.contrib.layers提供够将计算图中的 网络层、正则化、摘要操作、是构建计算图的高级操作,但是tf.contrib包含不稳定和实验代码,有可能以后API会改变。以上三个模块的封装程度是逐个递进的。

tf.nn.conv2d(input, 
filter,  #4D
strides,  #4D
padding, 
use_cudnn_on_gpu=None, 
data_format=None, 
name=None)
tf.layers.conv2d(inputs, 
filters, #1D
kernel_size,  #2D
strides=(1,1),
padding='valid', 
data_format='channels_last',
dilation_rate=(1,1), 
activation=None, 
use_bias=True, 
kernel_initializer=None, 
bias_initializer=init_ops.zeros_initializer(), 
kernel_regularizer=None, 
bias_regularizer=None, 
activity_regularizer=None, 
trainable=True, 
name=None, reuse=None)

对于卷积来说,作用是一样的。tf.layers.conv2d 使用tf.nn.convolution作为后端。

5. CPU & GPU

在实现上, TensorFlow 将图形定义转换成分布式执行的操作, 以充分利用可用的计算资源(如 CPU 或 GPU). 一般你不需要显式指定使用 CPU 还是 GPU, TensorFlow 能自动检测. 如果检测到 GPU, TensorFlow 会尽可能地利用找到的第一个 GPU 来执行操作.

如果机器上有超过一个可用的 GPU, 除第一个外的其它 GPU 默认是不参与计算的. 为了让 TensorFlow 使用这些 GPU, 你必须将 op 明确指派给它们执行. with…Device 语句用来指派特定的 CPU 或 GPU 执行操作:

with tf.Session() as sess:
  with tf.device("/gpu:1"):
    matrix1 = tf.constant([[3., 3.]])
    matrix2 = tf.constant([[2.],[2.]])
    product = tf.matmul(matrix1, matrix2)

设备用字符串进行标识. 目前支持的设备包括:

  • “/cpu:0”: 机器的 CPU.
  • “/gpu:0”: 机器的第一个 GPU, 如果有的话.
  • “/gpu:1”: 机器的第二个 GPU, 以此类推.

6. tf.InteractiveSession()

为了便于使用诸如 IPython 之类的 Python 交互环境, 可以使用 InteractiveSession 代替 Session 类, 使用 Tensor.eval()Operation.run()方法代替Session.run(). 这样可以避免使用一个变量来持有会话.

  • tf.InteractiveSession():它能让你在运行图的时候,插入一些计算图,这些计算图是由某些操作(operations)构成的。这对于工作在交互式环境中的人们来说非常便利,比如使用IPython。
  • tf.Session():需要在启动session之前构建整个计算图,然后启动该计算图。

7. 交叉熵函数

(1) tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)

特点:多分类,目标只有一个
Args:

  • logits:就是神经网络最后一层的输出,如果有batch的话,它的大小就是[batchsize,num_classes],单样本的话,大小就是num_classes
  • labels:实际的标签,大小同上

Retrue:
A Tensor of the shape [batchsize,]

import tensorflow as tf
logits=tf.constant([[1.0,2.0,3.0],[1.0,2.0,3.0],[1.0,2.0,3.0]])
y=tf.nn.softmax(logits)
y_=tf.constant([[0.0,0.0,1.0],[0.0,0.0,1.0],[0.0,0.0,1.0]])
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
cross_entropy2=tf.reduce_sum(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y_))
with tf.Session() as sess:
    softmax=sess.run(y)
    c_e = sess.run(cross_entropy)
    c_e2 = sess.run(cross_entropy2)
    print("step1:softmax result=")
    print(softmax)
    print("step2:cross_entropy result=")
    print(c_e)
    print("Function(softmax_cross_entropy_with_logits) result=")
    print(c_e2)

notes: tensorflow交叉熵计算函数输入中的logits都不是softmax或sigmoid的输出,而是softmax或sigmoid函数的输入,因为它在函数内部进行sigmoid或softmax操作。如果 logits 进行了缩放,那么反而会影响计算正确性。

(2) tf.nn.sigmoid_cross_entropy_with_logits

特点:二分类或多个二分类问题,每个分类互相独立
Args:

  • logits: A Tensor of type float32 or float64. 大小就是[batchsize,num_objects]
  • labels: A Tensor of the same type and shape as logits.

Returns:
A Tensor of the same shape as logits with the componentwise logistic losses.

(3) tf.nn.sparse_softmax_cross_entropy_with_logits

sparse_softmax_cross_entropy_with_logits是softmax_cross_entropy_with_logits的易用版本.
参数labels的shape为[batch_size],而值必须是从0开始编码的int32或int64,而且值范围是[0, num_class)

9. tf.nn.in_top_k

主要是用于计算预测的结果和实际结果的是否相等,返回一个bool类型的张量,tf.nn.in_top_k(prediction, target, K):

  • prediction就是表示你预测的结果,大小就是预测样本的数量乘以输出的维度,类型是tf.float32等。
  • target就是实际样本类别的标签,大小就是样本数量的个数。
  • K表示每个样本的预测结果的前K个最大的数的标签里面是否含有target中的值。一般都是取1。
import tensorflow as tf
A = [[0.7,0.8,0.3], [0.1,0.6,0.4]]
B = [1, 1]
out = tf.nn.in_top_k(A, B, 1)
correct_prediction = tf.equal(tf.argmax(A, 1), B)
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())
    print("Accuracy:", sess.run(accuracy)) #[True, True]
    print(sess.run(out))  #[True, True]

修改A的值,可以体现出方法一比方法二更加严谨

import tensorflow as tf
A = [[0.8,0.8,0.3], [0.1,0.6,0.4]]
B = [1, 1]
out = tf.nn.in_top_k(A, B, 1)
correct_prediction = tf.equal(tf.argmax(A, 1), B)
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())
    print("Accuracy:", sess.run(accuracy)) #[False, True]
    print(sess.run(out))  #[True, True]

10. tf.shape(a) & tensor.get_shape()

import tensorflow as tf
import numpy as np
x = tf.constant([[1,2,3],[4,5,6]])
y = [[1,2,3],[4,5,6]]
z = np.arange(24).reshape([2,3,4])
with tf.Session() as sess:
    # tf.shape()
    x_shape=tf.shape(x)          #   <tf.Tensor 'Shape_2:0' shape=(2,) dtype=int32>
    y_shape=tf.shape(y)          #  <tf.Tensor 'Shape_2:0' shape=(2,) dtype=int32>
    z_shape=tf.shape(z)          #  <tf.Tensor 'Shape_5:0' shape=(3,) dtype=int32>
    print(sess.run(x_shape))        # 结果:[2 3]
    print(sess.run(y_shape))        # 结果:[2 3]
    print(sess.run(z_shape))          # 结果:[2 3 4]

    #a.get_shape()
    x_shape=x.get_shape()  # 返回的是TensorShape([Dimension(2), Dimension(3)]),不能使用 sess.run() 因为返回的不是tensor 或string,而是元组
    x_shape=x.get_shape().as_list()  # 可以使用 as_list()得到具体的尺寸,x_shape=[2 3]
    x_shape1 = x.get_shape()[1].value
    print(x_shape)
    print(x_shape1)
    print(x_shape[1])
    #y_shape=y.get_shape()  # AttributeError: 'list' object has no attribute 'get_shape‘
    #z_shape=z.get_shape()  # AttributeError: 'numpy.ndarray' object has no attribute 'get_shape'

11.

name_scope:

此函数参数最为简单:
name_scope( name, default_name=None, values=None )
name 当然是scope 名称,当name 为none时, 该scope名称就由default_name 来,当前两项都为空而values不为空时,就会报错。 此外,name不允许以’/’结尾。
values是传入的张量参数列表。

注意:
with name_scope(…) 与with name_scope(…) as scope 的区别:
后者将该域的名字储存在了scope变量中。

在 tf.name_scope下时,tf.get_variable()创建的变量名不受 name_scope 的影响(tf.variable_scope中使用会受scope的影响),而且在未指定共享变量时,如果重名会报错,tf.Variable()会自动检测有没有变量重名,如果有则会自行处理。


import tensorflow as tf

with tf.name_scope('name_scope_x'):
    var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)
    var3 = tf.Variable(name='var2', initial_value=[2], dtype=tf.float32)
    var4 = tf.Variable(name='var2', initial_value=[2], dtype=tf.float32)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(var1.name, sess.run(var1))
    print(var3.name, sess.run(var3))
    print(var4.name, sess.run(var4))
# 输出结果:
# var1:0 [-0.30036557]   可以看到前面不含有指定的'name_scope_x'
# name_scope_x/var2:0 [ 2.]
# name_scope_x/var2_1:0 [ 2.]  可以看到变量名自行变成了'var2_1',避免了和'var2'冲突

如果使用tf.get_variable()创建变量,且没有设置共享变量,重名时会报错,使用variable_scope,可以设置共享变量

import tensorflow as tf

with tf.name_scope('name_scope_1'):
    var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)
    var2 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(var1.name, sess.run(var1))
    print(var2.name, sess.run(var2))

# ValueError: Variable var1 already exists, disallowed. Did you mean 
# to set reuse=True in VarScope? Originally defined at:
# var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)

variable_scope

variable_scope( name_or_scope, default_name=None, values=None, initializer=None, regularizer=None, caching_device=None, partitioner=None, custom_getter=None, reuse=None, dtype=None, use_resource=None)

name_or_scopedefault_namevalues参数与name_scope中的第一和第二项参数几乎是一样的(第一个参数除了名称外还可以是scope)。

initializer是选用的变量初始化器;
regularizer是选用的变量正则化器;
dtype:数据类型;
use_resource: If False, all variables will be regular Variables. If True, experimental ResourceVariables with well-defined semantics will be used instead. Defaults to False (will later change to True).

reuse 是一个很关键的参数,当reuse=True时,开启了重用模式(参数共享模式),使用get_variable创建变量时,会搜索现有的同名变量(没有就会报错),举个例子(官方例子):

with tf.variable_scope("foo"):
    v = tf.get_variable("v", [1])
with tf.variable_scope("foo", reuse=True):
    v1 = tf.get_variable("v", [1])
assert v1 == v

或者:

with tf.variable_scope("foo") as scope:
    v = tf.get_variable("v", [1])
    scope.reuse_variables()
    v1 = tf.get_variable("v", [1])
assert v1 == v

reuse参数是会继承的,你懂的。

可能的报错:
ValueError:在重用模式下创建变量或非重用模式下重用变量;(即前边提到的知乎答主的表述问题)
TypeError:参数有问题。

12、 flags的解析方法

1、使用argparse包
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
      '--learning_rate',
      type=float,
      default=0.01,
      help='Initial learning rate.'
  )
parser.add_argument(
      '--max_steps',
      type=int,
      default=2000,
      help='Number of steps to run trainer.'
  )
FLAGS, unparsed = parser.parse_known_args()
# 输出时,
print(FLAGS.learning_rate)  #输出=0.01

参数名为“ab”的为位置参数,“–ab”为可选参数

有时候,一个脚本可能只解析一些命令行参数,将剩余的参数传递给另一个脚本或程序。在这些情况下,parse_known_args()方法可能有用。它的工作方式很像parse_args(),只是当出现额外的参数时它不会产生错误。相反,它返回一个包含填充名称空间和剩余参数字符串列表的两项元组。

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_true')
>>> parser.add_argument('bar')
>>> parser.parse_known_args(['--foo', '--badger', 'BAR', 'spam'])
(Namespace(bar='BAR', foo=True), ['--badger', 'spam'])
2、使用tf的包(1)
import tensorflow as tf
FLAGS = tf.app.flags.FLAGS

tf.app.flags.DEFINE_string('train_dir', 'tmp/train/',
                           """Directory where to write event logs """
                           """and checkpoint.""")
tf.app.flags.DEFINE_integer('max_steps', 700,
                            """Number of batches to run.""")
tf.app.flags.DEFINE_boolean('log_device_placement', False,
                            """Whether to log device placement.""")

print(FLAGS.max_steps)   # 输出=700
3、使用tf的包(2)——简洁用法
import tensorflow as tf
flags = tf.app.flags
flags.DEFINE_float("threshold", 0.1, "detection threshold")
flags.DEFINE_string("model", "", "configuration of choice")
flags.DEFINE_string("trainer", "rmsprop", "training algorithm")
FLAGS = flags.FLAGS

print(FLAGS.threshold)   # 输出=0.1
发布了42 篇原创文章 · 获赞 6 · 访问量 1万+
展开阅读全文

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

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览