Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >CMU10-414/714 Deep Learning Systems 第二次作业hw1解析

CMU10-414/714 Deep Learning Systems 第二次作业hw1解析

作者头像
叶子的技术碎碎念
发布于 2025-04-08 13:52:13
发布于 2025-04-08 13:52:13
5100
代码可运行
举报
运行总次数:0
代码可运行

本周讲解dlsyscourse 的第二次作业,也就是hw1的部分。上周的内容主要是个warm up,熟悉一下环境以及一些简单的代码,本周要开始实现一个基础的自动微分框架needle。同样本周作业也放到了 https://github.com/careywyr/dlsyscourse ,colab的题目也翻译成了中文方便阅读,代码里面也移除了关于mugrade的部分,建议先自己做一遍,这样会更有收获。

关于needle框架的介绍在问题1的前面已经给出了描述,具体要注意的就是下面几个关键类:

  • Value: 计算图中的一个值,可能是通过对其他Value对象的操作计算得出,或者是常量(叶子)Value对象。我们使用了一个通用类(后续版本中可以专门化为其他数据结构,例如张量Tensor),但目前你主要会通过其子类Tensor进行交互(详见下文)。
  • Op: 计算图中的一个算子。算子需要在compute()方法中定义其前向传播(即如何基于Value对象的数据计算运算结果),并通过gradient()方法定义其反向传播,用于处理传入的输出梯度。编写这些算子的详细信息将在下文中提供。
  • Tensor: Value类的一个子类,表示计算图中的一个多维数组输出(张量)。在本次作业以及后续的作业中,你将主要使用Tensor这个Value的子类。我们提供了多个便捷函数(例如运算符重载),这些函数使你能够像正常使用Python中的操作符那样来操作张量,但在实现相应操作之前,这些便捷函数不会正常工作。
  • TensorOp: Op类的一个子类,专门用于返回张量的运算符。你将在本次作业中实现的所有操作都是这种类型。

那么基于上面的基础类,来完成本次的作业。

问题1:实现前向计算(略)

这一题要在 ops_mathematic 这个文件里实现所有类的 compute() 方法,这个应该是这次作业最简单的一题了,没有太多需要介绍的,就是按照公式使用numpy的方法即可。

问题2:反向传播

为了实现计算图的自动微分,那就要计算反向传播,即将函数的导数和传入的反向的梯度相乘。在题目的介绍中给了逐元素加法EWiseAdd和逐元素乘法EWiseMul运算的反向传播的实现。

  • • 对于 f(x,y) = x + y. 它对于x或者y的偏导均是1,因此它的梯度就是1乘以反向传播的梯度,还是其本身。
  • • 对于 f(x,y) = x \circ y 。它对于x或者y的偏导分别是另一半,即 y 和 x 。那么反向传播的结果就是 out_grad * y 以及 out_grad * x

那么这次作业其实就是完成剩下的那些方法的梯度计算。其实绝大部分都是简单的,只要掌握常见基本函数求导的基本公式即可,主要要说明的是下面几个方法:

  • • transpose
  • • reshape
  • • broadcast
  • • summation
  • • matmul
  • • ReLU Transpose 对于转置,前向传播的时候是将输入按照axes进行翻转,默认是-1,-2轴,反向传播就是将其翻转回来,所以代码如下:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def gradient(self, out_grad, node):
    if self.axes:
        x, y = self.axes[0], self.axes[1]
    else:
        # 如果 axes 是 None,默认交换最后两个轴
        x, y = -1, -2
    return transpose(out_grad, axes=(x, y))

Reshape

Reshape和转置类似,就是将梯度形状还原:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def gradient(self, out_grad, node):
    ### BEGIN YOUR SOLUTION
    # 将梯度 reshape 成原来的形状
    return reshape(out_grad, node.inputs[0].shape)
    ### END YOUR SOLUTION

Broadcast

广播就有点费劲了,广播前向计算的时候实际上会将张量的维度扩展,比如从(1,n)扩展到(m,n),那么反向传播的时候,需要将梯度压缩回(1,n)。具体来说,就是对第一个维度进行求和。那么就是:

  • • 对于那些被广播的维度,在反向传播时需要对这些维度进行求和。
  • • 对于那些没有被广播的维度,梯度会直接传递下去,不需要特殊处理。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def gradient(self, out_grad, node):
    lhs_shape = node.inputs[0].shape  # 原始输入的形状
    output_shape = self.shape  # 广播后的目标形状

