Skip to content

Commit

Permalink
Standardized code format (d2l-ai#1217)
Browse files Browse the repository at this point in the history
* Update selecting-servers-gpus.md (d2l-ai#1208)

Optimized language expression.

* Update machine-translation-and-dataset.md

* Update ndarray.md (d2l-ai#1216)

* Update index.md (d2l-ai#1213)

将Line11  “但是仍需要通过设计更复杂的序列模型  可以  进一步处理它”
更改为     “但是仍需要通过设计更复杂的序列模型  来      进一步处理它”。
仍需要和可以同时使用带来了语言不顺,因此用来替换掉可以。

* [fix] Formula Error (d2l-ai#1211)

链式法则中,对于多元函数求微分,应该使用偏微分符号。
已对比英文版本并做出修改。

* update sagemaker

* update bahdanau-attention

* update bahdanau-attention

* nadaraya-waston

* update transformer

* update async-computation

* update hybridize

* update multiple-gpu-concise

* update multiple-gpus

* update anchor

* update image-augmentation

* update kaggle-cifar10

* update kaggle-dog

* update object-detection-dataset

* update semantic-segmentation-and-dataset

* model-construction

* update use-gpu

* update bert

* update nadaraya-waston

Co-authored-by: Steve George <china.stevegeorge@gmail.com>
Co-authored-by: Aston Zhang <22279212+astonzhang@users.noreply.github.com>
Co-authored-by: byte911 <92360792+byte911@users.noreply.github.com>
Co-authored-by: caoke-963 <62205878+caoke-963@users.noreply.github.com>
Co-authored-by: Andy Shaw <570057644@qq.com>
  • Loading branch information
6 people authored Nov 8, 2022
1 parent e2f137d commit 318d0e3
Show file tree
Hide file tree
Showing 25 changed files with 71 additions and 156 deletions.
24 changes: 8 additions & 16 deletions chapter_appendix-tools-for-deep-learning/sagemaker.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ SageMaker提供多个具有不同计算能力和价格的[实例类型](https://
我们可以指定此GitHub存储库URL( :numref:`fig_sagemaker-create-3`),以允许SageMaker在创建实例时克隆它。
:end_tab:

:begin_tab:`paddle`
用于与SageMaker一起运行的ipynb格式的整本书可从https://github.com/d2l-ai/d2l-paddle-sagemaker获得。
我们可以指定此GitHub存储库URL( :numref:`fig_sagemaker-create-3`),以允许SageMaker在创建实例时克隆它。
:end_tab:

![指定GitHub存储库](../img/sagemaker-create-3.png)
:width:`400px`
:label:`fig_sagemaker-create-3`
Expand Down Expand Up @@ -77,46 +72,43 @@ SageMaker提供多个具有不同计算能力和价格的[实例类型](https://
这本开源书的notebook将定期在GitHub上的[d2l-ai/d2l-tensorflow-sagemaker](https://github.com/d2l-ai/d2l-tensorflow-sagemaker)存储库中更新。要更新至最新版本,你可以在SageMaker实例( :numref:`fig_sagemaker-terminal`)上打开终端。
:end_tab:

:begin_tab:`paddle`
这本开源书的notebook将定期在GitHub上的[d2l-ai/d2l-paddle-sagemaker](https://github.com/d2l-ai/d2l-paddle-sagemaker)存储库中更新。要更新至最新版本,你可以在SageMaker实例( :numref:`fig_sagemaker-terminal`)上打开终端。
:end_tab:

![在SageMaker实例上打开终端](../img/sagemaker-terminal.png)
:width:`300px`
:label:`fig_sagemaker-terminal`

你可能希望在从远程存储库提取更新之前提交本地更改。否则,只需在终端中使用以下命令放弃所有本地更改:

:begin_tab:`mxnet`

```bash
cd SageMaker/d2l-en-sagemaker/
git reset --hard
git pull
```


:end_tab:

:begin_tab:`pytorch`

```bash
cd SageMaker/d2l-pytorch-sagemaker/
git reset --hard
git pull
```


:end_tab:

:begin_tab:`tensorflow`

```bash
cd SageMaker/d2l-tensorflow-sagemaker/
git reset --hard
git pull
```
:end_tab:

:begin_tab:`paddle`
```bash
cd SageMaker/d2l-paddle-sagemaker/
git reset --hard
git pull
```

:end_tab:

## 小结
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

## 选择服务器

通常不需要购买具有多个线程的高端CPU,因为大部分计算都发生在GPU上。这就是说,由于Python中的全局解释器锁(GIL),CPU的单线程性能在有4-8个GPU的情况下可能很重要。所有的条件都是一样的,这意味着核数较少但时钟频率较高的CPU可能是更经济的选择。例如,当在6核4GHz和8核3.5GHz CPU之间进行选择时,前者更可取,即使其聚合速度较低。一个重要的考虑因素是,GPU使用大量的功率,从而消耗大量的热量。这需要非常好的冷却和足够大的机箱来使用GPU。如有可能,请遵循以下指南:
通常不需要购买具有多个线程的高端CPU,因为大部分计算都发生在GPU上。这就是说,由于Python中的全局解释器锁(GIL),CPU的单线程性能在有4-8个GPU的情况下可能很重要。所有的条件都是一样的,这意味着核数较少但时钟频率较高的CPU可能是更经济的选择。例如,当在6核4GHz和8核3.5GHz CPU之间进行选择时,前者更可取,即使其聚合速度较低。一个重要的考虑因素是,GPU使用大量的电能,从而释放大量的热量。这需要非常好的冷却和足够大的机箱来容纳GPU。如有可能,请遵循以下指南:

1. **电源**。GPU使用大量的电源。每个设备预计高达350W(检查显卡的*峰值需求*而不是一般需求,因为高效代码可能会消耗大量能源)。如果电源不能满足需求,系统会变得不稳定。
1. **机箱尺寸**。GPU很大,辅助电源连接器通常需要额外的空间。此外,大型机箱更容易冷却。
Expand Down
20 changes: 6 additions & 14 deletions chapter_attention-mechanisms/bahdanau-attention.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,9 +262,9 @@ class Seq2SeqAttentionDecoder(AttentionDecoder):
self.attention = d2l.AdditiveAttention(
num_hiddens, num_hiddens, num_hiddens, dropout)
self.embedding = nn.Embedding(vocab_size, embed_size)
self.rnn = nn.GRU(
embed_size + num_hiddens, num_hiddens, num_layers,bias_ih_attr=True,time_major=True,
dropout=dropout)
self.rnn = nn.GRU(embed_size + num_hiddens, num_hiddens,
num_layers, bias_ih_attr=True,
time_major=True, dropout=dropout)
self.dense = nn.Linear(num_hiddens, vocab_size)
def init_state(self, enc_outputs, enc_valid_lens, *args):
Expand Down Expand Up @@ -295,8 +295,8 @@ class Seq2SeqAttentionDecoder(AttentionDecoder):
# 全连接层变换后,outputs的形状为
# (num_steps,batch_size,vocab_size)
outputs = self.dense(paddle.concat(outputs, axis=0))
return outputs.transpose((1, 0, 2)), [enc_outputs, hidden_state,
enc_valid_lens]
return outputs.transpose((1, 0, 2)), [enc_outputs, hidden_state,
enc_valid_lens]
@property
def attention_weights(self):
Expand Down Expand Up @@ -424,7 +424,7 @@ d2l.show_heatmaps(
```

```{.python .input}
#@tab pytorch
#@tab pytorch, paddle
# 加上一个包含序列结束词元
d2l.show_heatmaps(
attention_weights[:, :, :, :len(engs[-1].split()) + 1].cpu(),
Expand All @@ -438,14 +438,6 @@ d2l.show_heatmaps(attention_weights[:, :, :, :len(engs[-1].split()) + 1],
xlabel='Key posistions', ylabel='Query posistions')
```

```{.python .input}
#@tab paddle
# 加上一个包含序列结束词元
d2l.show_heatmaps(
attention_weights[:, :, :, :len(engs[-1].split()) + 1].cpu(),
xlabel='Key positions', ylabel='Query positions')
```

## 小结

* 在预测词元时,如果不是所有输入词元都是相关的,那么具有Bahdanau注意力的循环神经网络编码器-解码器会有选择地统计输入序列的不同部分。这是通过将上下文变量视为加性注意力池化的输出来实现的。
Expand Down
4 changes: 3 additions & 1 deletion chapter_attention-mechanisms/nadaraya-waston.md
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,9 @@ class NWKernelRegression(nn.Layer):
def forward(self, queries, keys, values):
# queries和attention_weights的形状为(查询个数,“键-值”对个数)
queries = queries.reshape((queries.shape[0], 1)).tile([keys.shape[1]]).reshape((-1, keys.shape[1]))
queries = queries.reshape((queries.shape[0], 1)) \
.tile([keys.shape[1]]) \
.reshape((-1, keys.shape[1]))
self.attention_weight = nn.functional.softmax(
-((queries - keys) * self.w)**2 / 2, axis=1)
# values的形状为(查询个数,“键-值”对个数)
Expand Down
3 changes: 2 additions & 1 deletion chapter_attention-mechanisms/transformer.md
Original file line number Diff line number Diff line change
Expand Up @@ -1103,7 +1103,8 @@ dec_attention_weights_2d = [head[0].tolist()
for attn in step for blk in attn for head in blk]
dec_attention_weights_filled = paddle.to_tensor(
pd.DataFrame(dec_attention_weights_2d).fillna(0.0).values)
dec_attention_weights = dec_attention_weights_filled.reshape((-1, 2, num_layers, num_heads, num_steps))
dec_attention_weights = dec_attention_weights_filled.reshape((
-1, 2, num_layers, num_heads, num_steps))
dec_self_attention_weights, dec_inter_attention_weights = \
dec_attention_weights.transpose((1, 2, 3, 0, 4))
dec_self_attention_weights.shape, dec_inter_attention_weights.shape
Expand Down
53 changes: 0 additions & 53 deletions chapter_computational-performance/async-computation.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,15 +191,6 @@ z
接下来看看这在实践中是如何运作的。
:end_tab:

:begin_tab:`paddle`
强制Python等待完成:

* 使用命令`paddle.device.cuda.synchronize()`等待该GPU设备上的所有计算完成。除非绝对必要,否则在实践中使用此运算符不是个好主意,因为它可能会导致较差的性能。
* 如果只想等待一个特定的变量可用,在飞桨中一般不需要考虑这个问题,因为飞桨系统内部会自动保证数据的同步和可用,我们只需要调用该变量即可。在单机多卡和多机多卡并行处理的时候,等待和确认所有计算完成是非常重要的问题。

让我们看看这在实践中是如何运作的。
:end_tab:

```{.python .input}
with d2l.Benchmark('waitall'):
b = np.dot(a, a)
Expand All @@ -210,28 +201,12 @@ with d2l.Benchmark('wait_to_read'):
b.wait_to_read()
```

```{.python .input}
#@tab paddle
with d2l.Benchmark('Wait for the calculation to complete'):
b = paddle.dot(a, a)
paddle.device.cuda.synchronize()
with d2l.Benchmark('Do not wait for calculation to complete'):
b = paddle.dot(a, a)
```

:begin_tab:`mxnet`
两个操作的完成时间大致相同。除了显式地阻塞操作之外,建议注意*隐式*的阻塞器。打印变量就是一个阻塞器,因为其要求变量可用。最后,通过`z.asnumpy()`转换为NumPy类型的变量和通过`z.item()`转换为标量也是阻塞器。因为NumPy中没有异步的概念,因此它需要像`print`函数(等待变量可用)一样访问这些值。

频繁地将少量数据从MXNet的作用域复制到NumPy,可能会破坏原本高效代码的性能,因为每一个这样的操作都需要使用计算图来求得所有的中间结果,从而获得相关项,然后才能做其他事情。
:end_tab:

:begin_tab:`paddle`
两个操作的完成时间还是能看出明显差别的。除了显式地阻塞操作之外,我们还建议要注意*隐式*的阻塞器。打印变量就是一个阻塞器,因为其要求变量可用。最后,通过`z.numpy()`转换为NumPy类型的变量和通过`z.item()`转换为标量也是阻塞器。

频繁地将少量数据从飞桨的作用域复制到NumPy,可能会破坏原本高效代码的性能,因为每一个这样的操作都需要使用计算图来求得所有的中间结果,从而获得相关项,然后才能做其它事情。
:end_tab:

```{.python .input}
with d2l.Benchmark('numpy conversion'):
b = np.dot(a, a)
Expand All @@ -242,27 +217,12 @@ with d2l.Benchmark('scalar conversion'):
b.sum().item()
```

```{.python .input}
#@tab paddle
with d2l.Benchmark('numpy conversion'):
b = paddle.dot(a, a)
b.numpy()
with d2l.Benchmark('scalar conversion'):
b = paddle.dot(a, a)
b.sum().item()
```

## 改进计算

:begin_tab:`mxnet`
在重度多线程的系统中(即使普通笔记本电脑也有4个或更多线程,然而在多插槽服务器上这个数字可能超过256),调度操作的开销可能会变得非常大。这也是极度希望计算和调度是异步和并行的原因。为了说明这样做的好处,让我们看看按顺序(同步执行)或异步执行多次将变量递增$1$会发生什么情况。这里通过在每个加法之间插入`wait_to_read`障碍器来模拟同步执行。
:end_tab:

:begin_tab:`paddle`
在重度多线程的系统中(即使普通笔记本电脑也有4个或更多线程,然而在多插槽服务器上这个数字可能超过256),调度操作的开销可能会变得非常大。这也是极度希望计算和调度是异步和并行的原因。为了说明这样做的好处,让我们看看按顺序(同步执行)或异步执行多次将变量递增$1$会发生什么情况。我们通过在每个加法之间插入`paddle.device.cuda.synchronize()`障碍器来同步执行。
:end_tab:

```{.python .input}
with d2l.Benchmark('synchronous'):
for _ in range(10000):
Expand All @@ -275,19 +235,6 @@ with d2l.Benchmark('asynchronous'):
npx.waitall()
```

```{.python .input}
#@tab paddle
with d2l.Benchmark('synchronous'):
for _ in range(10000):
y = x + 1
paddle.device.cuda.synchronize()
with d2l.Benchmark('asynchronous'):
for _ in range(10000):
y = x + 1
paddle.device.cuda.synchronize()
```

Python前端线程和C++后端线程之间的简化交互可以概括如下:

1. 前端命令后端将计算任务`y = x + 1`插入队列;
Expand Down
11 changes: 6 additions & 5 deletions chapter_computational-performance/hybridize.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,12 +309,13 @@ with Benchmark('Graph模式'):
```{.python .input}
#@tab paddle
net = get_net()
with Benchmark('Paddle动态图命令式编程'):
with Benchmark('飞桨动态图命令式编程'):
for i in range(1000): net(x)
# InputSpec用于描述模型输入的签名信息,包括shape、dtype和name
x_spec = InputSpec(shape=[-1, 512], name='x')
net = to_static(get_net(),input_spec=[x_spec])
with Benchmark('Paddle静态图符号式编程'):
net = paddle.jit.to_static(get_net(),input_spec=[x_spec])
with Benchmark('飞桨静态图符号式编程'):
for i in range(1000): net(x)
```

Expand All @@ -331,7 +332,7 @@ with Benchmark('Paddle静态图符号式编程'):
:end_tab:

:begin_tab:`paddle`
如以上结果所示,在`nn.Sequential`的实例被函数`paddle.jit.to_static`脚本化后,通过使用符号式编程提高了计算性能。事实上飞桨非常巧妙的实现了动静自然统一,完备实现了一键式动静转换,也就是只需要一条命令,就可以实现动静转换。
如以上结果所示,在`nn.Sequential`的实例被函数`paddle.jit.to_static`脚本化后,通过使用符号式编程提高了计算性能。
:end_tab:

### 序列化
Expand All @@ -348,7 +349,7 @@ with Benchmark('Paddle静态图符号式编程'):
编译模型的好处之一是我们可以将模型及其参数序列化(保存)到磁盘。这允许这些训练好的模型部署到其他设备上,并且还能方便地使用其他前端编程语言。同时,通常编译模型的代码执行速度也比命令式编程更快。在TensorFlow中保存模型的底层API是`tf.saved_model`,让我们来看看`saved_model`的运行情况。
:end_tab:

:begin_tab:`pytorch`
:begin_tab:`paddle`
编译模型的好处之一是我们可以将模型及其参数序列化(保存)到磁盘。这允许这些训练好的模型部署到其他设备上,并且还能方便地使用其他前端编程语言。同时,通常编译模型的代码执行速度也比命令式编程更快。让我们看看`paddle.jit.save`的实际功能。
:end_tab:

Expand Down
21 changes: 5 additions & 16 deletions chapter_computational-performance/multiple-gpus-concise.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def resnet18(num_classes, in_channels=1):
net.add_sublayer("resnet_block4", resnet_block(256, 512, 2))
net.add_sublayer("global_avg_pool", nn.AdaptiveAvgPool2D((1, 1)))
net.add_sublayer("fc", nn.Sequential(nn.Flatten(),
nn.Linear(512, num_classes)))
nn.Linear(512, num_classes)))
return net
```

Expand Down Expand Up @@ -297,8 +297,8 @@ def train(net, num_gpus, batch_size, lr):
trainer.step()
timer.stop()
animator.add(epoch + 1, (d2l.evaluate_accuracy_gpu(net, test_iter),))
print(f'test acc: {animator.Y[0][-1]:.2f}, {timer.avg():.1f} sec/epoch '
f'on {str(devices)}')
print(f'测试精度:{animator.Y[0][-1]:.2f}, {timer.avg():.1f}秒/轮,'
f'{str(devices)}')
```

接下来看看这在实践中是如何运作的。我们先[**在单个GPU上训练网络**]进行预热。
Expand Down Expand Up @@ -332,13 +332,7 @@ train(net, num_gpus=2, batch_size=512, lr=0.2)
* 优化算法在多个GPU上自动聚合。
:end_tab:

:begin_tab:`pytorch`
* 神经网络可以在(可找到数据的)单GPU上进行自动评估。
* 每台设备上的网络需要先初始化,然后再尝试访问该设备上的参数,否则会遇到错误。
* 优化算法在多个GPU上自动聚合。
:end_tab:

:begin_tab:`paddle`
:begin_tab:`pytorch, paddle`
* 神经网络可以在(可找到数据的)单GPU上进行自动评估。
* 每台设备上的网络需要先初始化,然后再尝试访问该设备上的参数,否则会遇到错误。
* 优化算法在多个GPU上自动聚合。
Expand All @@ -352,12 +346,7 @@ train(net, num_gpus=2, batch_size=512, lr=0.2)
1. 如果去掉`npx.waitall()`会怎样?该如何修改训练,以使并行操作最多有两个步骤重叠?
:end_tab:

:begin_tab:`pytorch`
1. 本节使用ResNet-18,请尝试不同的迭代周期数、批量大小和学习率,以及使用更多的GPU进行计算。如果使用$16$个GPU(例如,在AWS p2.16xlarge实例上)尝试此操作,会发生什么?
1. 有时候不同的设备提供了不同的计算能力,我们可以同时使用GPU和CPU,那应该如何分配工作?为什么?
:end_tab:

:begin_tab:`paddle`
:begin_tab:`pytorch, paddle`
1. 本节使用ResNet-18,请尝试不同的迭代周期数、批量大小和学习率,以及使用更多的GPU进行计算。如果使用$16$个GPU(例如,在AWS p2.16xlarge实例上)尝试此操作,会发生什么?
1. 有时候不同的设备提供了不同的计算能力,我们可以同时使用GPU和CPU,那应该如何分配工作?为什么?
:end_tab:
Expand Down
7 changes: 3 additions & 4 deletions chapter_computational-performance/multiple-gpus.md
Original file line number Diff line number Diff line change
Expand Up @@ -448,11 +448,10 @@ def train_batch(X, y, device_params, devices, lr):
allreduce(
[device_params[c][i].grad for c in range(len(devices))])
# 在每个GPU上分别更新模型参数
for item in range(len(device_params)):
paddle.set_device(f"gpu:{item}")
param = device_params[item]
for i in range(len(device_params)):
paddle.set_device(f"gpu:{i}")
param = device_params[i]
d2l.sgd(param, lr, X.shape[0]) # 在这里,我们使用全尺寸的小批量
```

现在,我们可以[**定义训练函数**]
Expand Down
4 changes: 2 additions & 2 deletions chapter_computer-vision/anchor.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,8 @@ def multibox_prior(data, sizes, ratios):
# 生成“boxes_per_pixel”个高和宽,
# 之后用于创建锚框的四角坐标(xmin,xmax,ymin,ymax)
w = paddle.concat((size_tensor * paddle.sqrt(ratio_tensor[0]),
sizes[0] * paddle.sqrt(ratio_tensor[1:])))\
* in_height / in_width # 处理矩形输入
sizes[0] * paddle.sqrt(ratio_tensor[1:])))\
* in_height / in_width # 处理矩形输入
h = paddle.concat((size_tensor / paddle.sqrt(ratio_tensor[0]),
sizes[0] / paddle.sqrt(ratio_tensor[1:])))
# 除以2来获得半高和半宽
Expand Down
2 changes: 1 addition & 1 deletion chapter_computer-vision/image-augmentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ def train_batch_ch13(net, X, y, loss, trainer, devices):
#@save
def train_batch_ch13(net, X, y, loss, trainer, devices):
"""用多GPU进行小批量训练
Paddle doesn't support multi gpu training on notebooks
飞桨不支持在notebook上进行多GPU训练
Defined in :numref:`sec_image_augmentation`"""
if isinstance(X, list):
# 微调BERT中所需(稍后讨论)
Expand Down
6 changes: 3 additions & 3 deletions chapter_computer-vision/kaggle-cifar10.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ transform_train = paddlevision.transforms.Compose([
# 生成一个面积为原始图像面积0.64到1倍的小正方形,
# 然后将其缩放为高度和宽度均为32像素的正方形
paddlevision.transforms.RandomResizedCrop(32, scale=(0.64, 1.0),
ratio=(1.0, 1.0)),
ratio=(1.0, 1.0)),
paddlevision.transforms.RandomHorizontalFlip(),
paddlevision.transforms.ToTensor(),
# 标准化图像的每个通道
Expand Down Expand Up @@ -343,10 +343,10 @@ train_iter, train_valid_iter = [paddle.io.DataLoader(
for dataset in (train_ds, train_valid_ds)]
valid_iter = paddle.io.DataLoader(valid_ds, batch_size=batch_size, shuffle=False,
drop_last=True)
drop_last=True)
test_iter = paddle.io.DataLoader(test_ds, batch_size=batch_size, shuffle=False,
drop_last=False)
drop_last=False)
```

## 定义[**模型**]
Expand Down
Loading

0 comments on commit 318d0e3

Please sign in to comment.