2019-10-10

Tensorflow 、Python 用法

标签(空格分隔): tensorflow pyton


TensorFlow

import tensorflow as tf

列表项

tf.contrib.layers.xavier_initializer

xavier_initializer(
    uniform=True,
    seed=None,
    dtype=tf.float32
)

该函数返回一个用于初始化权重的初始化程序 “Xavier” 。
这个初始化器是用来保持每一层的梯度大小都差不多相同。

参数:
uniform: 使用uniform或者normal分布来随机初始化。
seed: 可以认为是用来生成随机数的seed
dtype: 只支持浮点数。
返回值:
初始化权重矩阵

梯度计算、累积与更新

minimize可看作compute_gradients和apply_gradients二者之和
将梯度在target network和learner间传递的功能在distributed tensorflow中默认已经实现好了。Between-graph的方式中,每个thread会拷贝一份Graph,计算后回传回主Graph。需要解决的主要是梯度累积的问题。
基本的思路是:

repeat:
     计算梯度
     存储梯度
until 一定次数
将累积的梯度回传至target network

具体要用到的是optimizer类的compute_gradients()和apply_gradients()两种方法。以下分步讲解
1. 定义操作

# Define input and output
with tf.name_scope('input'):
    x = tf.placeholder(tf.float32, name="x")
with tf.name_scope('weights'):
    w = tf.Variable(2.0, name='target_w')
with tf.name_scope('output'):
    y = tf.mul(x, w, name='y')
with tf.name_scope('real_output'):
    y_ = tf.placeholder(tf.float32, name="y_")

# Define train op
with tf.name_scope('train'):
   optimizer = tf.train.GradientDescentOptimizer(LEARNING_RATE)
with tf.name_scope('gradient'):
    loss = tf.reduce_mean(tf.square(y_ - y))  # MSE loss
    gradient_all = optimizer.compute_gradients(loss)  # gradient of network (with NoneType)
    grads_vars = [v for (g, v) in gradient_all if g is not None]  # all variable that has gradients
    gradient = optimizer.compute_gradients(loss, grads_vars)  # gradient of network (without NoneType)
    grads_holder = [(tf.placeholder(tf.float32, shape=g.get_shape()), v)
                     for (g, v) in gradient]
    train_op = optimizer.apply_gradients(grads_holder)

y_是真实值,y是网络的输出,loss是mse损失。optimizer是一个梯度下降优化器。gradient_all是optmizer计算的梯度,返回的是一个列表,其中的元素是型为的tuple。注意,如果网络不是单输入单输出(例如ac网络中有两个输出),那么compute_gradients可能会返回(None,v),即部分变量没有对应的梯度,在下一步的时候NoneType会导致错误。因此,需要将有梯度的变量提取出来,记为grads_vars。之后,对grads_vars再一次计算梯度,得到了gradient。最后, 生成一个placeholder用于存储梯度,并调用apply_gradients更新网络。

注意,此处定义的w会出现问题,在第三节实验部分会提出一个解决办法。

2. 应用操作

# calculate gradients every  
grads = []
for i in range(THREAD_STEPS):
    x_i = ...
    y_real = ...
    y_i = sess.run(y, feed_dict={x: x_i})
    loss_i = sess.run(loss, feed_dict={x: x_i, y_: y_real})
    grad_i = sess.run(gradient, feed_dict={x: x_i, y_: y_real})
    grads.append(grad_i)

# calculate total gradients
grads_sum = {}
# add up dθ
for i in range(len(grads_holder)):
    k = grads_holder[i][0]
    grads_sum[k] = sum([g[i][0] for g in grads])

# Apply gradients
_ = sess.run(train_op, feed_dict=grads_sum)

操作分为三步:

第一步,输入x_i,y_计算梯度,并使用一个列表grads保存梯度;

第二步,使用一个字典对梯度进行累积。字典的格式为。由于grads的每一个元素都是与grads_holder格式相同的梯度列表,grads_holder[i][0]对应的梯度值列表就是[g[i][0] for g in grads]。

第三步,将前一步生成的字典feed给apply_gradients,Mission complete。

tf.trainable_variables

返回的是需要训练的变量列表

tf.all_variables

返回的是所有变量的列表

tf.control_dependencies

tf.control_dependencies()设计是用来控制计算流图的,给图中的某些计算指定顺序。比如:我们想要获取参数更新后的值,那么我们可以这么组织我们的代码。

opt = tf.train.Optimizer().minize(loss)
with tf.control_dependencies([opt]):
  updated_weight = tf.identity(weight)
with tf.Session() as sess:
  tf.global_variables_initializer().run()
  sess.run(updated_weight, feed_dict={...}) # 这样每次得到的都是更新后的weight

