当前位置: 首页 > news >正文

网站建设找哪个好计算机网络技术就业方向工资

网站建设找哪个好,计算机网络技术就业方向工资,app开发公司的困难,素材模板网站张量 文章目录 张量torch.Tensor 的 主要属性torch.Tensor 的 其他常用属性和方法叶子张量#xff08;Leaf Tensors#xff09;定义叶子张量的约定深入理解示例代码总结 中间计算结果与 detach() 方法定义中间计算结果不是叶子节点使用 detach() 方法使中间结果成为叶子张量示…张量 文章目录 张量torch.Tensor 的 主要属性torch.Tensor 的 其他常用属性和方法叶子张量Leaf Tensors定义叶子张量的约定深入理解示例代码总结 中间计算结果与 detach() 方法定义中间计算结果不是叶子节点使用 detach() 方法使中间结果成为叶子张量示例代码实际应用总结 关于 requires_grad 的说明例子 直接创建张量的操作解释与应用 梯度 requires_grad关于张量是否计算梯度是否开启梯度计算 reshape/view张量连续的概念 参考 tensor是一个类我们先来认识它有哪些属性再去观察它有哪些方法函数可使用。 Tensor主要有以下八个主要属性datadtypeshapedevicegradgrad_fnis_leafrequires_grad。 torch.Tensor 的 主要属性 data: 包含张量的原始数据不包含梯度信息。如果你不关心梯度只关心张量的数据本身可以通过 tensor.data 访问。 dtype: 张量的数据类型如 torch.float32、torch.int64 等。可以通过 tensor.dtype 查看或指定张量的数据类型。 shape: 张量的形状也称为尺寸表示每个维度的大小。可以通过 tensor.shape 或 tensor.size() 获取。 device: 表示张量所在的设备如 cpu 或 cuda:0第一个GPU。可以通过 tensor.device 获取张量所在的设备。 requires_grad: 如果 True表示张量需要计算梯度在反向传播时会记录操作以便计算梯度。可以通过 tensor.requires_grad 设置或检查。 grad: 存储与张量关联的梯度信息在反向传播之后会填充该值。可以通过 tensor.grad 访问通常用于更新模型参数。 grad_fn: 记录创建张量的 Function函数是创建该张量的操作的历史。对于叶子节点张量is_leafTruegrad_fn 为 None因为它们不是通过某个操作计算得到的。 is_leaf: 如果张量是计算图中的叶子节点则 is_leafTrue。通常叶子节点是由用户创建的且 requires_gradTrue没有使用运算符对它们进行进一步的计算。 torch.Tensor 的 其他常用属性和方法 ndim: 返回张量的维度数即张量的秩。 T: 返回张量的转置对于2D张量来说相当于矩阵转置。 numel(): 返回张量中元素的总数。 stride(): 返回张量在每个维度上的步长。 storage(): 返回底层存储对象。 contiguous(): 返回一个内存连续的相同张量。如果张量在内存中不是连续的这个方法会返回一个连续的副本。 to(device): 将张量移动到指定设备如 CPU 或 GPU。 detach(): 创建一个与当前计算图分离的新张量不会参与梯度计算。 clone(): 创建张量的深拷贝。 item(): 对于单元素张量返回其 Python 标量值。 numpy(): 将张量转换为 NumPy 数组仅在张量位于 CPU 上时可用。 size(): 返回张量的形状等同于 shape。 view() 或 reshape(): 改变张量的形状view() 要求张量的内存是连续的而 reshape() 则不需要。 squeeze() 和 unsqueeze(): squeeze() 移除张量中所有大小为1的维度。unsqueeze() 在指定位置插入一个大小为1的新维度。 cpu() 和 cuda(): cpu() 将张量移动到 CPU。cuda() 将张量移动到 GPU。 backward(): 计算梯度通常在损失张量上调用。 retain_grad(): 对非叶节点也保留梯度默认情况下只有叶节点的梯度被保留。 register_hook(): 注册一个反向传播的钩子函数在计算梯度时调用可以用于调试或修改梯度。 以下是关于 PyTorch 中 叶子张量 和 中间计算结果 的整理总结。 叶子张量Leaf Tensors 定义 在 PyTorch 的自动求导机制中叶子张量 是计算图中的最基础的节点或源节点它们通常由用户直接创建并且不会通过任何操作进一步派生出新的张量。 叶子张量: 是计算图中不依赖其他张量的张量。通常是通过直接创建张量的操作例如 torch.tensor()、torch.randn() 等生成的。叶子张量通常代表模型的输入数据或参数。 叶子张量的约定 “All Tensors that have requires_grad which is False will be leaf Tensors by convention.” 这句话的意思是 按照惯例所有 requires_gradFalse 的张量都被视为叶子张量。 深入理解 叶子张量Leaf Tensors 在 PyTorch 的计算图中叶子张量是那些不是由其他张量通过操作创建的张量。它们通常是直接创建的或者是模型的参数。 requires_grad 这个属性表示是否需要为该张量计算梯度。当 requires_gradTrue 时PyTorch 会跟踪对该张量的所有操作以便后续进行自动微分。 约定Convention 这是 PyTorch 的一个设计决定不是技术上的必然结果但它简化了计算图的管理和梯度计算。 示例代码 import torch# 创建 requires_gradFalse 的张量叶子节点 x torch.randn(3) print(x is leaf:, x.is_leaf) # True print(x requires grad:, x.requires_grad) # False# 创建 requires_gradTrue 的张量也是叶子节点 y torch.randn(3, requires_gradTrue) print(y is leaf:, y.is_leaf) # True print(y requires grad:, y.requires_grad) # True# 进行操作创建非叶子节点 z x y print(z is leaf:, z.is_leaf) # False print(z requires grad:, z.requires_grad) # True# 使用 detach() 创建新的叶子节点 w z.detach() print(w is leaf:, w.is_leaf) # True print(w requires grad:, w.requires_grad) # False总结 叶子张量: 通常是由用户直接创建的不依赖其他张量。默认情况下requires_gradFalse 的张量会被视为叶子张量。非叶子张量: 是通过其他张量的操作生成的requires_gradTrue 的张量如果不是直接创建的张量而是通过计算生成的则不是叶子张量。 中间计算结果与 detach() 方法 定义 中间计算结果 是通过对叶子张量进行操作生成的张量。它们通常不是叶子张量除非使用 detach() 方法将它们从计算图中分离出来。 中间计算结果不是叶子节点 当我们对叶子张量进行操作时生成的中间计算结果会被记录在计算图中。这些结果通常是非叶子张量因为它们依赖于前面的操作和张量。 使用 detach() 方法使中间结果成为叶子张量 如果你希望将一个中间计算结果从计算图中分离出来使其成为叶子张量可以使用 detach() 方法。detach() 方法返回一个新的张量与原始张量共享数据但不会记录在计算图中因此不会参与梯度计算。 示例代码 import torch# 创建叶子张量 x torch.tensor([1.0, 2.0, 3.0], requires_gradTrue)# 对叶子张量进行操作生成非叶子张量 y x 2# 使用 detach() 使 y_detach 成为叶子张量 y_detach y.detach()print(y is leaf:, y.is_leaf) # False print(y_detach is leaf:, y_detach.is_leaf) # True# 检查 y_detach 是否记录计算历史 print(y requires grad:, y.requires_grad) # True print(y_detach requires grad:, y_detach.requires_grad) # False实际应用 使用 detach() 有多个应用场景 冻结模型的一部分在训练时冻结某些层的参数防止这些参数的梯度被计算和更新。防止梯度传播在反向传播中有时希望切断某些部分的梯度传播可以使用 detach()。生成中间结果用于其他目的例如在某些自定义损失函数或正则化过程中需要从计算图中提取中间结果。 总结 中间计算结果通常不是叶子节点因为它们依赖于前面的操作和张量。detach() 方法可以将中间结果从计算图中分离出来使其成为叶子张量并且不再计算梯度。 关于 requires_grad 的说明 如果一个张量的 requires_gradFalse意味着我们不需要对其计算梯度。在大多数情况下这样的张量是叶子张量。反之如果一个张量的 requires_gradTrue并且是通过其他张量的操作生成的比如 a b c其中 b.requires_gradTrue那么 a 不是叶子张量因为它是通过操作生成的依赖于 b 和 c。 例子 import torch# 直接创建的张量requires_gradFalse因此是叶子张量 x torch.tensor([1.0, 2.0, 3.0]) print(x is leaf:, x.is_leaf) # True# 直接创建的张量requires_gradTrue因此是叶子张量 y torch.tensor([1.0, 2.0, 3.0], requires_gradTrue) print(y is leaf:, y.is_leaf) # True# 通过操作创建的张量requires_gradTrue因此不是叶子张量 z y 2 print(z is leaf:, z.is_leaf) # False# 使用 detach 创建的张量requires_gradFalse是叶子张量 z_detach z.detach() print(z_detach is leaf:, z_detach.is_leaf) # True直接创建张量的操作 当然下面是一个表格列出了常见的用于直接创建张量的 PyTorch 函数和方法。每个方法都会创建一个新的张量默认情况下这些张量的 requires_gradFalse并且它们是计算图中的叶子节点。 函数/方法描述示例torch.tensor()从数据创建张量可以指定数据类型。x torch.tensor([1, 2, 3])torch.arange()创建一个包含从开始值到结束值不包含结束值的等差序列的张量。x torch.arange(0, 10, 2)torch.linspace()创建一个包含在指定区间内均匀分布数值的张量。x torch.linspace(0, 1, steps5)torch.zeros()创建一个所有元素都为0的张量。x torch.zeros(3, 3)torch.ones()创建一个所有元素都为1的张量。x torch.ones(3, 3)torch.full()创建一个所有元素都为指定值的张量。x torch.full((2, 2), 7)torch.eye()创建一个单位矩阵对角线为1其他位置为0。x torch.eye(3)torch.empty()创建一个未初始化的张量元素值为未定义。x torch.empty(2, 3)torch.rand()创建一个包含在 [0, 1) 之间均匀分布的随机数的张量。x torch.rand(3, 3)torch.randn()创建一个包含从标准正态分布均值为0方差为1中抽取的随机数的张量。x torch.randn(3, 3)torch.randint()创建一个包含在 [low, high) 范围内均匀分布的整数的张量。x torch.randint(0, 10, (3, 3))torch.randperm()创建一个包含从0到n-1的随机排列的整数的张量。x torch.randperm(10)torch.normal()创建一个包含从指定均值和标准差的正态分布中抽取的随机数的张量。x torch.normal(mean0, std1, size(3, 3))torch.from_numpy()从一个 NumPy 数组创建张量张量和数组共享内存。x torch.from_numpy(np.array([1, 2, 3]))torch.clone()创建一个与原张量内容相同但在内存中独立的副本。x torch.tensor([1, 2, 3]).clone()torch.randint_like()根据给定张量的形状创建一个包含在 [low, high) 范围内的均匀分布整数的张量。x torch.randint_like(torch.ones(3, 3), 0, 10)torch.zeros_like()根据给定张量的形状创建一个所有元素为0的新张量。x torch.zeros_like(torch.ones(3, 3))torch.ones_like()根据给定张量的形状创建一个所有元素为1的新张量。x torch.ones_like(torch.ones(3, 3))torch.full_like()根据给定张量的形状创建一个所有元素为指定值的新张量。x torch.full_like(torch.ones(3, 3), 7)torch.empty_like()根据给定张量的形状创建一个未初始化的新张量。x torch.empty_like(torch.ones(3, 3)) 解释与应用 直接创建张量: 这些方法创建的张量通常作为计算图中的叶子节点因为它们是由用户直接定义的。除非显式指定 requires_gradTrue否则它们不会参与梯度计算。 典型用例: torch.zeros() 和 torch.ones() 常用于初始化模型参数。torch.randn() 和 torch.rand() 常用于生成随机初始化的张量用于神经网络的权重初始化等。torch.eye() 常用于生成单位矩阵用于线性代数计算。torch.from_numpy() 常用于将现有的 NumPy 数据转换为 PyTorch 张量。 梯度 requires_grad 关于张量是否计算梯度 这是一个很好的问题PyTorch 中 requires_grad 的默认值取决于张量的创建方式和上下文。让我们详细探讨一下 基本规则 对于大多数通过 PyTorch 操作创建的新张量默认 requires_gradFalse。对于通过涉及至少一个 requires_gradTrue 的张量的操作创建的新张量默认 requires_gradTrue。 常见情况 a) 使用 PyTorch 函数直接创建的张量 x torch.ones(5) # 默认 requires_gradFalse y torch.randn(3) # 默认 requires_gradFalseb) 从 NumPy 数组创建的张量 import numpy as np a np.array([1, 2, 3]) x torch.from_numpy(a) # 默认 requires_gradFalsec) 通过操作已有张量创建的新张量 x torch.ones(5) y x 2 # 如果 x.requires_gradFalse则 y.requires_gradFalsed) 模型参数 import torch.nn as nn model nn.Linear(10, 5) # model.weight 和 model.bias 默认 requires_gradTrue特殊情况 a) 使用 torch.tensor() 创建张量时 x torch.tensor([1, 2, 3]) # 默认 requires_gradFalse y torch.tensor([1, 2, 3], requires_gradTrue) # 显式设置为 Trueb) 在 torch.no_grad() 上下文中 with torch.no_grad():x torch.ones(5) # 即使显式设置也会是 Falsey torch.ones(5, requires_gradTrue) # 仍然是 True但梯度不会被跟踪让我们通过一个例子来演示这些规则 import torch import torch.nn as nn# 基本张量创建 x torch.ones(5) print(1. torch.ones():, x.requires_grad)# 使用 torch.tensor() y torch.tensor([1, 2, 3]) print(2. torch.tensor():, y.requires_grad)# 操作现有张量 z x y print(3. 操作现有张量:, z.requires_grad)# 至少一个输入 requires_gradTrue x.requires_grad_(True) w x y print(4. 至少一个输入 requires_gradTrue:, w.requires_grad)# 模型参数 model nn.Linear(5, 3) print(5. 模型参数 (weight):, model.weight.requires_grad) print( 模型参数 (bias):, model.bias.requires_grad)# torch.no_grad() 上下文 with torch.no_grad():a torch.ones(5)b torch.ones(5, requires_gradTrue)print(6. torch.no_grad() 中创建:, a.requires_grad)print( torch.no_grad() 中显式设置 True:, b.requires_grad)# 检查 torch.no_grad() 对梯度跟踪的影响 c x * 2 with torch.no_grad():d x * 2 print(7. 正常操作:, c.requires_grad) print( torch.no_grad() 中的操作:, d.requires_grad) 这个示例展示了不同情况下 requires_grad 的默认行为。运行这段代码你会看到 基本张量创建默认为 False。使用 torch.tensor() 创建的张量默认为 False。操作不需要梯度的张量得到的新张量默认为 False。如果操作中至少有一个输入需要梯度结果张量默认为 True。模型参数默认为 True。在 torch.no_grad() 上下文中新创建的张量仍遵循默认规则但不会跟踪计算图。torch.no_grad() 会暂时阻止梯度跟踪即使操作涉及 requires_gradTrue 的张量。 理解这些默认行为很重要因为它们影响 计算图的构建内存使用反向传播过程 在实际应用中 对于模型参数通常保持默认的 requires_gradTrue。对于输入数据通常保持默认的 requires_gradFalse。在需要冻结某些参数或部分模型时可以手动设置 requires_gradFalse。使用 torch.no_grad() 来临时禁用梯度计算通常用于推理或评估阶段。 是否开启梯度计算 要查看一个 PyTorch 张量是否开启了梯度计算有几种方法。我来为您详细介绍这些方法并提供一些实用的例子。 import torch# 创建几个不同的张量用于演示 x torch.randn(3, requires_gradTrue) y torch.zeros(3) z x * 2print(1. 使用 .requires_grad 属性:) print(x.requires_grad:, x.requires_grad) print(y.requires_grad:, y.requires_grad) print(z.requires_grad:, z.requires_grad)print(\n2. 使用 .is_leaf 属性:) print(x.is_leaf:, x.is_leaf) print(y.is_leaf:, y.is_leaf) print(z.is_leaf:, z.is_leaf)print(\n3. 检查 .grad_fn 属性:) print(x.grad_fn:, x.grad_fn) print(y.grad_fn:, y.grad_fn) print(z.grad_fn:, z.grad_fn)print(\n4. 使用 torch.is_grad_enabled() 函数:) print(全局梯度计算状态:, torch.is_grad_enabled())print(\n5. 在 torch.no_grad() 上下文中:) with torch.no_grad():w x * 2print(w.requires_grad:, w.requires_grad)print(torch.is_grad_enabled():, torch.is_grad_enabled())print(\n6. 使用 .detach() 方法:) v x.detach() print(v.requires_grad:, v.requires_grad)print(\n7. 检查 .grad 属性:) print(x.grad:, x.grad) # 在反向传播之前为 None x.sum().backward() print(反向传播后 x.grad:, x.grad) 让我解释一下这些方法 使用 .requires_grad 属性 这是最直接的方法。如果为 True表示张量需要梯度计算。 使用 .is_leaf 属性 叶子节点通常是需要梯度的张量。但注意并非所有 requires_gradTrue 的张量都是叶子节点。 检查 .grad_fn 属性 如果张量有 grad_fn说明它是由某个操作创建的并且可能参与梯度计算。叶子节点如直接创建的张量的 grad_fn 为 None。 使用 torch.is_grad_enabled() 函数 这会检查全局的梯度计算状态。在 torch.no_grad() 上下文中这会返回 False。 在 torch.no_grad() 上下文中 这个上下文管理器临时禁用梯度计算。在此上下文中创建的张量默认 requires_gradFalse。 使用 .detach() 方法 这会创建一个与原张量共享数据但不需要梯度的新张量。 检查 .grad 属性 只有需要梯度的叶子节点在反向传播后才会有 .grad 属性。在反向传播之前即使 requires_gradTrue.grad 也是 None。 重要说明 requires_gradTrue 不意味着张量当前正在跟踪梯度只是表示它有能力跟踪梯度。在 torch.no_grad() 上下文中即使 requires_gradTrue 的张量也不会跟踪梯度。非叶子节点由操作创建的张量通常不存储梯度除非使用 retain_grad()。 在实际应用中 对于模型参数通常会看到 requires_gradTrue。对于输入数据通常 requires_gradFalse。在模型评估或推理阶段经常使用 torch.no_grad() 来提高效率。 reshape/view PyTorch 中的 reshape 和 view 方法。这两个方法都用于改变张量的形状但它们在某些情况下有细微的区别。我们来详细解释一下 x.view() view 方法返回一个新的张量其数据与原张量共享内存但具有不同的形状。 特点 更快因为它不会复制数据。要求张量是连续的contiguous。如果张量不是连续的会抛出错误。 x.reshape() reshape 方法也返回一个新形状的张量但它更灵活。 特点 可以处理非连续的张量。如果可能它会返回一个视图view。如果不可能返回视图它会返回一个副本。 让我们通过一些例子来说明 import torch# 创建一个简单的张量 x torch.tensor([[1, 2, 3],[4, 5, 6]]) print(原始张量 x:) print(x) print(x 的形状:, x.shape)# 使用 view y x.view(3, 2) print(\n使用 view 后的张量 y:) print(y) print(y 的形状:, y.shape)# 使用 reshape z x.reshape(3, 2) print(\n使用 reshape 后的张量 z:) print(z) print(z 的形状:, z.shape)# 创建一个非连续的张量 a torch.tensor([[1, 2, 3],[4, 5, 6]]).t() # 转置使其非连续 print(\n非连续张量 a:) print(a) print(a 是否连续:, a.is_contiguous())# 尝试使用 view这会引发错误 try:b a.view(3, 2) except RuntimeError as e:print(\n使用 view 时的错误:)print(e)# 使用 reshape这会成功 c a.reshape(3, 2) print(\n使用 reshape 后的张量 c:) print(c) print(c 的形状:, c.shape) 这个例子展示了 view 和 reshape 的主要区别 对于连续的张量view 和 reshape 的行为是相同的。对于非连续的张量view 会失败而 reshape 会成功通过创建一个新的张量副本。 在实践中 如果你确定张量是连续的使用 view 可能会稍微快一些。如果你不确定张量是否连续或者你希望代码更加健壮使用 reshape 是更安全的选择。 总的来说reshape 更加通用和安全而 view 在特定情况下可能会有轻微的性能优势。在大多数情况下使用 reshape 是个不错的选择因为它能够处理更多的情况并且性能差异通常是微不足道的。 张量连续的概念 很好的问题让我们深入探讨一下张量的连续性概念。 张量的连续性contiguity是指张量在内存中的存储方式。这个概念对于理解某些 PyTorch 操作的行为和性能很重要。 连续的张量Contiguous Tensor 在内存中以一个连续的块存储。元素的存储顺序与它们的访问顺序一致。可以直接用 view() 改变形状而不需要复制数据。 非连续的张量Non-contiguous Tensor 在内存中的存储可能是分散的或者顺序与访问顺序不一致。通常是某些操作如转置、切片等的结果。使用 view() 会引发错误需要先调用 contiguous() 或使用 reshape()。 让我们通过一些例子来说明这个概念 import torch# 创建一个连续的张量 x torch.tensor([[1, 2, 3],[4, 5, 6]]) print(原始张量 x:) print(x) print(x 是否连续:, x.is_contiguous())# 创建一个非连续的张量通过转置 y x.t() print(\n转置后的张量 y:) print(y) print(y 是否连续:, y.is_contiguous())# 尝试对非连续张量使用 view try:z y.view(6) except RuntimeError as e:print(\n对非连续张量使用 view 的错误:)print(e)# 使用 contiguous() 使张量变为连续 y_cont y.contiguous() print(\n使用 contiguous() 后的张量 y_cont:) print(y_cont) print(y_cont 是否连续:, y_cont.is_contiguous())# 现在可以使用 view 了 z y_cont.view(6) print(\n对连续张量使用 view 的结果 z:) print(z)# 使用 reshape 可以直接处理非连续张量 w y.reshape(6) print(\n对非连续张量使用 reshape 的结果 w:) print(w) 解释 原始张量 x 是连续的。 转置操作 x.t() 创建了一个非连续的张量 y。这是因为转置改变了元素的访问顺序但没有改变它们在内存中的实际存储顺序。 当我们尝试对非连续张量 y 使用 view() 时PyTorch 抛出了一个错误。这是因为 view() 需要张量是连续的。 我们可以使用 contiguous() 方法创建一个新的连续张量 y_cont。这个操作会在内存中重新排列元素。 对连续的 y_cont 使用 view() 是可以的。 reshape() 方法可以直接处理非连续的张量它会在内部自动调用 contiguous() 如果需要的话。 实际应用中的影响 性能连续的张量通常可以更快地进行某些操作因为数据在内存中是连续的。 内存使用contiguous() 操作可能会创建一个新的张量副本这会增加内存使用。 某些操作的要求一些 PyTorch 操作如 view()要求张量是连续的。 CUDA 操作在 GPU 上使用连续的张量通常会有更好的性能。 参考 https://pytorch.org/docs/stable/tensors.htmlhttps://tingsongyu.github.io/PyTorch-Tutorial-2nd/chapter-2/2.3-datastruct-tensor.htmlhttps://pytorch.org/tutorials/beginner/introyt/autogradyt_tutorial.htmlhttps://pytorch.org/docs/stable/notes/autograd.html
http://www.dnsts.com.cn/news/188495.html