# 如果输入形状和输出形状相同,说明没有发生广播,直接返回 out_grad
if lhs_shape == output_shape:
return out_grad

# 计算输入和输出形状的维度差,处理输入比输出少的维度情况
    ndim_diff =len(output_shape)-len(lhs_shape)

# 需要缩减的维度
    reduce_axes =[]

# 遍历输出张量的每个维度,找到需要缩减的维度
for i inrange(len(output_shape)):
# 计算对应的输入维度,如果是补上去的(即左边加 1),则视为 1
        input_dim = lhs_shape[i - ndim_diff]if i >= ndim_diff else1
        output_dim = output_shape[i]

# 如果输入维度为 1,而输出维度大于 1,则需要在该轴进行求和
if input_dim ==1and output_dim !=1:
            reduce_axes.append(i)

# 如果 reduce_axes 非空,执行 sum 操作以消除广播的影响
if reduce_axes:
# out_grad = array_api.sum(out_grad.numpy(), axis=tuple(reduce_axes))
        out_grad = summation(out_grad, axes=tuple(reduce_axes))

# reshape 回原始输入的形状
return reshape(out_grad, lhs_shape)

Sum

对于sum操作的反向传播,首先要考虑sum前向计算的时候带来的后果是什么?它在某些维度上进行了累加,那就意味着这些维度消失了,反向传播的时候需要把这些维度分配回来。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def gradient(self, out_grad, node):
    lhs = node.inputs[0]
    input_shape = lhs.shape  # 原始张量的形状

if out_grad.shape ==():
        out_grad = array_api.full_like(lhs.numpy(), out_grad.numpy())

if self.axes isNone:
# 如果没有指定轴,意味着我们对整个张量求和,结果是一个标量
return broadcast_to(ndl.Tensor(out_grad), input_shape)

    out_grad = out_grad.numpy()ifisinstance(out_grad,Tensor)else out_grad

# 为 out_grad 恢复被求和的维度
if out_grad.shape != input_shape:
for axis insorted(self.axes, reverse=True):
          out_grad = array_api.expand_dims(out_grad, axis)

# 扩展为原始输入的形状
    result = broadcast_to(ndl.Tensor(out_grad), input_shape)
return result

MatMul

对于矩阵乘法,其实如果两者的维度是一样的,那么就跟求xy的偏导区别不大,顶多就是注意一下要进行转置,一个是out_grad * y^T ,一个是 x^T * out_grad。 但要考虑一个问题,就是x和y的维度可能不一致,因为不一致并不代表不能进行矩阵乘法,只要x的最后一个维度和y的第一个维度一样即可。所以反向的时候正如上面的broadcast,这里也要sum一下。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def gradient(self, out_grad, node):
    lhs, rhs = node.inputs

# 始终使用批量矩阵乘法的逻辑
    grad_lhs = matmul(out_grad, transpose(rhs, axes=(-2,-1)))
    grad_rhs = matmul(transpose(lhs, axes=(-2,-1)), out_grad)

# 处理广播的维度
iflen(lhs.shape)<len(rhs.shape):
        axes_to_sum =tuple(range(len(rhs.shape)-len(lhs.shape)))
        grad_lhs = summation(grad_lhs, axes=axes_to_sum)
iflen(rhs.shape)<len(lhs.shape):
        axes_to_sum =tuple(range(len(lhs.shape)-len(rhs.shape)))
        grad_rhs = summation(grad_rhs, axes=axes_to_sum)

return grad_lhs, grad_rhs

ReLU

对于ReLU函数,前向传播就是max(0, x),其实就是个分段函数,那么对于两段的梯度分别是1和0。然后跟out_grad相乘即可。代码实现上可以创建一个新的Tensor方便进行计算:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def gradient(self, out_grad, node):
    lhs = node.inputs[0]
    np_lhs = lhs.numpy()
    # 创建一个掩码:lhs > 0 的位置为 1,其他位置为 0
    grad_mask = array_api.where(np_lhs > 0, 1, 0)
    # 将 out_grad 和 grad_mask 相乘,得到最终的梯度
    return out_grad * ndl.Tensor(grad_mask)

