PYTORCH整理:60分钟入门

官方地址:Deep Learning with PyTorch: A 60 Minute Blitz,感谢作者: Soumith Chintala
转载出处:Gaussic:夜露——PYTORCH整理:60分钟入门
本文在转载原文的基础上进行了基于自己理解的改动以期达到以下目标,改动比较小,如有问题欢迎批评指正。

  • 更高层次地理解Pythrch的Tensor库以及神经网络。
  • 训练一个小的神经网络模型用于分类图像
  • 掌握训练过程
  • 学习大佬思路(误 ̄□ ̄||)

什么是Pytorch

这是一个基于Python的科学计算包,主要针对两类人群:

  1. 替代Numpy以发挥GPU的强大能力
  2. 一个提供最大灵活性和速度的深度学习研究平台

Tensors基础知识

Tensors类似于numpy的ndarray,但是带了一些附加的功能,例如可以使用GPU加速计算等等。

构建一个未初始化的 5x3 矩阵:

import torch
x = torch.Tensor(5, 3)
print(x)
1.00000e-28 *0.0000  0.2524  0.00000.2524  2.8715  0.00002.9158  0.0000  2.91570.0000  2.9158  0.00000.0003  0.0000  0.0000
[torch.FloatTensor of size 5x3]

构建一个随机初始化的矩阵:

x = torch.rand(5, 3)
print(x)0.5453  0.4855  0.72360.3199  0.4525  0.49170.6965  0.8742  0.99480.9029  0.1873  0.00180.3080  0.2953  0.4313
[torch.FloatTensor of size 5x3]

获取矩阵维度大小:

print(x.size())
torch.Size([5, 3])

注意:

torch.Size实际上是一个元组,因此它支持相同的操作。

运算操作

运算操作有多种语法,让我们看看加法的例子。

加法:

语法1

y = torch.rand(5, 3)
print(x + y)
 1.1177  0.8514  1.14591.1878  0.9249  0.57591.3508  1.4628  1.28331.8678  0.8499  0.29410.9718  1.0785  0.6914
[torch.FloatTensor of size 5x3]

语法2

print(torch.add(x, y))
 1.1177  0.8514  1.14591.1878  0.9249  0.57591.3508  1.4628  1.28331.8678  0.8499  0.29410.9718  1.0785  0.6914
[torch.FloatTensor of size 5x3]

加法:给定一个输出tensor

result = torch.Tensor(5, 3)
torch.add(x, y, out=result)
print(result)
1.1177  0.8514  1.14591.1878  0.9249  0.57591.3508  1.4628  1.28331.8678  0.8499  0.29410.9718  1.0785  0.6914
[torch.FloatTensor of size 5x3]

加法:就地(in-place)

adds x to y

y.add_(x)
print(y)
1.1177  0.8514  1.14591.1878  0.9249  0.57591.3508  1.4628  1.28331.8678  0.8499  0.29410.9718  1.0785  0.6914
[torch.FloatTensor of size 5x3]

注意:
任何就地改变一个tensor的操作都以_为后缀
例如:无论x.copy_(y)或者x.t_()都会改变x。

tensor索引

你可以像numpy一样使用索引!

print(x[:, 1])
 0.48550.45250.87420.18730.2953
[torch.FloatTensor of size 5]

延伸阅读:100+ Tensor运算,包括转置、索引、切分、数学运算、线性代数随机数等等,链接:torch

Tensor与Numpy转换

Torch的Tensor和Numpy的数组之间的互转简直像一阵清风一样。

Torch的Tensor和Numpy的数组会共享它们的底层存储位置,该变其中一个,另外一个也会改变。

将Torch Tensor转换为Numpy数组:numpy()

a = torch.ones(5)
print(a)
 11111
[torch.FloatTensor of size 5]
b = a.numpy()
print(b)
[ 1.  1.  1.  1.  1.]

看看当改变numpy数组的值时发生了什么。

a.add_(1)
print(a)
print(b)
 22222
[torch.FloatTensor of size 5][ 2.  2.  2.  2.  2.]

更改Numpy数组的同时自动地更改了Torch Tensor

将Numpy数组转换为Torch Tensor:torch.from_numpy()

