《第八章》

8.1命令式和符号式混合编程

命令式:jupyter lab上一边输入一边输出。

符号式:将所有代码转化为字符prog,然后通过下述方法执行。

y = compile(prog, '', 'exec')
exec(y)

混合式编程:1.使用HybridSequential;2.使用HybridBlock,如下。

class HybridNet(nn.HybridBlock):
    def __init__(self, **kwargs):
        super(HybridNet, self).__init__(**kwargs)
        self.hidden = nn.Dense(10)
        self.output = nn.Dense(2)
	
    # 是hybrid_forward而不是forward,且需要F来决定使用哪个类
    # MXNet有基于命令式编程的NDArray类(默认)和基于符号式编程的Symbol类。
    def hybrid_forward(self, F, x):
        print('F: ', F)
        print('x: ', x)
        x = F.relu(self.hidden(x))
        print('hidden: ', x)
        return self.output(x)
    
net = HybridNet()
net.initialize()
x = nd.random.normal(shape=(1, 4))
net.hybridize() # 能提升性能。
net(x)
net(x)
# 在hybrid_forward函数里,相同输入和中间输出全部变成了Symbol类型,再次前向后不再打印输出。
# 对于原地操作a += b和a[:] = a + b(需改写为a = a + b)

练习

  • 在本节HybridNet类的hybrid_forward函数中第一行添加x.asnumpy(),运行本节的全部代码,观察并分析报错的位置和错误类型。

    答:在转换成符号式编程net.hybridize()的时候提示

    Function asnumpy is not implemented for Symbol and only available in NDArray.

    因为对于少数像asnumpy这样的Symbol所不支持的函数无法在hybrid_forward函数中使用并在调用hybridize函数后进行前向计算。

  • 如果在hybrid_forward函数中加入Python的iffor语句会怎么样?

    加入if的错误:Function __bool__ (namely operator "bool") is not implemented for Symbol and only available in NDArray.

    加入for,暂时没发现错误。

  • 回顾前面几章中你感兴趣的模型,改用HybridBlock类或HybridSequential类实现。

8.2异步计算

  • MXNet包括用户直接用来交互的前端和系统用来执行计算的后端。

  • MXNet能够通过异步计算提升计算性能。

  • 在“使用异步计算提升计算性能”一节中,我们提到使用异步计算可以使执行1000次计算的总耗时降为t1+1000t2+t3。这里为什么要假设1000t2>999t1?

    答:当执行真正计算的时间t2足够大的时候,才有必要通过异步降低(这题猜的)

8.3自动并行计算

MXNet能够通过自动并行计算提升计算性能。例如一边计算一边传入内存。

练习

  • 本节中定义的run函数里做了10次运算。它们之间也没有依赖关系。设计实验,看看MXNet有没有自动并行执行它们。

    答:有依赖,没有并行执行。

  • 设计包含更加复杂的数据依赖的计算任务,通过实验观察MXNet能否得到正确的结果并提升计算性能。

    答:可以。

  • 当运算符的计算量足够小时,仅在CPU或单块GPU上并行计算也可能提升计算性能。设计实验来验证这一点。

8.4多GPU计算

练习

  • 在多GPU训练实验中,使用2块GPU训练并将batch_size翻倍至512,训练时间有何变化?如果希望测试准确率与单GPU训练中的结果相当,学习率应如何调节?

    答:考虑ctx = [mx.gpu(0),mx.cpu(0)]来模拟两个gpu的效果。这种方法十分耗费时间,我这边测试44s一个周期。1.训练时间差不多。2.单GPU中lr为0.17,GPU+CPU中lr为0.2

    (对于上述实验结果,持有迷惑行为,无力解释)

  • 将实验的模型预测部分改为用多GPU预测。

8.5多GPU简洁计算

  1. 定义模型,初始化参数

  2. 划分数据样本到各个内存或显存上。

  3. 训练函数

  4. 训练

练习

  • 本节使用了ResNet-18模型。试试不同的迭代周期、批量大小和学习率。如果条件允许,使用更多GPU来计算。

    答:不想试,没什么意义。

  • 有时候,不同设备的计算能力不一样,例如,同时使用CPU和GPU,或者不同GPU之间型号不一样。这时候,应该如何将小批量划分到内存或不同显卡的显存?

最后更新于

这有帮助吗?