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厘米的蛋糕,每立方厘米都是一个分量。
有两种切割方式:
- 如果num_or_size_splits传入的是一个整数,这个整数代表这个张量最后会被切成几个小张量。此时,传入axis的数值就代表切割哪个维度(从0开始计数)。调用tf.split(my_tensor, 2,0)返回两个10 * 30 * 40的小张量。
- 如果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])