import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a, 1, out=a)
print(a)
print(b)
[ 2.  2.  2.  2.  2.]22222
[torch.DoubleTensor of size 5]

GPU与CPU Tensors

除了CharTensor之外,CPU上的所有Tensor都支持与Numpy数组的来回转换。
可以使用.cuda函数将Tensor转移到GPU上。

# let us run this cell only if CUDA is available
if torch.cuda.is_available():x = x.cuda()y = y.cuda()x + y

Autograd:自动求导

Pytorch中所有神经网络的中心部分是autograd包。我们首先浏览一下它,然后再构建我们的第一个神经网络。

autograd包为Tensor上的所有运算提供了自动求导功能。它是一个由运行定义的框架,即你的反向传播是由你的代码如何运行来决定的,而且每一轮迭代都可能是不同的。

让我们用几个简单的例子来了解几个简单的术语。

Variable 变量

autograd.Variable是这个包的中心类。它包装一个Tensor,并且支持几乎所有定义在这个Tensor上的运算。一旦你完成了你的计算,你可以调用.backward()来自动地计算全部的梯度。

你可以通过.data属性来访问最原始的tensor,而梯度则相应地被累计到了.grad中。


autograd的实现中还有一个非常重要的类-Function。

Variable和Function是相互关联的并且构建了一个非循环图,其中编码了整个的计算历史。每一个变量都有一个.creator属性,它引用一个常见Variable的Function(除了用户创建的Variables-它们的creator是None)。

如果你想计算导数,可以在Variable上调用.backward()。如果Variable是个标量(一个单元素数据),那么你不用为backward()指定任何参数,然而如果它有多个元素,你需要指定一个grad_output参数,它是一个匹配尺寸的tensor。

import torch
from torch.autograd import Variable
# 创建一个变量
x = Variable(torch.ones(2, 2), requires_grad=True)
print(x)
Variable containing:1  11  1
[torch.FloatTensor of size 2x2]
# 对变量进行运算
y = x + 2
print(y)
Variable containing:3  33  3
[torch.FloatTensor of size 2x2]

y是作为一个运算操作的结果而创建的,因而它有一个creator

print(y.creator)
<torch.autograd._functions.basic_ops.AddConstant object at 0x108ada4a8>

在y上做更多的运算:

z = y * y * 3
out = z.mean()
print(z, out)
Variable containing:27  2727  27
[torch.FloatTensor of size 2x2]Variable containing:27
[torch.FloatTensor of size 1]

Gradients 梯度

让我们使用反向传播out.backward(),它等同于out.backward(torch.Tensor([1.0]))

out.backward()
# 打印梯度 d(out)/dx
print(x.grad)
Variable containing:4.5000  4.50004.5000  4.5000
[torch.FloatTensor of size 2x2]

你应该会得到一个4.5的矩阵。让我们称out变量为o。我们有

因此,

你还可以使用autograd做一些疯狂的事情!

x = torch.randn(3)
x = Variable(x, requires_grad=True)
y = x * 2
while y.data.norm() < 1000:y = y * 2
print(y)
Variable containing:596.2775
-807.4459
-550.6819
[torch.FloatTensor of size 3]
gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
y.backward(gradients)
print(x.grad)
Variable containing:102.40001024.00000.1024
[torch.FloatTensor of size 3]

延伸阅读:Variable和Function的文档

神经网络

神经网络可以使用torch.nn包来构建。

现在你大致了解了autograd,nn依赖于autograd来定义模型并进行求导。一个nn.Module包含多个神经网络层,以及一个forward(input)方法来返回output

例如,看看以下这个分类数字图像的网络:

mnist

它是一个简单的前馈网络。它将输入逐步地喂给多个层,然后给出输出。

一个典型的神经网络训练过程如下:

  1. 定义一个拥有可学习参数(或权重)的神经网络
  2. 在输入数据上进行迭代
  3. 在网络中处理数据
  4. 计算损失(输出离分类正确有多远)
  5. 梯度反向传播给网络的参数
  6. 更新网络的权重,通常使用一个简单的更新规则:weight = weight + learning_rate * gradient

定义网络

