Introduction to PyTorch

所有的深度学习都是关于张量的计算,它一般是矩阵可以被索引到高于2维。
首先,让我们看看我们能用张量做什么。

import torch
import torch.autograd as autograd
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

torch.manual_seed(1)

创建张量
张量可以从Python列表中使用torch.Tensor()函数创建。

# torch.tensor(data) creates a torch.Tensor object with the given data.
V_data = [1., 2., 3.]
V = torch.tensor(V_data)

# Creates a matrix
M_data = [[1., 2., 3.], [4., 5., 6]]
M = torch.tensor(M_data)

# Create a 3D tensor of size 2x2x2.
T_data = [[[1., 2.], [3., 4.]],
          [[5., 6.], [7., 8.]]]
T = torch.tensor(T_data)

什么是三维张量?
像这样思考。
如果你有一个向量,对向量的索引会给你一个标量。
如果你有一个矩阵,对矩阵的索引会给你一个向量。
如果你有一个三维张量,那么对张量的索引就会得到一个矩阵!

注意术语:
当我在本教程中说“张量”时,它指的是任何torch.Tensor对象。
矩阵和向量是torch的特殊情况。
张量,它们的维数分别是1和2。
当我说到3D张量时,我将明确地使用“3D张量”这个术语。

# Index into V and get a scalar (0 dimensional tensor)
print(V[0])
# Get a Python number from it
print(V[0].item())

# Index into M and get a vector
print(M[0])

# Index into T and get a matrix
print(T[0])

你也可以创建其他数据类型的张量。默认值,如您所见,是Float。
要创建整数类型的张量,请尝试一下torch.LongTensor()。
检查文档以获得更多的数据类型,但是Float和Long将是最常见的。
你可以用随机数和提供的维度来创建一个张量:torch.randn()
x = torch.randn((3, 4, 5))
print(x)

你可以按照你期望的方式对张量进行操作。

x = torch.tensor([1., 2., 3.])
y = torch.tensor([4., 5., 6.])
z = x + y
print(z)

tensor([ 5.,  7.,  9.])

它们的扩展 比数学运算还要多。
我们稍后将使用的一个有用的操作是串联。
默认按照 行 连接

# By default, it concatenates along the first axis (concatenates rows)
x_1 = torch.randn(2, 5)
y_1 = torch.randn(3, 5)
z_1 = torch.cat([x_1, y_1])
print(z_1)


tensor([[-0.8029,  0.2366,  0.2857,  0.6898, -0.6331],
        [ 0.8795, -0.6842,  0.4533,  0.2912, -0.8317],
        [-0.5525,  0.6355, -0.3968, -0.6571, -1.6428],
        [ 0.9803, -0.0421, -0.8206,  0.3133, -1.1352],
        [ 0.3773, -0.2824, -2.5667, -1.4303,  0.5009]])

按照 列 连接

# Concatenate columns:
x_2 = torch.randn(2, 3)
y_2 = torch.randn(2, 5)
# second arg specifies which axis to concat along
z_2 = torch.cat([x_2, y_2], 1)
print(z_2)

# If your tensors are not compatible, torch will complain.  Uncomment to see the error
# torch.cat([x_1, x_2])

tensor([[ 0.5438, -0.4057,  1.1341, -0.1473,  0.6272,  1.0935,  0.0939,1.2381],
        [-1.1115,  0.3501, -0.7703, -1.3459,  0.5119, -0.6933, -0.1668,-0.9999]])

Reshaping Tensors 重塑张量

Use the .view() method to reshape a tensor.

这种方法得到了大量的使用,因为许多神经网络组件期望它们的输入有一定的形状。
通常,在将数据传递给组件之前,您需要进行重构。

x = torch.randn(2, 3, 4)
print(x)
print(x.view(2, 12))  # Reshape to 2 rows, 12 columns
# Same as above.  If one of the dimensions is -1, its size can be inferred
print(x.view(2, -1))

tensor([[[ 0.4175, -0.2127, -0.8400, -0.4200],
         [-0.6240, -0.9773,  0.8748,  0.9873],
         [-0.0594, -2.4919,  0.2423,  0.2883]],

        [[-0.1095,  0.3126,  1.5038,  0.5038],
         [ 0.6223, -0.4481, -0.2856,  0.3880],
         [-1.1435, -0.6512, -0.1032,  0.6937]]])
tensor([[ 0.4175, -0.2127, -0.8400, -0.4200, -0.6240, -0.9773,  0.8748,
          0.9873, -0.0594, -2.4919,  0.2423,  0.2883],
        [-0.1095,  0.3126,  1.5038,  0.5038,  0.6223, -0.4481, -0.2856,
          0.3880, -1.1435, -0.6512, -0.1032,  0.6937]])
tensor([[ 0.4175, -0.2127, -0.8400, -0.4200, -0.6240, -0.9773,  0.8748,
          0.9873, -0.0594, -2.4919,  0.2423,  0.2883],
        [-0.1095,  0.3126,  1.5038,  0.5038,  0.6223, -0.4481, -0.2856,
          0.3880, -1.1435, -0.6512, -0.1032,  0.6937]])