tf.identity

tf.identity是返回一个一模一样新的tensor,但这个操作是一个op,这会增加一个新节点到gragh中,这时control_dependencies就会生效
例子

x = tf.Variable(0.0)
x_plus_1 = tf.assign_add(x, 1)

with tf.control_dependencies([x_plus_1]):
    y = x
init = tf.initialize_all_variables()

with tf.Session() as session:
    init.run()
    for i in xrange(5):
        print(y.eval())

返回0, 0, 0, 0, 0. 因为y=x在tensorflow中不是一个结点,x = tf.Variable(0.0)修改为

x_plus_1 = tf.assign_add(x, 1)

with tf.control_dependencies([x_plus_1]):
    y = tf.identity(x)
init = tf.initialize_all_variables()

with tf.Session() as session:
    init.run()
    for i in xrange(5):
        print(y.eval())

返回为:1, 2, 3, 4, 5.

tf.no_op

tf.no_op()表示执行完 train_step, variable_averages_op 操作之后什么都不做
例子

with tf.control_dependencies([a, b]):
     c = ....
     d = ...

在执行完 a,b 操作之后,才能执行 c,d 操作。意思就是 c,d 操作依赖 a,b 操作

with tf.control_dependencies([train_step, variable_averages_op]):
    train_op = tf.no_op(name='train')

执行完train_step,variavle_averages_op后,什么也不做

tf.split()

API原型(TensorFlow 1.8.0):

tf.split(
    value,
    num_or_size_splits,
    axis=0,
    num=None,
    name='split'
)

这个函数是用来切割张量的。输入切割的张量和参数,返回切割的结果。
value传入的就是需要切割的张量。
这个函数有两种切割的方式:

以三个维度的张量为例,比如说一个20 * 30 * 40的张量my_tensor,就如同一个长20厘米宽30厘米高40厘米的蛋糕,每立方厘米都是一个分量。

有两种切割方式:

  1. 如果num_or_size_splits传入的是一个整数,这个整数代表这个张量最后会被切成几个小张量。此时,传入axis的数值就代表切割哪个维度(从0开始计数)。调用tf.split(my_tensor, 2,0)返回两个10 * 30 * 40的小张量。
  2. 如果num_or_size_splits传入的是一个向量,那么向量有几个分量就分成几份,切割的维度还是由axis决定。比如调用tf.split(my_tensor, [10, 5, 25], 2),则返回三个张量分别大小为 20 * 30 * 10、20 * 30 * 5、20 * 30 * 25。很显然,传入的这个向量各个分量加和必须等于axis所指示原张量维度的大小 (10 + 5 + 25 = 40)。

tf.losses.mean_squared_error()

tf.losses.mean_squared_error()就是直接计算mse值.

tf.losses.mean_squared_error(
    labels,
    predictions,
    weights=1.0,
    scope=None,
    loss_collection=tf.GraphKeys.LOSSES,
    reduction=Reduction.SUM_BY_NONZERO_WEIGHTS
)

参数:

  • labels:真实的输出张量,与“predictions”相同。
  • predictions:预测的输出。
  • weights:可选的Tensor,其秩为0或与labels具有相同的秩,并且必须可广播到labels(即,所有维度必须为> * 1与相应的losses具有相同的维度)。
  • scope:计算loss时执行的操作范围。
  • loss_collection:将添加loss的集合。
  • reduction:适用于loss的减少类型。
    返回:
  • 加权损失浮动Tensor。如果reduction是NONE,则它的形状与labels相同;否则,它是标量。
    可能引发的异常:
    ValueError:如果predictions与labels的形状不匹配,或者形状weights是无效,亦或,如果labels或是predictions为None,则会引发此类异常。

在训练过程中增加了平方和loss。
在这个函数中,weights作为loss的系数。如果提供了标量,那么loss只是按给定值缩放。如果weights是一个大小为[batch_size]的张量,那么批次的每个样本的总损失由weights向量中的相应元素重新调整。如果weights的形状与predictions的形状相匹配,则predictions中每个可测量元素的loss由相应的weights值缩放。

tf.layers.dense

tf.Layers.Dense是一个类,tf.layers.dense是一个函数

dense(inputs,
units,
activation=None,
use_bias=True,
kernel_initializer=None,
bias_initializer=tf.zeros_initializer(),
kernel_regularizer=None,
bias_regularizer=None,
activity_regularizer=None,
trainable=True,
name=None,
reuse=None)
原文:https://blog.csdn.net/jshmjs45/article/details/82697720?utm_source=copy 

参数:

