Variable
class paddle.fluid.Variable
[源代码]
注意:
1. 请不要直接调用 Variable 的构造函数,因为这会造成严重的错误发生!
2. 在静态图形模式下:请使用 Block.create_var 创建一个静态的 Variable ,该静态的 Variable 在使用 Executor 执行前是没有实际数据的。
3. 在 Dygraph 模式下:请使用 to_variable 创建一个拥有实际数据的 Variable
在Fluid中,OP的每个输入和输出都是 Variable 。多数情况下, Variable 用于保存不同种类的数据或训练标签。
Variable 总是属于某一个 Block 。所有 Variable 都有其自己的 name
,不同 Block 中的两个 Variable 可以具有相同的名称。如果使用的 不是 Dygraph 模式,那么同一个 Block 中的两个或更多 Variable 拥有相同 name
将意味着他们会共享相同的内容。通常我们使用这种方式来实现 参数共享
Variable 有很多种。它们每种都有自己的属性和用法。请参考 framework.proto 以获得详细信息。 Variable 的大多数成员变量可以设置为 None
。它的意思是它不可用或稍后指定。
如果您希望创建一个 Variable 那么可以参考如下示例:
代码示例
在静态图形模式下:
import paddle.fluid as fluid
cur_program = fluid.Program()
cur_block = cur_program.current_block()
new_variable = cur_block.create_var(name="X",
shape=[-1, 23, 48],
dtype='float32')
在 Dygraph 模式下:
import paddle.fluid as fluid
import numpy as np
with fluid.dygraph.guard():
new_variable = fluid.dygraph.to_variable(np.arange(10))
方法
detach()
注意:
1. 该API只在 Dygraph 模式下生效
2.
detach
后的 Variable 将会成为临时变量
产生一个新的,和当前计算图分离的,但是拥有当前 Variable 其内容的临时变量
返回
一个新的,和当前计算图分离的,但是拥有当前 Variable 其内容的临时 Variable
返回类型
(Variable | 和输入的 Dtype
一致)
代码示例
import paddle.fluid as fluid
from paddle.fluid.dygraph.base import to_variable
from paddle.fluid.dygraph import Linear
import numpy as np
data = np.random.uniform(-1, 1, [30, 10, 32]).astype('float32')
with fluid.dygraph.guard():
linear = Linear(32, 64)
data = to_variable(data)
x = linear(data)
y = x.detach()
numpy()
注意:
1. 该API只在 Dygraph 模式下生效
返回一个 ndarray
来表示当前 Variable 的值
返回
numpy
的数组,表示当前 Variable 的实际值
返回类型
ndarray,dtype
和输入的 dtype
一致
代码示例
import paddle.fluid as fluid
from paddle.fluid.dygraph.base import to_variable
from paddle.fluid.dygraph import Linear
import numpy as np
data = np.random.uniform(-1, 1, [30, 10, 32]).astype('float32')
with fluid.dygraph.guard():
linear = Linear(32, 64)
data = to_variable(data)
x = linear(data)
print(x.numpy())
set_value()
注意:
1. 该API只在 Dygraph 模式下生效
为此 Variable 设置一个新的值。
参数:
返回 无
抛出异常
ValueError
- 当要赋于的新值的 shape
和此 Variable 原有的 shape
不同时,抛出 ValueError
。
代码示例
import paddle.fluid as fluid
from paddle.fluid.dygraph.base import to_variable
from paddle.fluid.dygraph import Linear
import numpy as np
data = np.ones([3, 1024], dtype='float32')
with fluid.dygraph.guard():
linear = fluid.dygraph.Linear(1024, 4)
t = to_variable(data)
linear(t) # 使用默认参数值调用前向
custom_weight = np.random.randn(1024, 4).astype("float32")
linear.weight.set_value(custom_weight) # 将参数修改为自定义的值
out = linear(t) # 使用新的参数值调用前向
backward()
注意:
1. 该API只在 Dygraph 模式下生效
2. 由于如果该 Variable 以上没有任何地方需要梯度,那么仅仅设置该 Variable 的梯度为
1
是没有意义的。因此,这种情况下,为了节省一些计算,我们不去产生该 Variable 的梯度
从该节点开始执行反向
参数:
- backward_strategy: ( BackwardStrategy ) 使用何种 BackwardStrategy 聚合反向的梯度
返回 无
代码示例
import paddle.fluid as fluid
import numpy as np
x = np.ones([2, 2], np.float32)
with fluid.dygraph.guard():
inputs2 = []
for _ in range(10):
tmp = fluid.dygraph.base.to_variable(x)
# 如果这里我们不为输入tmp设置stop_gradient=False,那么后面loss2也将因为这个链路都不需要梯度
# 而不产生梯度
tmp.stop_gradient=False
inputs2.append(tmp)
ret2 = fluid.layers.sums(inputs2)
loss2 = fluid.layers.reduce_sum(ret2)
backward_strategy = fluid.dygraph.BackwardStrategy()
backward_strategy.sort_sum_gradient = True
loss2.backward(backward_strategy)
gradient()
注意:
1. 该API只在 Dygraph 模式下生效
2. 由于如果该 Variable 以上没有任何地方需要梯度,那么仅仅设置该 Variable 的梯度为
1
是没有意义的。因此,这种情况下,为了节省一些计算,我们不去产生该 Variable 的梯度
获取该 Variable 的梯度值
返回 如果 Variable 的类型是LoDTensor(参见 LoDTensor ),返回该 Variable 类型为 ndarray
的梯度值;如果 Variable 的类型是SelectedRows,返回该 Variable 类型为 ndarray
的梯度值和类型为 ndarray
的词id组成的tuple。
返回类型 ndarray
或者 tuple of ndarray
, 返回类型 tuple of ndarray
仅在 Embedding 层稀疏更新时产生。
代码示例
import paddle.fluid as fluid
import numpy as np
# example1: 返回ndarray
x = np.ones([2, 2], np.float32)
with fluid.dygraph.guard():
inputs2 = []
for _ in range(10):
tmp = fluid.dygraph.base.to_variable(x)
tmp.stop_gradient=False
inputs2.append(tmp)
ret2 = fluid.layers.sums(inputs2)
loss2 = fluid.layers.reduce_sum(ret2)
backward_strategy = fluid.dygraph.BackwardStrategy()
backward_strategy.sort_sum_gradient = True
loss2.backward(backward_strategy)
print(loss2.gradient())
# example2: 返回tuple of ndarray
with fluid.dygraph.guard():
embedding = fluid.dygraph.Embedding(
size=[20, 32],
param_attr='emb.w',
is_sparse=True)
x_data = np.arange(12).reshape(4, 3).astype('int64')
x_data = x_data.reshape((-1, 3, 1))
x = fluid.dygraph.base.to_variable(x_data)
out = embedding(x)
out.backward()
print(embedding.weight.gradient())
clear_gradient()
注意:
1. 该API只在 Dygraph 模式下生效
2. 只有当该 Variable 有梯度时才可调用,通常我们都会为参数调用这个方法,因为临时变量的梯度将会在其离开作用域时被
python
自动清除
设置该 Variable 的梯度为零
返回 无
代码示例
import paddle.fluid as fluid
import numpy as np
x = np.ones([2, 2], np.float32)
with fluid.dygraph.guard():
inputs2 = []
for _ in range(10):
tmp = fluid.dygraph.base.to_variable(x)
tmp.stop_gradient=False
inputs2.append(tmp)
ret2 = fluid.layers.sums(inputs2)
loss2 = fluid.layers.reduce_sum(ret2)
backward_strategy = fluid.dygraph.BackwardStrategy()
backward_strategy.sort_sum_gradient = True
loss2.backward(backward_strategy)
print(loss2.gradient())
loss2.clear_gradient()
print("After clear {}".format(loss2.gradient()))
to_string()
注意:
1. 该API只在非 Dygraph 模式下生效
获取该 Variable 的静态描述字符串
参数:(仅在非 Dygraph 模式下生效)
- throw_on_error (bool) - 是否在没有设置必需字段时抛出异常。
- with_details (bool) - 值为true时,打印更多关于 Variable 的信息,如
error_clip
,stop_gradient
等
返回 用于静态描述该 Variable 的字符串
返回
将Program转换为字符串
返回类型
str
抛出异常
ValueError
- 当 throw_on_error == true
,当没有设置任何必需的字段时,抛出 ValueError
。
代码示例
import paddle.fluid as fluid
cur_program = fluid.Program()
cur_block = cur_program.current_block()
new_variable = cur_block.create_var(name="X",
shape=[-1, 23, 48],
dtype='float32')
print(new_variable.to_string(True))
print("\n=============with detail===============\n")
print(new_variable.to_string(True, True))
astype(self, dtype)
将该 Variable 中的数据转换成目标 Dtype
参数:
返回 一个全新的转换了 Dtype
的 Variable
返回类型
代码示例
在静态图模式下:
import paddle.fluid as fluid
startup_prog = fluid.Program()
main_prog = fluid.Program()
with fluid.program_guard(startup_prog, main_prog):
original_variable = fluid.data(name = "new_variable", shape=[2,2], dtype='float32')
new_variable = original_variable.astype('int64')
print("new var's dtype is: {}".format(new_variable.dtype))
在 Dygraph 模式下:
import paddle.fluid as fluid
import numpy as np
x = np.ones([2, 2], np.float32)
with fluid.dygraph.guard():
original_variable = fluid.dygraph.to_variable(x)
print("original var's dtype is: {}, numpy dtype is {}".format(original_variable.dtype, original_variable.numpy().dtype))
new_variable = original_variable.astype('int64')
print("new var's dtype is: {}, numpy dtype is {}".format(new_variable.dtype, new_variable.numpy().dtype))
属性
属性
stop_gradient
注意:该属性在 Dygraph 模式下除参数以外默认值为 True
,而参数的该属性默认值为 False
。在静态图下所有的 Variable 该属性默认值都为 False
是否从此 Variable 开始,之前的相关部分都停止梯度计算
代码示例
import paddle.fluid as fluid
with fluid.dygraph.guard():
value0 = np.arange(26).reshape(2, 13).astype("float32")
value1 = np.arange(6).reshape(2, 3).astype("float32")
value2 = np.arange(10).reshape(2, 5).astype("float32")
linear = fluid.Linear(13, 5, dtype="float32")
linear2 = fluid.Linear(3, 3, dtype="float32")
a = fluid.dygraph.to_variable(value0)
b = fluid.dygraph.to_variable(value1)
c = fluid.dygraph.to_variable(value2)
out1 = linear(a)
out2 = linear2(b)
out1.stop_gradient = True
out = fluid.layers.concat(input=[out1, out2, c], axis=1)
out.backward()
# 可以发现这里linear的参数变成了
assert (linear.weight.gradient() == 0).all()
assert (out1.gradient() == 0).all()
persistable
注意:该属性我们即将废弃,此介绍仅为了帮助用户理解概念, 1.6版本后用户可以不再关心该属性
1. 该属性除参数以外默认值为
False
,而参数的该属性默认值为True
。2. 该属性在 Dygraph 模式下一经初始化即不能修改,这是由于在动态执行时, Variable 的生命周期将由
Python
自行控制不再需要通过该属性来修改
name
注意:在非 Dygraph 模式下,那么同一个 Block 中的两个或更多 Variable 拥有相同 name
将意味着他们会共享相同的内容。通常我们使用这种方式来实现参数共享
此 Variable 的名字(str)
shape
注意:该属性是只读属性
此 Variable 的维度
dtype
注意:该属性是只读属性
此 Variable 的实际数据类型
lod_level
注意:
1. 该属性是只读属性
2. Dygraph 模式下,不支持该属性,该值为零
此 Variable 的 LoD
信息,关于 LoD
可以参考 api_fluid_LoDTensor 相关内容
type
注意:该属性是只读属性
此 Variable 的内存模型,例如是:api_fluid_LoDTensor, 或者SelectedRows