注意:这是旧版本的PyTorch教程的一部分。你可以在Learn the Basics查看最新的开始目录。

该教程通过几个独立的例子较少了PyTorch的基本概念。

核心是:PyTorch提供了两个主要的特性:

  • 一个n维的Tensor,与Numpy相似但可以在GPU上运行
  • 构建和训练神经网络的自动微分

我们将使用一个三阶多项式拟合 \(y=sin(x)\) 的问题作为我们的运行示例。该网络会有4个参数,将使用梯度下降来训练,通过最小化神经网络输出和真值之间的欧氏距离来拟合随机数据。

Tensors

热身:numpy

在介绍PyTorch之前,我们首先使用numpy实现网络

Numpy提供了一个n维的array对象,以及对数组操作的多种方法。Numpy是一个用于科学计算的通用框架,它没有关于计算图、深度学习、梯度的任何内容。但是我们可以利用numpy操作,通过人工实现贯穿网络的前向和后向传递,从而简单的向sin函数拟合一个三阶多项式。

  1. # -*- coding: utf-8 -*-
  2. import numpy as np
  3. import math
  4. # Create random input and output data
  5. x = np.linspace(-math.pi, math.pi, 2000) # 生成含有2000个数的-π到π的等差数列
  6. y = np.sin(x)
  7. # Randomly initialize weights
  8. a = np.random.randn() # 返回浮点数
  9. b = np.random.randn()
  10. c = np.random.randn()
  11. d = np.random.randn()
  12. learning_rate = 1e-6
  13. for t in range(2000):
  14. # Forward pass: compute predict y
  15. # y = a + b x + c x^2 + d x^3
  16. y_pred = a + b * x + c * x ** 2 + d * x ** 3
  17. # Compute and print loss
  18. loss = np.square(y_pred - y).sum() # 所有样本与真值的差值平方的和
  19. if t % 100 == 99:
  20. print(t, loss)
  21. # Backprop to compute gradients of a, b, c, d with respect to loss
  22. grad_y_pred = 2.0 * (y_pred - y) # loss关于y_pred的偏导(梯度),这里没有对所有样本求和
  23. grad_a = grad_y_pred.sum() # 这里及下面都要对所有样本得到的梯度求和
  24. grad_b = (grad_y_pred * x).sum()
  25. grad_c = (grad_y_pred * x ** 2).sum()
  26. grad_d = (grad_y_pred * x ** 3).sum()
  27. # Update weights
  28. a -= learning_rate * grad_a
  29. b -= learning_rate * grad_b
  30. c -= learning_rate * grad_c
  31. d -= learning_rate * grad_d
  32. print(f"Result: y = {a} + {b} x + {c} x^2 + {d} x^3")

PyTorch: Tensors

Numpy是一个强大的框架,但是它无法使用GPUs加速数值计算。对于现代的深度神经网络,GPUs通常提供了50倍或更高的加速性能,所以很遗憾,numpy对于现代的深度学习是不够的。

现在介绍PyTorch基础中的基础:Tensor。PyTorch Tensor概念上来说与numpy array相同:一个Tensor就是一个n维数组,并且PyTorch提供了许多用于tensor的操作。在幕后,张量可以跟踪计算图和梯度,但它们也可用作科学计算的通用工具。

而且不像numpy,PyTorch Tensors可以使用GPUs加速数值计算。简单地制定正确的设备,即可在GPU上运行PyTorch tensor。