import torch
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as Fclass Net(nn.Module):def __init__(self):super(Net, self).__init__()# 1 图像输入通道, 6 输出通道, 5x5 正方形卷积核self.conv1 = nn.Conv2d(1, 6, 5)self.conv2 = nn.Conv2d(6, 16, 5)# an affine operation: y = Wx + bself.fc1 = nn.Linear(16 * 5 * 5, 120)self.fc2 = nn.Linear(120, 84)self.fc3 = nn.Linear(84, 10)def forward(self, x):# 使用 (2, 2) 窗口最大池化x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))# If the size is a square you can only specify a single numberx = F.max_pool2d(F.relu(self.conv2(x)), 2)x = x.view(-1, self.num_flat_features(x))x = F.relu(self.fc1(x))x = F.relu(self.fc2(x))x = self.fc3(x)return xdef num_flat_features(self, x):size = x.size()[1:]   # 所有维度,除了批尺寸num_features = 1for s in size:num_features *= sreturn num_featuresnet = Net()
print(net)
Net ((conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))(conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))(fc1): Linear (400 -> 120)(fc2): Linear (120 -> 84)(fc3): Linear (84 -> 10)
)

你只需要定义forward函数,backward函数(用来计算梯度)是使用autograd自动为你定义的。你可以在forward中使用任意的Tensor运算操作。

模型中可学习的参数是通过net.parameters()返回的:

params = list(net.parameters())
print(len(params))
print(params[0].size())  # conv1's .weight
10
torch.Size([6, 1, 5, 5])

forward的输入是一个autograd.Variable ,输出亦然。

input = Variable(torch.randn(1, 1, 32, 32))
out = net(input)
print(out)
Variable containing:0.0455 -0.0445  0.0064 -0.0310  0.0945 -0.0362 -0.1971  0.0555  0.0943  0.1016
[torch.FloatTensor of size 1x10]

将梯度缓冲区置0,并使用随机的梯度进行反向传播:

net.zero_grad()
out.backward(torch.randn(1, 10))

⚠️ 注意:torch.nn仅支持mini-batch。整个的torch.nn包仅支持小批量的数据,而不是一个单独的样本。

例如,nn.Conv2d应传入一个4D的Tensor,维度为nSamples x nChannels x Height x Width。

如果你有一个单独的样本,使用input.unsqueeze(0)来添加一个伪批维度。

在继续之前,我们先回顾一下迄今为止的所有课程。

回顾:

  • torch.Tensor 一个多维数组
  • autograd.Variable包装一个Tensor并且记录应用在其上的历史运算操作。拥有与Tensor相同的API,添加了一些像backward()的操作。还包括相关tensor的梯度。
  • nn.Module 神经网络模块。封装参数的方便方式,带有将它们转移到GPU、导出、载入等的帮助函数。
  • nn.Parameter一种Variable,当给Module赋值时自动注册一个参数。
  • autograd.Function 实现一个autograd 操作的 forward 和 backward定义。每一个Variable操作,创建至少一个Function节点,来连接那些创建Variable的函数,并且记录其历史。

在这里,我们涵盖了:

  • 定义神经网络
  • 处理输入并调用backward

还剩下:

  • 计算损失
  • 更新网络权重

损失函数

一个损失函数以一个(output, target)pairs为输入,利用损失估计输出结果离目标结果多远。

存在多种的损失函数。一个简单的损失函数:nn.MSELoss,它计算输出与目标的均方误差。

例如:

output = net(input)
target = Variable(torch.arange(1, 11))  # a dummy target, for example
criterion = nn.MSELoss()
loss = criterion(output, target)
print(loss)
Variable containing:38.3005
[torch.FloatTensor of size 1]

现在,如果你在反方向跟随loss,使用它的.creator属性,你会看到一个如下所示的计算图:
还是没弄明白.create属性的功能是什么以及怎样查看
❓使用loss.create

input -> conv2d -> relu -> maxpool2d -> conv2d -> relu -> maxpool2d-> view -> linear -> relu -> linear -> relu -> linear-> MSELoss-> loss

因此,当我们调用loss.backward()时,损失对应的整个(上面的计算图)都被求导,并且图中所有的变量都会带有累积了梯度的.grad属性。