相关文章:

  • 做网站哪家公司商业空间设计有限公司
  • html做网站编写网页的软件叫什么
  • 网站怎么进行优化排名网站策划书背景介绍怎么写
  • 宝山做网站公司怎么做自己的网站后台教程
  • 湖北黄石域名注册网站建设互联网最挣钱82项目
  • 普通网站建设是什么青海省住房和城乡建设厅官方网站
  • 1网站建设合肥seo建站
  • 有经验的南昌网站制作企业网站内容运营
  • 写网站论文怎么做的丹东网站建设公司
  • 温州网站优化排名wordpress 产品模板
  • 网站推广对企业的优势注册网站什么要求
  • 织梦 安装网站网站正在建设中 html源码
  • 做网站怎么上线报价网站系统
  • 建设网站的技术方案是啥网站服务器选择
  • 货架网站开发西安php网站制作
  • 建设网站建设的目标在线小程序
  • 帮做非法网站免费域名申请国外
  • 网站开发知识产权归属半年工作总结ppt模板
  • 龙岗区网站建设百度关键词排名优化
  • 为什么建行网站打不开免费海报背景素材
  • 英雄联盟做的广告视频网站中企动力邮箱官网
  • 手机网站开发看什么书做外贸网站格式
  • 中药材网站开发住房城乡建设部网站诚信
  • 国内优秀的网站国内比百度好的搜索引擎
  • 国外代理网站小程序 wordpress绑定
  • 提供服务的网站珠海网络公司联系方式
  • 哈尔滨网站营销推广家乡网站设计模板
  • 百盛联合建设集团有限公司网站培训课程有哪些
  • 网站模板 下载北京网站建设哪家好
  • 企业网站类型主要包括网站的推广费用票可以做抵扣吗