动态图

    日期: 2021.01

    摘要: 从飞桨开源框架2.0版本开始,飞桨默认为用户开启了动态图开发模式。在这种模式下,每次执行一个运算,可以立即得到结果(而不是事先定义好网络结构,然后再执行)。在动态图模式下,你可以更加方便的组织代码,更容易的调试程序,本示例教程将向你介绍飞桨的动态图的使用。

    二、基本用法

    在动态图模式下,ni可以直接运行一个飞桨提供的API,它会立刻返回结果到python。不再需要首先创建一个计算图,然后再给定数据去运行。

    1. a = paddle.randn([4, 2])
    2. b = paddle.arange(1, 3, dtype='float32')
    3. print(a)
    4. print(b)
    5. c = a + b
    6. print(c)
    7. d = paddle.matmul(a, b)
    8. print(d)

    动态图模式下,您可以使用python的条件判断和循环,这类控制语句来执行神经网络的计算。(不再需要cond, loop这类OP)

    1. a = paddle.to_tensor(np.array([1, 2, 3]))
    2. b = paddle.to_tensor(np.array([4, 5, 6]))
    3. for i in range(10):
    4. r = paddle.rand([1,])
    5. if r > 0.5:
    6. c = paddle.pow(a, i) + b
    7. print("{} +> {}".format(i, c.numpy()))
    8. else:
    9. c = paddle.pow(a, i) - b
    10. print("{} -> {}".format(i, c.numpy()))
    1. 0 +> [5 6 7]
    2. 2 +> [ 5 9 15]
    3. 4 +> [ 5 21 87]
    4. 5 -> [ -3 27 237]
    5. 6 +> [ 5 69 735]
    6. 7 -> [ -3 123 2181]
    7. 8 -> [ -3 251 6555]
    8. 9 -> [ -3 507 19677]

    四、构建更加灵活的网络:控制流

    • 在sequence to sequence with attention的机器翻译的示例中,你会看到更实际的使用动态图构建RNN类的网络带来的灵活性。

    1. total_data, batch_size, input_size, hidden_size = 1000, 64, 128, 256
    2. x_data = np.random.randn(total_data, input_size).astype(np.float32)
    3. y_data = np.random.randn(total_data, 1).astype(np.float32)
    4. model = MyModel(input_size, hidden_size)
    5. loss_fn = paddle.nn.MSELoss(reduction='mean')
    6. optimizer = paddle.optimizer.SGD(learning_rate=0.01,
    7. parameters=model.parameters())
    8. for t in range(200 * (total_data // batch_size)):
    9. idx = np.random.choice(total_data, batch_size, replace=False)
    10. x = paddle.to_tensor(x_data[idx,:])
    11. y = paddle.to_tensor(y_data[idx,:])
    12. y_pred = model(x)
    13. loss = loss_fn(y_pred, y)
    14. if t % 200 == 0:
    15. print(t, loss.numpy())
    16. optimizer.step()
    17. optimizer.clear_grad()
    1. 0 [1.3321278]
    2. 200 [0.82869977]
    3. 400 [0.57817966]
    4. 600 [0.47205922]
    5. 800 [0.15331703]
    6. 1000 [0.06435855]
    7. 1200 [0.07417449]
    8. 1400 [0.04293861]
    9. 1600 [0.02513926]
    10. 1800 [0.02017618]
    11. 2000 [0.00986554]
    12. 2200 [0.00199787]
    13. 2400 [0.00101295]
    14. 2600 [0.00083713]
    15. 2800 [0.00051033]
    • 使用动态图还可以更加方便的创建共享权重的网络,下面的示例展示了一个共享了权重的简单的AutoEncoder。

    1. step: 0, loss: [0.33400834]
    2. step: 1, loss: [0.31674492]
    3. step: 2, loss: [0.29477125]
    4. step: 3, loss: [0.2680785]
    5. step: 4, loss: [0.23595281]
    6. step: 5, loss: [0.20035137]
    7. step: 6, loss: [0.16562223]
    8. step: 7, loss: [0.13548139]
    9. step: 8, loss: [0.11210174]
    10. step: 9, loss: [0.09638017]

    The End

    可以看到使用动态图带来了更灵活易用的方式来组网和训练。你也可以在【使用注意力机制的LSTM的机器翻译】和【图片检索】两个示例中看到更完整的动态图的实际应用的灵活和便利。