这里我们使用PyTorch Tensors为sin函数拟合一个3阶多项式。像上面的numpy例子一样,我们需要手动实现贯穿网络的前向和后向传递:

  1. # -*- coding: utf-8 -*-
  2. import torch
  3. import math
  4. dtype = torch.float
  5. device = torch.device('cpu')
  6. # device = torch.device('cuda:0') # Uncomment this to run on GPU
  7. # Create random input and output data
  8. x = torch.linspace(-math.pi, math.pi, 2000, device=device, dtype=dtype)
  9. y = torch.sin(x)
  10. # Randomly initialize weights
  11. a = torch.randn((), device=device, dtype=dtype)
  12. b = torch.randn((), device=device, dtype=dtype)
  13. c = torch.randn((), device=device, dtype=dtype)
  14. d = torch.randn((), device=device, dtype=dtype)
  15. learning_rate = 1e-6
  16. for t in range(2000):
  17. # Forward pass: compute predicted y
  18. y_pred = a + b * x + c * x ** 2 + d * x ** 3
  19. # Compute and print loss
  20. loss = (y_pred - y).pow(2).sum().item() # .item()是取tensor的数值
  21. if t % 100 == 99:
  22. print(t, loss)
  23. # Backprop to compute gradients of a, b, c, d with respect to loss
  24. grad_y_pred = 2.0 * (y_pred - y)
  25. grad_a = grad_y_pred.sum()
  26. grad_b = (grad_y_pred * x).sum()
  27. grad_c = (grad_y_pred * x ** 2).sum()
  28. grad_d = (grad_y_pred * x ** 3).sum()
  29. # Update weights
  30. a -= learning_rate * grad_a
  31. b -= learning_rate * grad_b
  32. c -= learning_rate * grad_c
  33. d -= learning_rate * grad_d
  34. print(f"Result: y = {a.item()} + {b.item()} x + {c.item()} x^2 + {d.item()} x^3")

Autograd

PyTorch: Tensors and autograd

在上面的例子中,我们必须手动实现神经网络的前向和后向传递。手动实现后向传递对于小型的只有两层的网络不算什么,但是对于大型复杂的网络的将变得非常困难。

幸运的是,我们可以使用自动微分来使神经网络反向传递的计算自动化。PyTorch中的autograd包提供了该功能。当使用autograd,神经网络前向传递将定义一个计算图,图中的节点是Tensor,edges是从输入tensor产生输出tensor的函数。然后通过该图,反向传播可以轻松地计算梯度。

这听起来很复杂,在实践中使用却非常简单。每个Tensor表示计算图中的一个节点。如果 x 是一个Tensor,它有属性 x.requires_grad=True,那么 x.grad 就是另一个保存x关于一些标量值的梯度的tensor。

这里,我们使用PyTorch tensors和autograd实现了拟合3阶多项式的例子;现在我们不再需要手动实现网络的反向传递了。

  1. # -*- coding: utf-8 -*-
  2. import torch
  3. import math
  4. dtype = torch.float
  5. device = torch.device('cpu')
  6. # device = torch.device('cuda:0') # Uncomment this to run on GPU
  7. # Create Tensors to hold input and outputs.
  8. # 默认情况下,requires_grad=False, 表示在反向传递中,无需计算关于这些tensrs的的梯度
  9. x = torch.linspace(-math.pi, math.pi, 2000, device=device, dtype=dtype)
  10. y = torch.sin(x)
  11. # Create random Tensors for weights.对于一个3阶多项式,我们需要4个权重参数:
  12. # y = a + b x + c x^2 + d x^3
  13. # 设置requires_grad=True表示我们想要在反向传递中计算关于这些Tensors的梯度
  14. a = torch.randn((), device=device, dtype=dtype, requires_grad=True)
  15. b = torch.randn((), device=device, dtype=dtype, requires_grad=True)
  16. c = torch.randn((), device=device, dtype=dtype, requires_grad=True)
  17. d = torch.randn((), device=device, dtype=dtype, requires_grad=True)
  18. learning_rate = 1e-6
  19. for t in range(2000):
  20. # 前向传递:使用tensor操作计算预测值y
  21. y_pred = a + b * x + c * x ** 2 + d * x ** 3
  22. # 使用tensor操作计算和打印loss
  23. # 现在loss是一个shape为(1,)的Tensor
  24. # loss.item() 获得loss中保存的标量值
  25. loss = (y_pred - y).pow(2).sum()
  26. if t % 100 == 99:
  27. print(t, loss.item())
  28. # 使用autograd计算反向传递。该调用将会计算loss关于所有具有requires_grad=True属性的tensor的梯度
  29. # 调用之后,a.grad, b.grad, c.grad, d.grad将分别称为保存loss关于a,b,c,d的梯度的Tensor
  30. loss.backward()
  31. # 使用梯度下降手动更新权重。包围在torch.no_grad()进行该操作是因为
  32. # 权重具有requires_grad=True属性,但我们不需要在autograd中跟踪该操作:
  33. with torch.no_grad():
  34. a -= learning_rate * a.grad
  35. b -= learning_rate * b.grad
  36. c -= learning_rate * c.grad
  37. d -= learning_rate * d.grad
  38. # 更新权重后,手动地将梯度置为0,不清零会累加
  39. a.grad = None
  40. b.grad = None
  41. c.grad = None
  42. d.grad = None
  43. print(f'Result: y = {a.item()} + {b.item()} x + {c.item()} x^2 + {d.item()} x^3')