问题3:拓扑排序(Topological Sort)

这一题就是图的排序,不过要确保执行的是后序深度优先搜索(Post-order Depth-First Search, DFS),它的意思是在访问某个节点之前,先递归地访问它的所有子节点或相邻节点,直到所有路径都被遍历完毕,再回溯并记录当前节点。 比如假设有这样一个有向无环图:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    A
   / \
  B   C
 / \   \
D   E   F

通过DFS排序后,结果是DEBFCA。大致逻辑是:

  • • 选择一个未访问的起始节点作为起点。
  • • 将该节点标记为已访问。
  • • 对于该节点的每一个未访问相邻节点,递归执行后序深度优先搜索。
  • • 当所有相邻节点都访问完毕后,将当前节点加入遍历结果。

题目中给出了两个待实现的方法,find_topo_sorttopo_sort_dfs ,其中 topo_sort_dfs 是用来当做递归辅助的函数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def find_topo_sort(node_list: List[Value])->List[Value]:
    visited =set()# 用于记录已访问过的节点
    topo_order =[]# 存储拓扑排序的结果

# 遍历节点列表,执行 DFS
for node in node_list:
if node notin visited:
            topo_sort_dfs(node, visited, topo_order)

# 返回拓扑排序的结果,由于我们在 DFS 中是后序添加节点的,因此需要反转
return topo_order

deftopo_sort_dfs(node, visited, topo_order):
"""Post-order DFS"""
# 如果当前节点已经访问过,直接返回
if node in visited:
return
    visited.add(node)# 标记当前节点为已访问

# 遍历所有前驱节点(即指向当前节点的节点),递归执行DFS
for predecessor in node.inputs:
if predecessor notin visited:
            topo_sort_dfs(predecessor, visited, topo_order)

# 在所有前驱节点都被访问后,将当前节点加入到拓扑排序的结果中
    topo_order.append(node)

问题4:实现反向自动微分

这一题需要参考课件里面的关于反向微分计算的伪码:

要实现的方法实际上是要计算神经网络中每个节点(变量)的梯度,即最终输出张量对每个节点的梯度。那么按照图中的描述,大致如下几个步骤:

  1. 1. 初始化字典来存储各节点的梯度(Dictionary that records a list of partial adjoints of each node)
  2. 2. 反向遍历图中的节点(就是reverse上一题的list)
  3. 3. 遍历节点并计算梯度
    1. 1. 遍历节点
    2. 2. 累加该节点的梯度 (Sum up partial adjoints)
    3. 3. 计算梯度
    4. 4. 遍历inputs将梯度放进去(Propagate gradients to input nodes)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def compute_gradient_of_variables(output_tensor, out_grad):
"""Take gradient of output node with respect to each node in node_list.

    Store the computed result in the grad field of each Variable.
    """
# Step 1: Dictionary that records a list of partial adjoints of each node
    node_to_grad ={output_tensor:[out_grad]}

# Step 2: Traverse nodes in reverse topological order (i.e., from output to input)
    reverse_topo_order =list(reversed(find_topo_sort([output_tensor])))

for node in reverse_topo_order:
# Step 3: Sum up partial adjoints        
        v_i = sum_node_list(node_to_grad[node])
# Step 4: Store the computed gradient in the node's grad field
        node.grad = v_i
if node.is_leaf():
continue
        gradient = node.op.gradient_as_tuple(v_i, node)
# Step 5: Propagate gradients to input nodes
for i, node1 inenumerate(node.inputs):
ifnot node_to_grad.get(node1):
              node_to_grad[node1]=[]
            node_to_grad[node1].append(gradient[i])

问题5:计算Softmax Loss

对于要实现方法的输入输出如下:

  • Z: 一个 2D Tensor,形状为 (batch_size, num_classes),包含每个类的logit(未归一化的预测值)
  • y_one_hot: 一个 2D Tensor,形状为 (batch_size, num_classes),表示one-hot 编码的真实标签
  • • 返回的是一个标量 Tensor,表示平均的 softmax 损失

