让我们看一下`forward`方法的工作方式。 `z_dim`维度的输入噪声向量经过全连接层以提供 12544 输出。 然后,我们将 12544 输出调整为`256 x 7 x 7`,其中 256 是通道数。 `256 x 7 x 7`张量然后通过反卷积层以提供`128 x 14 x 14`输出,然后通过具有 128 个特征和泄漏 ReLU 的`Batchnorm`层。 `128 x 14 x 14`然后在第二次反卷积中转换为`64 x 14 x 14`张量,在第三次反卷积中变为`1 x 28 x 28`张量; 这些只是我们需要的尺寸。 然后,我们创建生成器对象并将其移动到设备。
MXNet 服务器带有管理 API,该 API 通过 HTTP 提供。 这有助于生产团队根据需要增加/减少资源。 除了处理工人规模之外,管理 API 还具有其他选项。 但是我们不会在这里深入探讨。 由于模型服务器在 JVM 上运行,因此我们需要安装 Java8。此外,MXNet 模型服务器在 Windows 上仍处于试验模式,但在 Linux 风味和 Mac 上稳定。
MXNet 服务器带有管理 API,该 API 通过 HTTP 提供。 这有助于生产团队根据需要增加/减少资源。 除了处理工作器规模之外,管理 API 还具有其他选项。 但是我们不会在这里深入探讨。 由于模型服务器在 JVM 上运行,因此我们需要安装 Java8。此外,MXNet 模型服务器在 Windows 上仍处于试验模式,但在 Linux 风味和 Mac 上稳定。
@@ -79,7 +79,7 @@ TORCH_LIBRARY_IMPL(myops, CUDA, m) {
至此,我们有了一个同时具有 CPU 和 CUDA 实现的运算符。 我们如何为它添加 Autograd 支持? 您可能会猜到,我们将注册一个 Autograd 内核(类似于[自定义 Autograd 函数](cpp_autograd)教程中描述的内容)! 但是,有一个变数:与 CPU 和 CUDA 内核不同,Autograd 内核需要*重新分发*:它需要回调分派器才能到达最终的 CPU 和 CUDA 实现。
因此,在编写 Autograd 内核之前,让我们编写一个*调度函数*,该函数调用调度程序以为您的运算符找到合适的内核。 该函数构成了供您的运算符使用的公共 C++ API,实际上,PyTorch C++ API 中的所有张量函数都在后台完全以相同的方式调用了调度程序。 调度函数如下所示:
因此,在编写 Autograd 内核之前,让我们编写一个*调度函数*,该函数调用调度器以为您的运算符找到合适的内核。 该函数构成了供您的运算符使用的公共 C++ API,实际上,PyTorch C++ API 中的所有张量函数都在后台完全以相同的方式调用了调度器。 调度函数如下所示:
* 在第一行中,我们从调度程序中查找与要调度到的运算符相对应的类型化运算符句柄。 `findSchemaOrThrow`具有两个参数:运算符的(名称空间限定)名称和运算符的重载名称(通常只是空字符串)。 `typed`将动态类型的句柄转换为静态类型的句柄(进行运行时测试以确保您提供了正确的 C++ 类型),以便我们可以对其进行常规的 C++ 调用。 我们将其传递给`decltype(myadd)`,因为调度函数的类型与注册到调度程序的基础内核的类型相同。
* 在第一行中,我们从调度器中查找与要调度到的运算符相对应的类型化运算符句柄。 `findSchemaOrThrow`具有两个参数:运算符的(名称空间限定)名称和运算符的重载名称(通常只是空字符串)。 `typed`将动态类型的句柄转换为静态类型的句柄(进行运行时测试以确保您提供了正确的 C++ 类型),以便我们可以对其进行常规的 C++ 调用。 我们将其传递给`decltype(myadd)`,因为调度函数的类型与注册到调度器的基础内核的类型相同。