print(loss.creator)  # MSELoss
print(loss.creator.previous_functions[0][0])  # linear
print(loss.creator.previous_functions[0][0].previous_functions[0][0])  # ReLU
<torch.nn._functions.thnn.auto.MSELoss object at 0x10e0bdd68>
<torch.nn._functions.linear.Linear object at 0x10e0bdba8>
<torch.nn._functions.thnn.auto.Threshold object at 0x10e0bdac8>

反向传播

要进行反向传播,我们只需要调用loss.backward()。在这之前,你需要清除现有的梯度,否则梯度将累积到现有梯度。

现在我们将调用loss.backward(),并看看conv1在backward之前和之后的梯度变化。

net.zero_grad()   # zeroes the gradient buffers of all parameters
print('conv1.bias.grad before backward')
print(net.conv1.bias.grad)loss.backward()print('conv1.bias.grad after backward')
print(net.conv1.bias.grad)
conv1.bias.grad before backward
Variable containing:000000
[torch.FloatTensor of size 6]conv1.bias.grad after backward
Variable containing:0.1392
-0.11550.02470.1121
-0.05590.0363
[torch.FloatTensor of size 6]

现在我们知道怎么使用损失函数了。

延伸阅读:神经网络包包含构建深度神经网络的多个模块和损失函数,完整的文档列表见TORCH.NN
仅剩的一个要学习的东西:

  • 更新网络权重

更新权重

实践中最简单的更新规则是随机梯度下降(SGD):weight = weight - learning_rate * gradient
我们可以使用简单的Python代码实现:

learning_rate = 0.01
for f in net.parameters():f.data.sub_(f.grad.data * learning_rate)

然而,当使用神经网络时,希望使用各种不同的更新规则,例如SGD,Nesterov-SGD,Adam,RMSProp等等。为了实现这一点,我们构建一个小的包:torch.optim,来实现所有的方法。使用非常简单:

import torch.optim as optim# create your optimizer
optimizer = optim.SGD(net.parameters(), lr=0.01)# in your training loop:
optimizer.zero_grad()   # zero the gradient buffers
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step()    # Does the update

训练一个分类器

在此,你已经知道如何定义神经网络,计算损失以及更新网络权重。

现在你可能会想,

数据怎样读取

详细的数据读取过程可以参考我之前写过的一篇文章python数据集处理
一般来说,当你处理图像、文本、音频或视频数据时,你可以:

  1. 使用标准的python包来将数据载入到numpy数组中
  2. 将这个数组转化为torch.Tensor

对于图像和视频,诸如Pillow, OpenCV这些包很好用。
对于音频,可以使用scipy和librosa。
对于文本,要么使用原始的Python或Cython载入方式,要么使用NLTK和SpaCy。
特别的对于vision,pytorch创建了一个叫做torchvision的包,它有一些常用数据集(Imagenet, CIFAR10, MNIST等)的数据载入器,以及图像的数据转换器, torchvision.datasetstorch.utils.data.DataLoader

在本教程中,我们使用CIFAR10数据集。它有10个类别:‘airplane’,‘automobile’, ‘bird’,‘cat’, ‘deer’, ‘dog’, ‘frog’, ‘horse’, ‘ship’, ‘truck’。CIFAR10中的图像尺寸在3x32x32,即3通道彩色图像,32x32像素大小。

训练一个图像分类器

我们将按顺序完成以下步骤:

  1. 使用torchvision,载入和规范化CIFAR10的训练和测试集
  2. 定义一个卷积神经网络
  3. 定义损失函数
  4. 在训练集上进行训练
  5. 在测试集上进行测试
1. 载入和规范化CIFAR10

使用torchvision,载入CIFAR10非常简单。

import torch
import torchvision
import torchvision.transforms as transforms

torchvision datasets的输出时范围在[0, 1]的PILImage图像。我们将它们转换为规范区间[-1, 1]的Tensor。

transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])trainset = torchvision.datasets.CIFAR10(root='./data', train=True,download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,shuffle=True, num_workers=2)testset = torchvision.datasets.CIFAR10(root='./data', train=False,download=True, transform=transform)testloader = torch.utils.data.DataLoader(testset, batch_size=4,shuffle=True, num_workers=2)classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')