对于损失的数学公式定义为:

\ell_{\mathrm{softmax}}(z, y) = \log\sum_{i=1}^k \exp z_i - z_y.

那么我们可以将步骤分解成如下几步:

  1. 1. 对每个样本的logits取指数求和
  2. 2. 提取每个样本真实标签的logit值
  3. 3. 求loss,记得除以batch
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def softmax_loss(Z, y_one_hot):
    exp_sum_z = ndl.summation(ndl.exp(Z), axes=(-1,))
    b = Z.shape[0]
    z_y = ndl.summation(ndl.multiply(Z, y_one_hot), axes=(-1,))
    loss = ndl.summation(ndl.log(exp_sum_z) - z_y) / b
    return loss

问题6:两层神经网络的SGD

这一题跟hw0中的nn_epoch类似,不同的是输入的W1和W2是 Tensors,此外上次是手动推导两层网络的反向传播方差,这次实现了自动微分的方法,因此可以直接使用backward() 方法计算梯度。要注意的就是要使用needle里面的方法,要使得参数是Tensor

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def nn_epoch(X, y, W1, W2, lr=0.1, batch=100):
    num_examples, input_dim = X.shape
    _, num_classes = W2.shape
for i inrange(0, num_examples, batch):
        X_batch = X[i:i + batch]
        y_batch = y[i:i + batch]
        x = ndl.Tensor(X_batch)

        y_one_hot = np.zeros((y_batch.size, num_classes))
        y_one_hot[np.arange(y_batch.size), y_batch]=1
        y_tensor = ndl.Tensor(y_one_hot)

        Z = ndl.matmul(ndl.relu(ndl.matmul(x, W1)), W2)
        loss = softmax_loss(Z, y_tensor)
        loss.backward()

        W1 = ndl.Tensor(W1.numpy()- lr * W1.grad.numpy())
        W2 = ndl.Tensor(W2.numpy()- lr * W2.grad.numpy())
return W1, W2

本次作业因为很多地方不再是使用NDArray,而是有时候是Tensor,写的时候经常分不清某个变量到底是个啥类型,所以其实我写的代码是有一些模糊的,虽然功能是实现了,但觉得并不是最优雅的写法,因此仅供参考,相信很多同学可以写出更好的方案。