PyTorch: 定义个新的autograd函数

在底层,每个原始的autograd操作实际是两个在tensor上操作的函数,forward函数计算从输入张量得到的输出张量。backward函数

在PyToch中,我们可以通过定义一个 torch.autograd.Function 子类,简单地定义一个autograd操作,并实现 forwardbackward 函数。然后,我们可以通过构造一个实例并向函数一样调用它,传递包含输入数据的Tensor来使用我们新的autograd操作符。

在这个例子中,我们定义了一个模型 \(y = a + b P_3(c + dx)\) 来代替 \(y = a + bx + cx^2 + dx^3\),\(P_3(x) = \frac{1}{2}(5x^3-3x)\),即3阶勒让德多项式,我们编写了自己的autograd函数,实现了\(P_3\)的前向和后向计算,并使用它来实现我们的模型。

  1. # -*- coding: utf-8 -*-
  2. import torch
  3. import math
  4. class LegendrePolynomial3(torch.autograd.Function):
  5. """
  6. 我们可以通过继承torch.autograd.Function来实现自定义autograd Functions。
  7. Function和实现对Tensor进行操作的前向和反向传递。
  8. """
  9. @staticmethod
  10. def forward(ctx, input):
  11. """
  12. 前向传递,我们接收包含输入的Tensor并返回包含输出的Tensor。ctx是一个上下文对象,可用于储存信息以进行反向计算。
  13. 你可以使用ctx.save_for_backward方法缓存任意对象以用于反向传递。
  14. """
  15. ctx.save_for_backward(input)
  16. return 0.5 * (5 * input ** 3 - 3 * input)
  17. @staticmethod
  18. def backward(ctx, grad_output):
  19. """
  20. 后向传递,我们接收了一个包含loss关于output的梯度的Tenor,我们需要计算loss关于input的梯度???
  21. """
  22. input, = ctx.saved_tensors
  23. return grad_output * 1.5 * (5 * input ** 2 -1)
  24. dtype = torch.float
  25. device = torch.device('cpu')
  26. # device = torch.device('cuda:0') # Uncomment this to run on GPU
  27. # 构建tensors保存input和output
  28. # 默认情况下,requires_grad=False, 表明我们在后向传递中无需计算关于这些tensor的梯度
  29. x = torch.linspace(-math.pi, math.pi, 2000, device=device, dtype=dtype)
  30. y = torch.sin(x)
  31. # 创建权重tensor。例如,我们需要4个权重参数:y = a + b * P3(c + d * x)
  32. # 为了确保收敛,这些权重的初始化值需要与正确的结果相近
  33. # 设置requires_grad=True表示我们希望在后向传递中计算关于这些tensor的梯度
  34. a = torch,full((), 0.0, device=device, dtype=dtype, requires_grad=True) # 创建元素全为0.0的tensor
  35. b = torch,full((), -1.0, device=device, dtype=dtype, requires_grad=True)
  36. c = torch,full((), 0.0, device=device, dtype=dtype, requires_grad=True)
  37. d = torch,full((), 0.3, device=device, dtype=dtype, requires_grad=True)
  38. learning_rate = 5e-6
  39. for t in range(2000):
  40. # 为了应用我们的Function,使用Function.apply,并赋为'P3'
  41. P3 = LegendrePolynomial3.apply
  42. ## 前向传递:计算预测值y_pred,使用自动以的autograd操作计算P3
  43. y_pred = a + b * P3(c + d * x)
  44. # Compute and print loss
  45. loss = (y_pred - y).pow(2).sum()
  46. if t % 100 == 9:
  47. print(t, loss.item())
  48. # Use autograd to compute the backward pass
  49. loss.backward()
  50. # Update weights using gradient descent
  51. with torch.no_grad():
  52. a -= learning_rate * a.grad
  53. b -= learning_rate * b.grad
  54. c -= learning_rate * c.grad
  55. d -= learning_rate * d.grad
  56. # Manually zero the gradients after updating weights
  57. a.grad = None
  58. b.grad = None
  59. c.grad = None
  60. d.grad = None
  61. print(f'Result: y = {a.item()} + {b.item()} * P3({c.item()} + {d.item()} x)')