让我们展示一些训练图像。

import matplotlib.pyplot as plt
import numpy as np# functions to show image
def imshow(img):img = img / 2 + 0.5 # unnormalizenpimg = img.numpy()plt.imshow(np.transpose(npimg, (1, 2, 0)))# get some random training images
dataiter = iter(trainloader)
images, labels = dataiter.next()# show images
imshow(torchvision.utils.make_grid(images))
# print labels
print(' '.join('%5s' % classes[labels[j]] for j in range(4)))

2. 定义一个卷积神经网络

复制在神经网络那一节的神经网络,将其更改为3通道图像输入(而不是原始的单通道输入)。

from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as Fclass Net(nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = nn.Conv2d(3, 6, 5)self.pool = nn.MaxPool2d(2, 2)self.conv2 = nn.Conv2d(6, 16, 5)self.fc1 = nn.Linear(16 * 5 * 5, 120)self.fc2 = nn.Linear(120, 84)self.fc3 = nn.Linear(84, 10)def forward(self, x):x = self.pool(F.relu(self.conv1(x)))x = self.pool(F.relu(self.conv2(x)))x = x.view(-1, 16 * 5 * 5)x = F.relu(self.fc1(x))x = F.relu(self.fc2(x))x = self.fc3(x)return xnet = Net()

3. 定义损失函数和优化器

让我们来使用分类交叉熵和带有动量的SGD

import torch.optim as optimcriterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

4. 训练网络

for epoch in range(10): # loop over the dataset multiple timesrunning_loss = 0.0for i, data in enumerate(trainloader, 0):# get the inputinputs, labels = data# wrap time in Variableinputs, labels = Variable(inputs), Variable(labels)# zero the parameter gradientsoptimizer.zero_grad()# forward + backward + optimizeoutputs = net(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()# print statisticsrunning_loss += loss.data[0]if i % 2000 == 1999:   # print every 2000 mini-batchesprint('[%d, %5d] loss: %.3f' %(epoch + 1, i + 1, running_loss / 2000))running_loss = 0.0print('Finished Training')
[1,  2000] loss: 1.184
[1,  4000] loss: 1.206
[1,  6000] loss: 1.186
[1,  8000] loss: 1.162
[1, 10000] loss: 1.195
[1, 12000] loss: 1.165
[2,  2000] loss: 1.095
[2,  4000] loss: 1.076
[2,  6000] loss: 1.086
[2,  8000] loss: 1.092
[2, 10000] loss: 1.060
[2, 12000] loss: 1.110
[3,  2000] loss: 0.999
[3,  4000] loss: 1.005
[3,  6000] loss: 1.016
[3,  8000] loss: 1.016
[3, 10000] loss: 1.017
[3, 12000] loss: 1.023
[4,  2000] loss: 0.922
[4,  4000] loss: 0.933
[4,  6000] loss: 0.959
[4,  8000] loss: 0.975
[4, 10000] loss: 0.985
[4, 12000] loss: 0.968
[5,  2000] loss: 0.861
[5,  4000] loss: 0.908
[5,  6000] loss: 0.911
[5,  8000] loss: 0.932
[5, 10000] loss: 0.920
[5, 12000] loss: 0.919
[6,  2000] loss: 0.839
[6,  4000] loss: 0.853
[6,  6000] loss: 0.887
[6,  8000] loss: 0.891
[6, 10000] loss: 0.890
[6, 12000] loss: 0.876
[7,  2000] loss: 0.819
[7,  4000] loss: 0.808
[7,  6000] loss: 0.831
[7,  8000] loss: 0.852
[7, 10000] loss: 0.842
[7, 12000] loss: 0.869
[8,  2000] loss: 0.761
[8,  4000] loss: 0.784
[8,  6000] loss: 0.808
[8,  8000] loss: 0.827
[8, 10000] loss: 0.841
[8, 12000] loss: 0.860
[9,  2000] loss: 0.731
[9,  4000] loss: 0.758
[9,  6000] loss: 0.801
[9,  8000] loss: 0.784
[9, 10000] loss: 0.831
[9, 12000] loss: 0.817
[10,  2000] loss: 0.723
[10,  4000] loss: 0.733
[10,  6000] loss: 0.775
[10,  8000] loss: 0.763
[10, 10000] loss: 0.802
[10, 12000] loss: 0.799
Finished Training

5. 在测试数据上测试网络

我们已经在训练集上训练了10轮。但是我们需要检查网络是否有学到什么。

我们可以通过检测预测的类别标签,再与真实标签进行对比。如果预测是对的,我们将这个样本加到分类正确的列表中。

Okay,第一步。让我们先展示一些测试数据集中的图像。

dataiter = iter(testloader)
images, labels = dataiter.next()# print images
imshow(torchvision.utils.make_grid(images))
print('GroundTruth: ', ' '.join('%5s' % classes[labels[j]] for j in range(4)))

再来看一下神经网络认为这些样本是什么。

输出是10个类别的能量。一个类别能量越高,网络就更多地认为图像是这个特定的类别。因此,让我们获取最高能量类别的索引。

outputs = net(Variable(images))_, predicted = torch.max(outputs.data, 1)print('Predicted: ', ' '.join('%5s' % classes[predicted[j][0]] for j in range(4)))
Predicted:  horse plane horse  frog

结果看起来不错。

让我们再来看看网络在整个数据集上的性能。

correct = 0
total = 0
for data in testloader:images, labels = dataoutputs = net(Variable(images))_, predicted = torch.max(outputs.data, 1)total += labels.size(0)correct += (predicted == labels).sum()print('Accuracy of the network on the 10000 test images: %d %%' % (100 * correct / total))
Accuracy of the network on the 10000 test images: 63 %

这个结果看起来远比随机抽取要好,随机抽取的概率为10%。看起来网络确实学到了一些东西。

那么,有哪些类别表现优秀,哪些类别表现不佳呢?

class_correct = list(0. for i in range(10))
class_total = list(0. for i in range(10))
for data in testloader:images, labels = dataoutputs = net(Variable(images))_, predicted = torch.max(outputs.data, 1)c = (predicted == labels).squeeze()for i in range(4):label = labels[i]class_correct[label] += c[i]class_total[label] += 1for i in range(10):print('Accuracy of %5s: %2d %%' % (classes[i], 100 * class_correct[i] / class_total[i]))
Accuracy of plane: 59 %
Accuracy of   car: 73 %
Accuracy of  bird: 51 %
Accuracy of   cat: 46 %
Accuracy of  deer: 51 %
Accuracy of   dog: 54 %
Accuracy of  frog: 76 %
Accuracy of horse: 69 %
Accuracy of  ship: 78 %
Accuracy of truck: 72 %

如何在GPU上面运行这个神经网络?

在GPU上训练

与你如何将Tensor转移到GPU上类似,你可以将神经网络转移到GPU上。这将递归的遍历所有的模块并将它们的参数和缓存转化为CUDA tensors。

net.cuda()

记住,你还必须在每一步将输入和结果数据传输到GPU上:

inputs, labels = Variable(inputs.cuda()), Variable(labels.cuda())

为什么我没有注意到相比CPU的巨大的加速?因为你的神经网络非常小。

训练:试着增加你的网络宽度(将第一个nn.Conv2d增广2,将第二个nn.Conv2d增广1 - 它们需要相同的数量),看看你的网络提速了多少。

目标达成:

  • 更高层次地理解Pythrch的Tensor库以及神经网络。
  • 训练一个小的神经网络模型用于分类图像
  • 掌握训练过程

【转载】PYTORCH整理:60分钟入门相关推荐

  1. (翻译)60分钟入门深度学习工具-PyTorch

    60分钟入门深度学习工具-PyTorch 作者:Soumith Chintala 原文翻译自: https://pytorch.org/tutorials/beginner/deep_learning ...

  2. 可下载:60分钟入门PyTorch(中文翻译全集)

    来源:机器学习初学者本文约9500字,建议阅读20分钟官网教程翻译:60分钟入门PyTorch(全集) 前言 原文翻译自:Deep Learning with PyTorch: A 60 Minute ...

  3. 【深度学习】翻译:60分钟入门PyTorch(四)——训练一个分类器

    前言 原文翻译自:Deep Learning with PyTorch: A 60 Minute Blitz 翻译:林不清(https://www.zhihu.com/people/lu-guo-92 ...

  4. 【深度学习】翻译:60分钟入门PyTorch(三)——神经网络

    前言 原文翻译自:Deep Learning with PyTorch: A 60 Minute Blitz 翻译:林不清(https://www.zhihu.com/people/lu-guo-92 ...

  5. PyTorch 60 分钟入门教程中的一些疑惑

    PyTorch 60 分钟入门教程中的一些疑惑 自动微分 参考: PyTorch 60 分钟入门教程. 自动微分 y.data.norm()指的是y的范数,举一个例子 假设x是[1.,2.,3.],则 ...

  6. C++ 60分钟入门教程 - 1、绪论

    C++ 60分钟入门教程不到20节,可以让你在最短的时间内快速了解C++. 该教程重点讲解C++与C语言的区别,以及C++的新增内容,不再重复讲解C语言的知识. C++是面向对象的语言,该教程重点讲解 ...

  7. (转载)正则表达式30分钟入门教程

    (转载)正则表达式30分钟入门教程  作者:deerchao 来源:unibetter大学生社区 转载请注明来源  什么是正则表达式?  很可能你使用过Windows/Dos下用于文件查找的通配符,也 ...

  8. 60分钟入门PyTorch,官方教程手把手教你训练第一个深度学习模型

    点击我爱计算机视觉标星,更快获取CVML新技术 本文转载自机器之心. 近期的一份调查报告显示:PyTorch 已经力压 TensorFlow 成为各大顶会的主流深度学习框架.想发论文,不学 PyTor ...

  9. 60分钟入门PyTorch,官方教程手把手教你训练第一个深度学习模型(附链接)

    来源:机器之心 本文约800字,建议阅读5分钟. 本文介绍了官方教程入门PyTorch的技巧训练. 近期的一份调查报告显示:PyTorch 已经力压 TensorFlow 成为各大顶会的主流深度学习框 ...

最新文章

  1. Grunt-几个常用的任务配置,加载,执行的写法
  2. MATLAB实现偏最小二乘回归PLS
  3. python资料书-关于 Python 的经典入门书籍有哪些?
  4. VTK:IO之ReadRectilinearGrid
  5. 马云狂炸近百亿,你的借呗额度涨了吗?
  6. 合并 多个dataframe_什么是Pandas的DataFrame?
  7. Dom4J__ZZ_我的示例代码
  8. mybatis配置 SqlMapConfig.xml user.xml
  9. LeetCode刷题(18)
  10. java 10什么意思_详解:Java 10的10个新特性
  11. win7磁盘清理_Win7系统使用久变慢怎么办?Windows7系统优化方法
  12. 字节跳动重大宣布:取消!员工炸了:直接降薪1
  13. http 503 service
  14. Ramnit 蠕虫分析
  15. SWD调试接口接上下拉电阻
  16. Android 技术淘金者:杨丰盛
  17. 华擎主板设置来电开机_华擎主板设置来电开机_一块性价比超高的B550主板、华擎(ASRock)B550 Extreme4极限玩家主板 评测......
  18. 云海多功能二开解析接口计费系统全开源免授权v4.5
  19. 公式编辑器mathpix下载及使用简介
  20. 2012年08月20日

热门文章

  1. 监控线上服务器运行情况脚本
  2. 利用朴素贝叶斯分类器实现手写数字的识别
  3. 「镁客·请讲」FXG Nikk Mitchell:优质VR内容能够带你真正进入细节
  4. 1131. 拯救大兵瑞恩
  5. 2012春季高考计算机试题,春季高考历年真题-2012年天津市季高考计算机试卷.doc...
  6. Java遍历Json数据
  7. java 睡眠一小时_java线程睡眠sleep
  8. Java8中重要的收集器Collector
  9. 数字孪生技术应用在物流领域中的案例解析
  10. iOS几个关键字(nonnull、nullable、null_resettable、__null_unspecified)