你好,我是叶子,7年Java开发老司机,待过小的创业公司也待过上市厂子。擅长各种姿势的CRUD,但现在工作重心逐渐往中间件开发转移。喜欢折腾技术,AI是个人爱好驱动去学习的。但不管是Java还是AI还是其他非技术行业的知识,我都希望能和大家共同学习进步,如果文章有用,还请大家点击关注,希望我们能一起在技术的道路上走的更远!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-10-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 叶子的技术碎碎念 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
CMU10-414/714 Deep Learning Systems 第一次作业解析
最近要开始刷CMU的 10-414/714: Deep Learning Systems (https://dlsyscourse.org/) 这门课了,之前其实就看了个开头,因为自己就是希望未来可以多研究研究关于System方面的内容,因此这门课可以说是必须刷的了。目前只看了前面5节的内容,已经足以做第一次的作业了。因此开了个仓库(https://github.com/careywyr/dlsyscourse)用来管理作业了,官方的是每次作业都单独一个库,自己学的话还是放一块比较方便,而且因为现在官方已经不提供评分系统的注册渠道了,因此作业里面的关于分数提交的内容已经没用了,本人在作业模板里把相关的代码都删掉了,这样只保留实际作业相关的题目,会比较适合阅读但实际并不影响代码测试。除此之外我还将作业里面的内容翻译成了中文,也是为了方便学习的时候看着方便。
叶子的技术碎碎念
2025/04/08
520
CMU10-414/714 Deep Learning Systems 第一次作业解析
机器学习系统SyeML笔记三——自动微分
这篇文章先介绍一下自动微分吧,这一个月来对我来说真的是多事之秋,能遇上的各种事情几乎都遇上了,但愿生活节奏和工作方面能够慢慢平稳下来。
老潘
2023/10/19
3880
机器学习系统SyeML笔记三——自动微分
[源码解析] PyTorch如何实现前向传播(3) --- 具体实现
本系列将通过大概十篇左右文章来分析 PyTorch 的自动微分功能如何实现。本文是前向传播的第三篇,介绍具体实现机制。
罗西的思考
2021/10/26
1.3K0
手把手开发一个深度学习框架(Python)
当前深度学习框架越来越成熟(如Keras、Pytorch、TensorFlow等等),对于使用者而言封装程度越来越高,好处就是现在可以非常快速地将这些框架作为工具使用,用非常少的代码就可以构建模型进行实验,坏处就是可能背后地实现都被隐藏起来了。
算法进阶
2023/11/22
3500
手把手开发一个深度学习框架(Python)
Deep Learning with PyTorch > A Gentle Introduction to torch.autograd
torch.autograd is PyTorch’s automatic differentiation engine that powers neural network training. In this section, you will get a conceptual understanding of how autograd helps a neural network train.
望天
2024/06/07
1930
Deep Learning with PyTorch > A Gentle Introduction to torch.autograd
NumPyML 源码解析(二)
The activations module implements several common activation functions:
ApacheCN_飞龙
2024/02/17
1970
[源码解析]深度学习利器之自动微分(3) --- 示例解读
本文从 PyTorch 两篇官方文档开始为大家解读两个示例。本文不会逐句翻译,而是选取重点并且试图加入自己的理解。
罗西的思考
2021/10/20
1.4K0
[Deep-Learning-with-Python]神经网络的数学基础
理解深度学习需要熟悉一些简单的数学概念:Tensors(张量)、Tensor operations 张量操作、differentiation微分、gradient descent 梯度下降等等。
用户1631856
2018/08/01
1.3K1
【他山之石】Pytorch学习笔记
“他山之石,可以攻玉”,站在巨人的肩膀才能看得更高,走得更远。在科研的道路上,更需借助东风才能更快前行。为此,我们特别搜集整理了一些实用的代码链接,数据集,软件,编程技巧等,开辟“他山之石”专栏,助你乘风破浪,一路奋勇向前,敬请关注。
马上科普尚尚
2021/11/16
1.6K0
TensorFlow 高效编程
TensorFlow 和其他数字计算库(如 numpy)之间最明显的区别在于 TensorFlow 中操作的是符号。这是一个强大的功能,这保证了 TensorFlow 可以做很多其他库(例如 numpy)不能完成的事情(例如自动区分)。这可能也是它更复杂的原因。今天我们来一步步探秘 TensorFlow,并为更有效地使用 TensorFlow 提供了一些指导方针和最佳实践。
ApacheCN_飞龙
2022/12/02
1.6K0
【动手学深度学习】深入浅出深度学习之PyTorch基础
启动jupyter notebook,使用新增的pytorch环境新建ipynb文件,为了检查环境配置是否合理,输入import torch以及torch.cuda.is_available() ,若返回TRUE则说明实验环境配置正确,若返回False但可以正确导入torch则说明pytorch配置成功,但实验运行是在CPU进行的,结果如下:
SarPro
2024/04/02
4390
【动手学深度学习】深入浅出深度学习之PyTorch基础
动手学DL——深度学习预备知识随笔【深度学习】【PyTorch】
多加一个括号,结果都是一致的,都是表示二维张量,张量形状都是(4,9),所以二维有两种写法,但再加一层括号,形状就变成了(1,4,9)三维,判断维数技巧:最外面的括号去掉开始数,比如:
来杯Sherry
2023/07/24
4010
动手学DL——深度学习预备知识随笔【深度学习】【PyTorch】
NumPyML 源码解析(六)
ApacheCN_飞龙
2024/02/17
2850
[源码解析] 深度学习流水线并行 GPipe(3) ----重计算
GPipe是一个基于 Lingvo (Lingvo 是 Google 基于 TensorFlow 二次开发的重点针对序列模型的框架)开发的,支持超大规模模型的神经网络训练并行库,本文介绍其重计算功能,同时可以和其他实现一起印证。
罗西的思考
2021/09/08
1.1K0
使用腾讯云 GPU 学习深度学习系列之二:Tensorflow 简明原理
本文介绍了如何通过C++代码实现一个基本的轮子,包括轮子中的各个组件,以及如何使用Tensorflow框架进行模型的训练和推理。同时,本文还介绍了一个基于云服务器的GPU集群的搭建过程,以及如何使用Python编程语言进行编程。本文的内容详实,深入浅出,适合对深度学习有兴趣,同时有一定的Linux系统基础和编程基础的读者阅读。
集智
2017/05/14
2.8K2
[源码解析]PyTorch如何实现前向传播(2) --- 基础类(下)
本系列将通过大概十篇左右文章来分析 PyTorch 的自动微分功能如何实现。本文是前向传播的第二篇,介绍自动微分(梯度计算)所涉及的部分 PyTorch 基础类。因为字数太多(1万两千字),所以拆分成上下两篇。
罗西的思考
2021/10/21
1.2K0
【Pytorch 】笔记二:动态图、自动求导及逻辑回归
疫情在家的这段时间,想系统的学习一遍 Pytorch 基础知识,因为我发现虽然直接 Pytorch 实战上手比较快,但是关于一些内部的原理知识其实并不是太懂,这样学习起来感觉很不踏实, 对 Pytorch 的使用依然是模模糊糊, 跟着人家的代码用 Pytorch 玩神经网络还行,也能读懂,但自己亲手做的时候,直接无从下手,啥也想不起来, 我觉得我这种情况就不是对于某个程序练得不熟了,而是对 Pytorch 本身在自己的脑海根本没有形成一个概念框架,不知道它内部运行原理和逻辑,所以自己写的时候没法形成一个代码逻辑,就无从下手。这种情况即使背过人家这个程序,那也只是某个程序而已,不能说会 Pytorch, 并且这种背程序的思想本身就很可怕, 所以我还是习惯学习知识先有框架(至少先知道有啥东西)然后再通过实战(各个东西具体咋用)来填充这个框架。而「这个系列的目的就是在脑海中先建一个 Pytorch 的基本框架出来, 学习知识,知其然,知其所以然才更有意思 :)」。
阿泽 Crz
2020/08/28
1.8K0
【Pytorch 】笔记二:动态图、自动求导及逻辑回归
半小时学会 PyTorch Hook
提到 hook,我首先想起的是动画《小飞侠》里滑稽的 captain hook,满满童年的回忆促使我 P 了张题图:虎克船长勾着 PyTorch 的 logo。同时想起的还有大名鼎鼎的胡克定律:Hooke's law(虽然不是一个 hook),当年上物理实验课,看着弹簧测力计下面的钩子,联想到胡克被牛顿爵士打压的悲惨一生,不由发出既生胡何生牛的唏嘘……然而本文将介绍的是 PyTorch 中的 hook。
SIGAI学习与实践平台
2019/07/30
4.1K1
半小时学会 PyTorch Hook
【他山之石】适合PyTorch小白的官网教程:Learning PyTorch With Examples
“他山之石,可以攻玉”,站在巨人的肩膀才能看得更高,走得更远。在科研的道路上,更需借助东风才能更快前行。为此,我们特别搜集整理了一些实用的代码链接,数据集,软件,编程技巧等,开辟“他山之石”专栏,助你乘风破浪,一路奋勇向前,敬请关注。
马上科普尚尚
2020/12/03
5750
【他山之石】适合PyTorch小白的官网教程:Learning PyTorch With Examples
干货 | PyTorch相比TensorFlow,存在哪些自身优势?
1、 PyTorch 课替代NumPy 使用:PyTorch 本身主要构件是张量——和 NumPy 看起来差不多。使得 PyTorch 可支持大量相同的 API,有时候可以把它用作是 NumPy 的替代品。PyTorch 的开发者们这么做的原因是希望这种框架可以完全获得 GPU 加速带来的便利,以便你可以快速进行数据预处理,或其他任何机器学习任务。将张量从 NumPy 转换至 PyTorch 非常容易,反之亦然。看看如下代码: import torch import numpy as np numpy_t
IT派
2018/03/28
3.5K0
干货 | PyTorch相比TensorFlow,存在哪些自身优势?
推荐阅读
相关推荐
CMU10-414/714 Deep Learning Systems 第一次作业解析
更多 >
LV.0
这个人很懒,什么都没有留下~
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验