inputs:tf.layers.dense 的Tensor输入。

  • units:整数或长整数,输出空间的维数。
  • activation:激活功能(可调用),将其设置为“None”以保持线性激活。
  • use_bias:Boolean,表示该层是否使用偏差。
  • kernel_initializer:权重矩阵的初始化函数;如果为None(默认),则使用tf.get_variable使用的默认初始化程序初始化权重。
  • bias_initializer:偏置的初始化函数。
  • kernel_regularizer:权重矩阵的正则化函数。
  • bias_regularizer:正规函数的偏差。
  • activity_regularizer:输出的正则化函数。
  • kernel_constraint:由Optimizer更新后应用于内核的可选投影函数(例如,用于实现层权重的范数约束或值约束)。该函数必须将未投影的变量作为输入,并且必须返回投影变量(必须具有相同的形状)。在进行异步分布式训练时,使用约束是不安全的。
  • bias_constraint:由Optimizer更新后应用于偏置的可选投影函数。
  • trainable:Boolean,如果为True,还将变量添加到图集合GraphKeys.TRAINABLE_VARIABLES中(请参阅参考资料tf.Variable)。
  • name:String,图层的名称;具有相同名称的图层将共享权重,但为了避免错误,在这种情况下,我们需要reuse=True。
  • reuse:Boolean,是否以同一名称重用前一层的权重。

这个函数返回一个全连接层 outputs = activation(inputs * kernel_initializer + bias)
例如:

net = tf.layers.dense(s, 30, activation=tf.nn.relu, name='l1', trainable=trainable)
a = tf.layers.dense(net, self.a_dim, activation=tf.nn.tanh, name='a',trainable=trainable)

tf.squared_difference(x,y,name=None)

功能:计算(x-y)(x-y)。
输入:x为张量,可以为`half`,`float32`,`float64`类型。
例:
x=tf.constant([[-1,0,2]],tf.float64)
y=tf.constant([[2,3,4,]],tf.float64)
z=tf.squared_difference(x,y) 
z==>[[9. 9. 4.]]

tf.concat

tf.concat( values,concat_dim, name='concat')
除去name参数用以指定该操作的name,与方法有关的一共两个参数:
第一个参数concat_dim:必须是一个数,表明在哪一维上连接
如果concat_dim是0,那么在某一个shape的第一个维度上连,对应到实际,就是叠放到列上

t1 = [[1, 2, 3], [4, 5, 6]]
t2 = [[7, 8, 9], [10, 11, 12]]
tf.concat([t1, t2],0) == > [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]

如果concat_dim是1,那么在某一个shape的第二个维度上连

t1 = [[1, 2, 3], [4, 5, 6]]
t2 = [[7, 8, 9], [10, 11, 12]]
tf.concat([t1, t2],1) ==> [[1, 2, 3, 7, 8, 9], [4, 5, 6, 10, 11, 12

如果有更高维,最后连接的依然是指定那个维:
values[i].shape = [D0, D1, ... Dconcat_dim(i), ...Dn]连接后就是:[D0, D1, ... Rconcat_dim, ...Dn]

第二个参数values:就是两个或者一组待连接的tensor了

Python

import numpy as np

np.random.normal()

numpy.random.normal(loc=0.0, scale=1.0, size=None)
loc:float
    此概率分布的均值(对应着整个分布的中心centre)
scale:float
    此概率分布的标准差(对应于分布的宽度,scale越大越矮胖,scale越小,越瘦高)
size:int or tuple of ints
    输出的shape,默认为None,只输出一个值

更经常会用到的np.random.randn(size)所谓标准正态分布(μ=0,σ=1μ=0,σ=1),对应于np.random.normal(loc=0, scale=1, size)。

np.clip

numpy.clip(a, a_min, a_max, out=None)
参数说明 
a : 输入的数组
a_min: 限定的最小值 也可以是数组 如果为数组时 shape必须和a一样
a_max:限定的最大值 也可以是数组 shape和a一样
out:剪裁后的数组存入的数组

>>> a = np.arange(10)
>>> np.clip(a, 1, 8)
array([1, 1, 2, 3, 4, 5, 6, 7, 8, 8]) # a被限制在1-8之间
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) # 没改变a的原值

>>> np.clip(a, 3, 6, out=a) # 修剪后的数组存入到a中
array([3, 3, 3, 3, 4, 5, 6, 6, 6, 6])

>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.clip(a, [3,4,1,1,1,4,4,4,4,4], 8)
# 当a_min为数组时, a中每个元素和都和a_min中对应元素比较
# 0 < 3 -->小于最小值 则等于3
# 3 > 2 -->大于最小值 则等于本身 再和最大值比 没超过最大值 所以为3
array([3, 4, 2, 3, 4, 5, 6, 7, 8, 8])

你可能感兴趣的:(2019-10-10)