计算图和自动微分
计算图的概念对于有效的深度学习编程是至关重要的,因为它允许您不必自己编写反向传播梯度。
计算图只是说明如何将数据组合起来以获得输出的规范。
由于图形完全指定了哪些参数与哪些操作有关,所以它包含了足够的信息来计算导数。
这可能听起来很模糊,所以让我们看看使用基本标志requires_grad的情况
首先,从程序员的角度来看。
在torch中储存了什么。
我们在上面创建的张量对象?
很明显,数据和形状,还有一些其他的东西。
但是当我们把两个张量加在一起时,我们得到了一个输出张量。
所有这些输出张量都知道它的数据和形状。
它不知道它是另外两个张量的和(它可能是从文件中读取的,可能是一些文件的结果其他操作,等等)。
If requires_grad=True,张量对象跟踪它是如何被创建的。
让我们在行动中看到它

# Tensor factory methods have a ``requires_grad`` flag
x = torch.tensor([1., 2., 3], requires_grad=True)

# With requires_grad=True, you can still do all the operations you previously could
y = torch.tensor([4., 5., 6], requires_grad=True)
z = x + y
print(z)

# BUT z knows something extra.
print(z.grad_fn)

tensor([ 5.,  7.,  9.])
<AddBackward1 object at 0x000001F74B564828>

所以张量知道是什么创造了它们。
z知道它不是从一个文件中读取的,它不是一个乘法或指数的结果,或者别的什么。
如果你一直跟着z。你会在x和y发现自己。
但这如何帮助我们计算梯度呢?

# Lets sum up all the entries in z
s = z.sum()
print(s)
print(s.grad_fn)

tensor(21.)
<SumBackward0 object at 0x000001F74B564518>

那么现在,x的第一个分量的和的导数是什么呢?
嗯,s知道它是作为张量z的和。z知道它是x+y的总和。
所以s包含了足够的信息来确定我们想要的导数是1!
当然,这掩盖了如何计算导数的挑战。
这里的重点是s携带了足够的信息,可以计算它。
在现实中,Pytorch程序的开发人员可以通过sum()和+操作来计算他们的梯度,并运行反向传播算法。
对该算法的深入讨论超出了本教程的范围。

让Pytorch计算梯度,看看我们是对的:
注意,如果你多次运行这个block,梯度将会增加。
这是因为Pytorch将梯度累积到.grad的属性中,因为对于许多模型来说,这是非常方便的。

# calling .backward() on any variable will run backprop, starting from it.
s.backward()
print(x.grad)

tensor([ 6.,  6.,  6.])

理解下面这一段的内容对于成为一个成功的深度学习的程序员是至关重要的。

x = torch.randn(2, 2)
y = torch.randn(2, 2)
# By default, user created Tensors have ``requires_grad=False``
print(x.requires_grad, y.requires_grad)

False False

z = x + y
# So you can't backprop through z
print(z.grad_fn)

None


# ``.requires_grad_( ... )`` changes an existing Tensor's ``requires_grad`` flag in-place. 
#  The input flag defaults to ``True`` if not given.
x = x.requires_grad_()
y = y.requires_grad_()
# z contains enough information to compute gradients, as we saw above
z = x + y
print(z.grad_fn)

<AddBackward1 object at 0x000001F74B564240>


# If any input to an operation has ``requires_grad=True``, so will the output
print(z.requires_grad)

True


# Now z has the computation history that relates itself to x and y
# Can we just take its values, and **detach** it from its history?
new_z = z.detach()
# ... does new_z have information to backprop to x and y? # NO!
print(new_z.grad_fn)
# And how could it? ``z.detach()`` returns a tensor that shares the same storage as ``z``, but with the computation history forgotten. 
#  It doesn't know anything about how it was computed.
# In essence, we have broken the Tensor away from its past history

None

你也可以阻止autograd在张量上跟踪历史requiresgrad=True,用结束代码块with torch.no_grad():

print(x.requires_grad)
print((x ** 2).requires_grad)

with torch.no_grad():
    print((x ** 2).requires_grad)

True
True
False
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,682评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,277评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,083评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,763评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,785评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,624评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,358评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,261评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,722评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,900评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,030评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,737评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,360评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,941评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,057评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,237评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,976评论 2 355

推荐阅读更多精彩内容

  • 官方所有教程的地址:pytorch.org/tutorials 以下是基于实例来入门pytorch Learnin...
    MiracleJQ阅读 1,831评论 0 4
  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,332评论 0 10
  • 《穿条纹睡衣的男孩》是一部感人剧情、讲述一位德国小男孩和犹太男孩纯真友谊的电影,亦是一部没有血腥杀戮场面却又震慑心...
    爱蹦哒的大可爱阅读 443评论 0 0
  • “吾爱吾师,吾更爱真理。” 亚里斯多德这名言,很有科学探索的精神,也引导着西方哲学朝向思辨和新知的方向发展...
    刘向雄_阅读 676评论 0 0
  • 本文参加#乡忆·乡思·乡情·乡恋#活动,本人承诺,文章内容为原创,且未在其他平台发表过。 古人...
    冯海宇阅读 234评论 0 0