深度学习第一节
·
深度学习第一节
pytorch是广泛应用于机器学习领域的强大开源框架,因其易用性和高效性备受青睐。其中 pytorch的核心数据类型是张量对象。 pytorch提供了许多帮助构建神经网络的高级方法及组件,并提供了利用GPU更快的训练神经网络的张量对象。
张量类似于Numpy中的多为矩阵ndarrays,标量可以表示为零维张量,向量可以表示为一维张量,二维矩阵可以表示为二维矩阵,多维矩阵可以表示为多维张量。
PyTorch 中的张量(Tensor)和 NumPy 中的 ndarray相比,pytorch张量对象经过优化配合gpu使用。
数据基本操作
1.导入pytorch并通过在列表上调用torch.tensor来初始化张量
import torch x = torch.tensor([[1,2]]) y = torch.tensor([[1],[2]])
2.内置函数快速生成张量
x = torch.arange(12) #tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) x = torch.zeros((2,3,4)) #tensor([[[0., 0., 0., 0.], [0., 0., 0., 0.], [0., 0., 0., 0.]], [[0., 0., 0., 0.], [0., 0., 0., 0.], [0., 0., 0., 0.]]]) x = torch.ones((2,3,4)) #tensor([[[1., 1., 1., 1.], [1., 1., 1., 1.], [1., 1., 1., 1.]], [[1., 1., 1., 1.], [1., 1., 1., 1.], [1., 1., 1., 1.]]]) #随机填充 c = torch.randint(low=0,high=10,size=(3,4)) #每个元素为0到10之间的随机整数值 #tensor([[4, 5, 5, 4], [1, 5, 3, 2], [3, 5, 7, 6]]) d = torch.rand(3,4) #每个元素为0到1之间的随机浮点值 #tensor([[0.0413, 0.9341, 0.4687, 0.3344], [0.1153, 0.6723, 0.3727, 0.3245], [0.6182, 0.1326, 0.9461, 0.5833]]) e = torch.randn((3,4)) # 每个元素服从正态分布 #tensor([[ 0.1260, 1.5217, -0.0127, 2.3229], [ 0.5907, 0.1080, -0.5392, 0.9487], [ 1.0874, -0.0342, 0.9897, -1.0400]])
3.获取张量对象的形状和数据类型
x.shape x.dtype
注意:同一张量的所有元素的数据类型相同,这意味着如果张量包含不同数据类型的数据(例如布尔、整数和浮点数),则整个张量被强制转换为最通用的数据类型:
x = torch.tensor([False,1,2.0]) print(x) #tensor([0.,1.,2.])
4.numpy中 ndarray可以转换为tensor
A = X.numpy() B = torch.tensor(A) #type(A),type(B) #(numpy.ndarray, torch.Tensor) 注意:只有一个元素可以转换为标量 a = torch.tensor([3.5]) #a,a.item,float(a),int(a) #tensor([3.5000]), <function Tensor.item>, 3.5, 3
5.原地操作内存地址不变
Y = torch.arange(12) before = id(Y) Y = x+y #id(Y) == before #False #内存地址变化 Y = torch.arange(12).reshape((2,6)) before = id(Y) X = x.reshape((2,6)) Y[:] = X+Y #id(Y) == before #True #原地操作内存地址不变化
6.张量运算
神经网络中常见运算包括输入与权重的矩阵相乘,添加偏置项,以及需要时整形(reshape)输入或权重值。
每个元素×10,每个元素+10 A = torch.tensor([[1,2,3,4],[3,4,5,6]]) #A*10,A+10,A.add(10) #tensor([[10, 20, 30, 40], [30, 40, 50, 60]]), tensor([[11, 12, 13, 14], [13, 14, 15, 16]]), tensor([[11, 12, 13, 14], [13, 14, 15, 16]])
#矩阵乘法 torch.matmul(x,y) x@y
x==y #tensor([[False, True, False, True], [False, False, False, False], [False, False, False, False]])
7.改变张量形状
在 PyTorch 中,reshape、view和 squeeze都是用于改变张量形状(shape)的操作
torch.reshape() #reshape 函数会返回一个具有指定形状的新张量。它既可以操作连续的张量,也可以操作不 连续的张量。 #可能复制数据,如果张量不连续则会复制数据 troch.view() #只能操作连续的张量 #不复制数据,返回一个共享底层数据的视图 torch.squeeze() #移除张量中所有或指定维度中大小为 1 的维度 #如果不指定维度,squeeze() 会移除所有大小为 1 的维度。 #如果指定维度 dim,squeeze(dim) 只会移除该维度,前提是该维度的大小为 1。如果指定维度的大小不为 1,则该操作不会改变张量的形状。 #squeeze 操作通常返回一个共享底层数据的新视图,不进行数据复制。 x = torch.randn(10,1,10) z1 = torch.squeeze(x,1) z2 = x.squeeze(1) assert torch.all(z1==z2) #x.shape,z1.shape #torch.Size([10, 1, 10]), torch.Size([10, 10])
与squeeze相反的操作是unsqueeze,向矩阵添加一个新维度 x = torch.randn(10,10) z1 = x.unsqueeze(0) z2,z3,z4 = x[None],x[:,None],x[:,:,None]#也可以使用None进行创建新通道/维度 #x.shape,z1.shape,z2.shape,z3.shape #torch.Size([10, 10]), torch.Size([1, 10, 10]), torch.Size([1, 10, 10]), torch.Size([10, 1, 10])
8.张量连接运算
x = torch.arange(12,dtype = torch.float32).reshape((3,4)) y = torch.tensor([[2.0,1,4,3],[1,2,3,4],[4,3,2,1]]) #torch.cat((x,y),dim=0),torch.cat((x,y),dim=1) #tensor([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.], [ 2., 1., 4., 3.], [ 1., 2., 3., 4.], [ 4., 3., 2., 1.]]), tensor([[ 0., 1., 2., 3., 2., 1., 4., 3.], [ 4., 5., 6., 7., 1., 2., 3., 4.], [ 8., 9., 10., 11., 4., 3., 2., 1.]])
9.提取张量中最大值
#提取张量中的最大值 x = torch.arange(25).reshape(5,5) #x.max() #tensor(24) #提取最大值以及存在最大值的行索引 #x.max(dim=0) #torch.return_types.max( values=tensor([20, 21, 22, 23, 24]), indices=tensor([4, 4, 4, 4, 4])) #m,argm = x.max(dim=1) #tensor([ 4, 9, 14, 19, 24]), tensor([4, 4, 4, 4, 4])
10.张量对象的自动梯度计算
微分和计算梯度在更新神经网络的权重中至关重要,pytorch中的张量对象内置梯度计算函数。
#定义一个张量对象,同时指定它需要计算梯度,requires_grad = True指定腰围张#量对象计算梯度 x = torch.tensor([[2.,-1.],[1.,1.]],requires_grad = True) #tensor([[ 2., -1.], [ 1., 1.]], requires_grad=True)
11.计算所有输入的平方和
out = x.pow(2).sum() #x,out #tensor([[ 2., -1.], [ 1., 1.]], requires_grad=True), tensor(7., grad_fn=<SumBackward0>)
12.计算梯度
x.grad #tensor([[ 4., -2.], [ 2., 2.]])
13.比较numpy数组和tensor张量执行矩阵所花费的时间
#生成不同的torch对象 import torch import time x = torch.rand(1,6400) y = torch.rand(6400,5000)
#定义用于存储张量对象的设备 device = 'cuda' if torch.cuda.is_available() else 'cpu' assert device == 'cuda',"this exercise is on a GPU machine"
#将创建的张量对象注册到设备中,注册张量对象意味着将信息存储到指定设备中 x,y = x.to(device),y.to(device)
#执行torch对象的矩阵乘法,并对其计时,并比较在numpy数组中执行矩阵乘法的速度。
start = time.time()
for i in range(10):
z = x@y
end = time.time()
print(end - start)
#在cpu上执行相同的矩阵乘法
x,y = x.cpu(),y.cpu()
start = time.time()
for i in range(10):
z = x@y
end = time.time()
print(end - start)
#在numpy数组上执行相同的矩阵乘法
import numpy as np
x = np.random.random((1,6400))
y = np.random.random((6400,5000))
start = time.time()
for i in range(10):
z = np.matmul(x,y)
end = time.time()
print(end - start)
在gpu上对torch对象执行的矩阵乘法比在cpu上的torch对象快约18倍,比在numpy数组上执行矩阵乘法快约40倍,一般来说,在cpu中使用torch张量的矩阵乘法同样比numpy更快。
更多推荐


所有评论(0)