nn module

PyTorch: nn

计算图和autograd是定义复杂运算符合自动求导的非常强大的工具,但是对于大型神经网络,原生的autograd就显得有些低级了。

构建神经网络时,我们常会思考将计算放入layers,它包含训练时将被优化的learnable parameters

在TensorFlow中,类似Keras、TensorFlow-Slim,TFLearn等库在原生计算图上提供了更高级别的抽象,这对于构建神经网络很有用。

在PyTorch中,nn 库同样为这个目标服务。nn 库定义了Modules的集合,它与神经网络层大致对等。一个Module接受输入Tensors,计算输出Tensors,但也可能保持内部状态,例如包含可学习参数的Tensors。nn 库还定义了训练神经网络时常用的损失函数的集合。

该例中,我们使用 nn 库实现我们的多项式模型网络:

  1. # -*- coding: utf-8 -*-
  2. import torch
  3. import math
  4. # Create Tensors to hold input and outputs
  5. x = torch.linspace(-math.pi, math.pi, 2000)
  6. y = torch.sin(x)
  7. # 对于这个例子,输出的y是(x, x^2, x^3)的线性函数,所以
  8. # 我们可以将它认为是一个线性神经网络层。
  9. # 准备tensor(x, x^2, x^3)
  10. p = torch.tensor([1, 2, 3])
  11. xx = x.unsqueeze(-1).pow(p) # 增加维度,原来是(2000,),现在是(2000, 1)
  12. # 在上述代码中,x.unsqueeze(-1)的shape是(2000, 1),p的shape是(3,),
  13. # "broadcasting semantics"将会获得shape为(2000, 3)的张量
  14. # 使用nn库将我们的模型定义为一系列层。nn.Sequential是一个包含其它Modules的Module,按顺序使用以产生输出。
  15. # 线性Module使用线性函数从输入计算输出,并持有内部张量的权重和偏差。
  16. # 为了匹配 'y'的shape,Flatten层将线性层的输出展平至1D tensor,
  17. model = torch.nn.Sequential(torch.nn.Linear(3, 1),
  18. torch.nn.Linear(3, 1),
  19. torch.nn.Flatten(0, 1)
  20. )
  21. # nn库还包含了流行的损失函数的定义
  22. # 该例中,我们将使用Mean Squared Error (MSE)
  23. loss_fn = torch.nn.MSELoss(reduction='sum')
  24. learning_rate = 1e-6
  25. for t in range(2000):
  26. # 前向传递:将x传入模型计算预测值y。Module对象重写了__call__操作,所以你可以向函数一样调用它们。
  27. y_pred = model(xx)
  28. # 计算和打印loss
  29. loss = loss_fn(y_pred, y)
  30. if t % 100 == 99:
  31. print(t, loss.item())
  32. # 在后向传递前将梯度置0
  33. model.zero_grad()
  34. # 后向传递:计算loss关于所有模型可学习参数的梯度。
  35. # 每个Module的参数都保存在具有requires_grad=True属性的Tensors中,
  36. # 所以下面的调用将为模型中所有可学习参数计算梯度。
  37. loss.backward()
  38. # 使用梯度下降更新权重。每个参数都是一个Tensor,所以我们可以像之前那样访问它的梯度
  39. with torch.no_grad():
  40. for param in model.parameters():
  41. param -= learning_rate * param.grad
  42. # 你可以像访问列表的item一样访问'model'的第一个layer
  43. linear_layer = model[0]
  44. # 对于线性层,它的参数被保存为'weight'和'bias'
  45. print(f'Result: y = {learn_layer.bias.item()} + {linear_layer.weight[:, 0].item()} x +
  46. {linear_layer.weight[:, 1].item()} x^2 + {linear_layer.weight[:, 2].item()} x^3')

PyTorch: optim

到目前为止,我们已经通过使用 torch.no_grad() 手动改变持有可学习参数的张量来更新模型参数。这对于如随机梯度下降这样的简单优化算法没有什么问题,但在实践中,我们常使用更复杂的优化器如AdaGrad,RMSProp,Adam等来训练网络。

PyTorch的 optim 库提供了常用优化算法的实现

下例中,我们将首先使用 nn 库定义我们的模型,使用 optim 库提供的RMSProp算法优化模型。

  1. # -*- coding: utf-8 -*-
  2. import torch
  3. import math
  4. # Create Tensors to hold input and outputs
  5. x = torch.linspace(-math.pi, math.pi, 2000)
  6. y = torch.sin(x)
  7. # 准备输入张量(x, x^2, x^3)
  8. p = torch.tensor([1, 2, 3])
  9. xx = x.unsqueeze(-1).pow(p)
  10. # 使用nn库定义模型和损失函数
  11. model = torch.nn.Sequential(
  12. torch.nn.Linear(3, 1)
  13. torch.nn.Flatten(0, 1)
  14. )
  15. loss_fn = torch.nn.MSELoss(reduction='sum')
  16. # 使用optim库定义优化器更新模型参数,这里使用RMSProp,optim库包含许多其它优化算法。
  17. # RMSProp构造函数的第一个参数是告诉优化器应该更新哪些Tensors。
  18. learning_rate = 1e-3
  19. optitmizer = torch.optim.RMSProp(model.parameters(), lr=learning_rate)
  20. for t in range(2000):
  21. # 前向传递:将x传入模型,计算预测值y
  22. y_pred = model(xx)
  23. # 计算和打印loss
  24. loss = loss_fn(y_pred, y)
  25. if t % 100 == 99:
  26. print(t, loss.item())
  27. # 在反向传递之前,使用optimizer对象将所有将更新的变量(即模型的可学习参数)的梯度置0,这是因为默认情况下,每当调
  28. # 用.backward(),梯度在缓存中是累加的(而不是重写),查阅torch.autograd.backward()获得更多细节。
  29. optimizer.zero_grad()
  30. # 后向传递:计算loss关于模型参数的梯度
  31. loss.backward()
  32. # 在optimizer上调用step函数用于更新其参数
  33. optimizer.step()
  34. linear_layer = model[0]
  35. print(f'Result: y = {linear_layer.bias.item()} + {linear_layer.weight[:, 0].item()} x +
  36. {linear_layer.weight[:, 1].item()} x^2 + {linear_layer.weight[:, 2].item()} x^3')

PyTorch: Custom nn Modules

有些时候你想指定比一系列现有Modules更复杂的模型,那么可以通过继承 nn.Module来定义自己的Modules,并且定义 forward,用以接收输入Tensors,利用其它modules或其它在Tensor上的autograd操作符产生输出Tensor。

实现3阶多项式,作为一个自定义的Module模块的子类。

  1. # -*- coding: utf-8 -*-
  2. import torch
  3. import math
  4. class Polynomial3(torch.nn.Module):
  5. def __init__(self):
  6. """
  7. 在构造函数中,我们实例化了4个参数,并将它们赋为成员参数
  8. """
  9. super().__init__()
  10. self.a = torch.nn.Parameter(torch.randn(()))
  11. self.b = torch.nn.Parameter(torch.randn(()))
  12. self.c = torch.nn.Parameter(torch.randn(()))
  13. self.d = torch.nn.Parameter(torch.randn(()))
  14. def forward(self, x):
  15. """
  16. 在前向传递中,接收输入数据tensor,也要返回输出数据的tensor。可以使用构造函数中定义的Modules,
  17. 也可以是其它任意Tensor上的操作。
  18. """
  19. return self.a + self.b * x + self.c x ** 2 + self.d * x ** 3
  20. def string(self):
  21. """
  22. 就像Python的其它类一样,你可以在PyTorch modules上自定义方法
  23. """
  24. return f'y = {self.a.item()} + {self.b.item()} x + {self.c.item()} x^2 + {self.d.item()} x^3'
  25. # 创建tensor保存input和output
  26. x = torch.linspace(-math.pi, math.pi, 2000)
  27. y = torch.sin(x)
  28. # 通过实例化之前定义的类构造模型
  29. model = Polynomial3()
  30. # 构造损失函数和优化器。SGD构造函数中调用的model.parameters()包含可学习参数(由torch.nn.Parameter定义的模型成员)
  31. criterion = torch.nn.MSELoss(reduction='sum')
  32. optimizer = torch.optim.SGD(model.parameters(), lr=1e-6)
  33. for t in range(2000):
  34. # Forward pass: Compute predicted y by passing x to the model
  35. y_pred = model(x)
  36. # Compute and print loss
  37. loss = criterion(y_pred, y)
  38. if t % 100 == 99:
  39. print(t, loss.item())
  40. # Zero gradients, perform a backward pass, and update the weights.
  41. optimizer.zero_grad()
  42. loss.backward()
  43. optimizer.step()
  44. print(f'Result: {model.string()}')

PyTorch: 控制流 + 权重共享

作为动态图和权重共享的例子,我们实现了一个非常奇怪的模型:一个3到5阶的多项式,在每一次前向传递时,选择一个3到5之间的随机值作为阶,并且多次重用相同的权重计算第4和第5阶。

对于这个模型,我们可以使用普通的Python控制流实现循环,并且在定义前向传递时,可以通过简单的多次复用相同的参数实现权重共享。

我们可以简单地将其作为Module子类来实现模型。

  1. # -*- coding: utf-8 -*-
  2. import random
  3. import torch
  4. import math
  5. class DynamicNet(torch.nn.Module):
  6. def __init__(self):
  7. """
  8. 构造函数中,我们实例化5个参数并将其赋为成员
  9. """
  10. super().__init__()
  11. self.a = torch.nn.Parameter(torch.randn(()))
  12. self.b = torch.nn.Parameter(torch.randn(()))
  13. self.c = torch.nn.Parameter(torch.randn(()))
  14. self.d = torch.nn.Parameter(torch.randn(()))
  15. self.e = torch.nn.Parameter(torch.randn(()))
  16. def forward(self, x):
  17. """
  18. 对于模型的前向传递,我们随机选择4,5并重用参数e计算这两个阶的共享
  19. 因为每次前向传递都会构建一个动态计算图,当定义模型前向传递时,我们可以使用普通的Python控制流语句,如循环或条件语句
  20. 这里我们还可以看到,定义计算图时,多次重用相同的参数时完全安全的
  21. """
  22. y = self.a + self.b + self.c * x ** 2 + self.d * x ** 3
  23. for exp in range(4, random.randint(4, 6)):
  24. y = y + self.e * x ** exp
  25. return y
  26. def string(self):
  27. """
  28. 就像Python中的其它任何类一样,你还可以在PyTorch modules上自定义方法
  29. """
  30. return f'y = {self.a.item()} + {self.b.item()} x + {self.c.item()} x^2 + {self.d.item()} x^3 + {self.e.item()} x^4 ? + {self.e.item()} x^5 ?'
  31. # 创建Tensors保存input和outputs
  32. x = torch.linspace(-math.pi, math.pi, 2000)
  33. y = torch.sin(x)
  34. # 通过实例化上面定义的类构造模型
  35. model = DynamicNet()
  36. # 构造损失函数和优化器,使用vanilla(batch)梯度下降训练这个奇怪的网络有些困难,我们使用momentum
  37. criterion = torch.nn.MSELoss(reduction='sum')
  38. optimizer = torch.optim.SGD(model.parameters(), lr=1e-8, momentum=0.9)
  39. for t in range(30000):
  40. # 前向传递:将x传入模型,计算预测值y
  41. y_pred = model(x)
  42. # 计算并打印loss
  43. loss = criterion(y_pred, y)
  44. if t % 2000 == 1999:
  45. print(t, loss.item())
  46. # 梯度归0,反向传递,权重更新
  47. optimizer.zero_grad()
  48. loss.backward()
  49. optimizer.step()
  50. print(f'Result: {model.string()}')

通过示例学习PYTORCH的更多相关文章

  1. DL基础补全计划(二)---Softmax回归及示例(Pytorch,交叉熵损失)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  2. MIL 多示例学习 特征选择

    一个主要的跟踪系统包含三个成分:1)外观模型,通过其可以估计目标的似然函数.2)运动模型,预测位置.3)搜索策略,寻找当前帧最有可能为目标的位置.MIL主要的贡献在第一条上. MIL与CT的不同在于后 ...

  3. html5游戏引擎phaser官方示例学习

    首发:个人博客,更新&纠错&回复 phaser官方示例学习进行中,把官方示例调整为简明的目录结构,学习过程中加了点中文注释,代码在这里. 目前把官方的完整游戏示例看了一大半, brea ...

  4. Delphi之通过代码示例学习XML解析、StringReplace的用法(异常控制 good)

    *Delphi之通过代码示例学习XML解析.StringReplace的用法 这个程序可以用于解析任何合法的XML字符串. 首先是看一下程序的运行效果: 以解析这样一个XML的字符串为例: <? ...

  5. 多示例学习 multiple instance learning (MIL)

    多示例学习:包(bags) 和 示例 (instance). 包是由多个示例组成的,举个例子,在图像分类中,一张图片就是一个包,图片分割出的patches就是示例.在多示例学习中,包带有类别标签而示例 ...

  6. [深度学习] Pytorch(三)—— 多/单GPU、CPU,训练保存、加载模型参数问题

    [深度学习] Pytorch(三)-- 多/单GPU.CPU,训练保存.加载预测模型问题 上一篇实践学习中,遇到了在多/单个GPU.GPU与CPU的不同环境下训练保存.加载使用使用模型的问题,如果保存 ...

  7. [深度学习] Pytorch学习(一)—— torch tensor

    [深度学习] Pytorch学习(一)-- torch tensor 学习笔记 . 记录 分享 . 学习的代码环境:python3.6 torch1.3 vscode+jupyter扩展 #%% im ...

  8. 001-深度学习Pytorch环境搭建(Anaconda , PyCharm导入)

    001-深度学习Pytorch环境搭建(Anaconda , PyCharm导入) 在开始搭建之前我们先说一下本次主要安装的东西有哪些. anaconda 3:第三方包管理软件. 这个玩意可以看作是一 ...

  9. [PyTorch入门]之从示例中学习PyTorch

    Learning PyTorch with examples 来自这里. 本教程通过自包含的示例来介绍PyTorch的基本概念. PyTorch的核心是两个主要功能: 可在GPU上运行的,类似于num ...

