动态图
在这种模式下,每次执行一个运算,可以立即得到结果(而不是事先定义好网络结构,然后再执行)。在动态图模式下,你可以更加方便的组织代码,更容易的调试程序,本示例教程将向你介绍飞桨的动态图的使用。
一、环境配置
import paddle
import paddle.nn.functional as F
import numpy as np
print(paddle.__version__)
2.2.1
二、基本用法
在动态图模式下,你可以直接运行一个飞桨提供的API,它会立刻返回结果到python。不再需要首先创建一个计算图,然后再给定数据去运行。
a = paddle.randn([4, 2])
b = paddle.arange(1, 3, dtype='float32')
print(a)
print(b)
c = a + b
print(c)
d = paddle.matmul(a, b)
print(d)
Tensor(shape=[4, 2], dtype=float32, place=CUDAPlace(0), stop_gradient=True,
[[-1.23295915, 0.43236846],
[-0.09865052, 0.95576662],
[-0.06097634, 2.17814565],
[ 0.08014798, -0.56198031]])
Tensor(shape=[2], dtype=float32, place=CUDAPlace(0), stop_gradient=True,
[1., 2.])
Tensor(shape=[4, 2], dtype=float32, place=CUDAPlace(0), stop_gradient=True,
[[-0.23295915, 2.43236852],
[ 0.90134948, 2.95576668],
[ 0.93902367, 4.17814541],
[ 1.08014798, 1.43801975]])
Tensor(shape=[4], dtype=float32, place=CUDAPlace(0), stop_gradient=True,
[-0.36822224, 1.81288266, 4.29531479, -1.04381263])
三、使用python的控制流
动态图模式下,你可以使用python的条件判断和循环,这类控制语句来执行神经网络的计算
。(不再需要cond, loop这类OP)
a = paddle.to_tensor(np.array([1, 2, 3]))
b = paddle.to_tensor(np.array([4, 5, 6]))
for i in range(10):
r = paddle.rand([1,])
if r > 0.5:
c = paddle.pow(a, i) + b
print("{} +> {}".format(i, c.numpy()))
else:
c = paddle.pow(a, i) - b
print("{} -> {}".format(i, c.numpy()))
0 -> [-3 -4 -5]
1 +> [5 7 9]
2 +> [ 5 9 15]
3 -> [-3 3 21]
4 +> [ 5 21 87]
5 +> [ 5 37 249]
6 -> [ -3 59 723]
7 -> [ -3 123 2181]
8 -> [ -3 251 6555]
9 +> [ 5 517 19689]
四、构建更加灵活的网络:控制流
class MyModel(paddle.nn.Layer):
def __init__(self, input_size, hidden_size):
super(MyModel, self).__init__()
self.linear1 = paddle.nn.Linear(input_size, hidden_size)
self.linear2 = paddle.nn.Linear(hidden_size, hidden_size)
self.linear3 = paddle.nn.Linear(hidden_size, 1)
def forward(self, inputs):
x = self.linear1(inputs)
x = F.relu(x)
if paddle.rand([1,]) > 0.5:
x = self.linear2(x)
x = F.relu(x)
x = self.linear3(x)
return x
total_data, batch_size, input_size, hidden_size = 1000, 64, 128, 256
x_data = np.random.randn(total_data, input_size).astype(np.float32)
y_data = np.random.randn(total_data, 1).astype(np.float32)
model = MyModel(input_size, hidden_size)
loss_fn = paddle.nn.MSELoss(reduction='mean')
optimizer = paddle.optimizer.SGD(learning_rate=0.01,
parameters=model.parameters())
for t in range(200 * (total_data // batch_size)):
idx = np.random.choice(total_data, batch_size, replace=False)
x = paddle.to_tensor(x_data[idx,:])
y = paddle.to_tensor(y_data[idx,:])
y_pred = model(x)
loss = loss_fn(y_pred, y)
if t % 200 == 0:
print(t, loss.numpy())
loss.backward()
optimizer.step()
optimizer.clear_grad()
0 [1.5085251]
200 [0.76789844]
400 [0.52853113]
600 [0.27155834]
800 [0.21036112]
1000 [0.04863136]
1200 [0.0624725]
1400 [0.02772576]
1600 [0.02455759]
1800 [0.00250034]
2000 [0.00698137]
2200 [0.008535]
2400 [0.00082006]
2600 [0.00335711]
2800 [0.00096334]
五、构建更加灵活的网络:共享权重
inputs = paddle.rand((256, 64))
linear = paddle.nn.Linear(64, 8, bias_attr=False)
loss_fn = paddle.nn.MSELoss()
optimizer = paddle.optimizer.Adam(0.01, parameters=linear.parameters())
for i in range(10):
hidden = linear(inputs)
# weight from input to hidden is shared with the linear mapping from hidden to output
outputs = paddle.matmul(hidden, linear.weight, transpose_y=True)
loss = loss_fn(outputs, inputs)
loss.backward()
print("step: {}, loss: {}".format(i, loss.numpy()))
optimizer.step()
optimizer.clear_grad()
step: 0, loss: [0.32769835]
step: 1, loss: [0.30599958]
step: 2, loss: [0.28045067]
step: 3, loss: [0.25096473]
step: 4, loss: [0.218723]
step: 5, loss: [0.1859532]
step: 6, loss: [0.1555582]
step: 7, loss: [0.13047957]
step: 8, loss: [0.11281298]
step: 9, loss: [0.10287865]
The End
可以看到使用动态图带来了更灵活易用的方式来组网和训练。你也可以在【使用注意力机制的LSTM的机器翻译】和【图片检索】两个示例中看到更完整的动态图的实际应用的灵活和便利。