随机推荐

  1. windows环境jdk8下载安装与配置环境变量

    1)jdk8官网下载地址 Java Downloads | Oracle 下载前需登录Oracle账号,没有的话可以用邮箱注册一个,登录之后即可进行下载. 2)jdk8安装 ①下载完成之后双击运行文件 ...

  2. 详解nohup /dev/null 2>&1 含义的使用

    https://www.jb51.net/article/169837.htm 这篇文章主要介绍了详解nohup /dev/null 2>&1 含义的使用,文中通过示例代码介绍的非常详细 ...

  3. MySQL 截取小数位数

    项目中遇到一些有关小数位数截取的问题,留下痕迹,以便后续使用时注意:个人推荐使用方法2),直接四舍五入 1)select FORMAT(1478568.2457,2): 查询出来的结果为: ,每隔3位 ...

  4. Go语言系列之依赖管理

    依赖管理 为什么需要依赖管理? 最早的时候,Go所依赖的所有的第三方库都放在GOPATH这个目录下面.这就导致了同一个库只能保存一个版本的代码.如果不同的项目依赖同一个第三方的库的不同版本,应该怎么解 ...

  5. k8s 理解Service工作原理

    什么是service? Service是将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法. 简单来说K8s提供了service对象来访问pod.我们在<k8s网络模型与集群通信> ...

  6. vue3 watch和watchEffect的详细讲解

    watch 监听 reative 创建的值 const state = reactive({ nickname: "xiaofan", age: 20 }); setTimeout ...

  7. ​第3届云原生技术实践峰会(CNBPS 2020)重磅开启,“原”力蓄势待发!

    CNBPS 2020将在11月19-21日全新启动!作为国内最有影响力的云原生盛会之一,云原生技术实践峰会(CNBPS)至今已举办三届. 在2019年的CNBPS上,灵雀云CTO陈恺喊出"云 ...

  8. 解析HetuEngine实现On Yarn原理

    摘要:本文介绍HetuEngine实现On Yarn的原理,通过阅读本文,读者可以了解HetuEngine如何在资源使用方面融入Hadoop生态体系. 本文分享自华为云社区<MRS HetuEn ...

  9. dubbo泛化引发的生产故障之dubbo隐藏的坑

    dubbo泛化引发的生产故障之dubbo隐藏的坑 上个月公司zk集群发生了一次故障,然后要求所有项目组自检有无使用Dubbo编程式/泛化调用,强制使用@Reference生成Consumer.具体原因 ...

  10. Cesium入门8 - Configuring the Scene - 配置视窗

    Cesium入门8 - Configuring the Scene - 配置视窗 Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coini ...