pytorch-tensor等

常用Tensor操作:

通过tensor.view方法可以调整tensor的形状,但必须保证调整前后元素总数一致。view不会修改自身的数据,返回的新tensor与源tensor共享内存,也即更改其中的一个,另外一个也会跟着改变。在实际应用中可能经常需要添加或减少某一维度,这时候squeezeunsqueeze两个函数就派上用场了。

resize是另一种可用来调整size的方法,但与view不同,它可以修改tensor的大小。如果新大小超过了原大小,会自动分配新的内存空间,而如果新大小小于原大小,则之前的数据依旧会被保存。

# None类似于np.newaxis, 为a新增了一个轴
# 等价于a.view(1, a.shape[0], a.shape[1])
a[None].shape

gather相对应的逆操作是scatter_gather把数据从input中按index取出,而scatter_是把取出的数据再放回去。注意scatter_函数是inplace操作。

假设输入的形状是(m, n, k)

  • 如果指定dim=0,输出的形状就是(1, n, k)或者(n, k)
  • 如果指定dim=1,输出的形状就是(m, 1, k)或者(m, k)
  • 如果指定dim=2,输出的形状就是(m, n, 1)或者(m, n)

如按某个维度sum,则该维度为一个数。

dot/cross内积/外积

Tensor和Numpy数组之间具有很高的相似性,彼此之间的互操作也非常简单高效。需要注意的是,Numpy和Tensor共享内存。由于Numpy历史悠久,支持丰富的操作,所以当遇到Tensor不支持的操作时,可先转成Numpy数组,处理后再转回tensor,其转换开销很小。当numpy的数据类型和Tensor的类型不一样的时候,数据会被复制,不会共享内存。如float32和float64数据类型不一样。

Module中的可学习参数可以通过named_parameters()或者parameters()返回迭代器,前者会给每个parameter都附上名字,使其更具有辨识度。打印参数:layer为实例化的一个网络。

for name, parameter in layer.named_parameters():

     print(name, parameter) # w and b

为方便用户使用,PyTorch实现了神经网络中绝大多数的layer,这些layer都继承于nn.Module,封装了可学习参数parameter,并实现了forward函数,且很多都专门针对GPU运算进行了CuDNN优化,其速度和性能都十分优异。本书不准备对nn.Module中的所有层进行详细介绍,具体内容读者可参照官方文档1或在IPython/Jupyter中使用nn.layer?来查看。阅读文档时应主要关注以下几点:

  • 构造函数的参数,如nn.Linear(in_features, out_features, bias),需关注这三个参数的作用。
  • 属性、可学习参数和子module。如nn.Linear中有weightbias两个可学习参数,不包含子module。
  • 输入输出的形状,如nn.linear的输入形状是(N, input_features),输出为(N,output_features),N是batch_size。

为方便用户使用,PyTorch实现了神经网络中绝大多数的layer,这些layer都继承于nn.Module,封装了可学习参数parameter,并实现了forward函数,且很多都专门针对GPU运算进行了CuDNN优化,其速度和性能都十分优异。本书不准备对nn.Module中的所有层进行详细介绍,具体内容读者可参照官方文档1或在IPython/Jupyter中使用nn.layer?来查看。阅读文档时应主要关注以下几点:

  • 构造函数的参数,如nn.Linear(in_features, out_features, bias),需关注这三个参数的作用。
  • 属性、可学习参数和子module。如nn.Linear中有weightbias两个可学习参数,不包含子module。
  • 输入输出的形状,如nn.linear的输入形状是(N, input_features),输出为(N,output_features),N是batch_size。

这些自定义layer对输入形状都有假设:输入的不是单个数据,而是一个batch。输入只有一个数据,则必须调用tensor.unsqueeze(0) 或 tensor[None]将数据伪装成batch_size=1的batch。

优化器torch.optim需重点掌握:

  • 优化方法的基本使用方法
  • 如何对模型的不同部分设置不同的学习率
  • 如何调整学习率

应该什么时候使用nn.Module,什么时候使用nn.functional呢?答案很简单,如果模型有可学习的参数,最好用nn.Module,否则既可以使用nn.functional也可以使用nn.Module,二者在性能上没有太大差异,具体的使用取决于个人的喜好。如激活函数(ReLU、sigmoid、tanh),池化(MaxPool)等层由于没有可学习参数,则可以使用对应的functional函数代替,而对于卷积、全连接等具有可学习参数的网络建议使用nn.Module。

数据处理:数据加载可通过自定义的数据集对象。数据集对象被抽象为Dataset类,实现自定义的数据集需要继承Dataset,并实现两个Python魔法方法:

  • __getitem__:返回一条数据,或一个样本。obj[index]等价于obj.__getitem__(index)
  • __len__:返回样本的数量。len(obj)等价于obj.__len__()

torchvision主要包含三部分:

  • models:提供深度学习中各种经典网络的网络结构以及预训练好的模型,包括AlexNet、VGG系列、ResNet系列、Inception系列等。
  • datasets: 提供常用的数据集加载,设计上都是继承torhc.utils.data.Dataset,主要包括MNISTCIFAR10/100ImageNetCOCO等。
  • transforms:提供常用的数据预处理操作,主要包括对Tensor以及PIL Image对象的操作。

CUDA:除了调用对象的.cuda方法之外,还可以使用torch.cuda.device,来指定默认使用哪一块GPU,或使用torch.set_default_tensor_type使程序默认使用GPU,不需要手动调用cuda。

要实现模型单机多卡十分容易,直接使用 new_module = nn.DataParallel(module, device_ids), 默认会把模型分布到所有的卡上。多卡并行的机制如下:

  • 将模型(module)复制到每一张卡上
  • 将形状为(N,C,H,W)的输入均等分为 n份(假设有n张卡),每一份形状是(N/n, C,H,W),然后在每张卡前向传播,反向传播,梯度求平均。要求batch-size 大于等于卡的个数(N>=n)

在绝大多数情况下,new_module的用法和module一致,除了极其特殊的情况下(RNN中的PackedSequence)。另外想要获取原始的单卡模型,需要通过new_module.module访问。

本质上上述这些信息最终都是保存成Tensor。Tensor的保存和加载十分的简单,使用t.save和t.load即可完成相应的功能。在save/load时可指定使用的pickle模块,在load时还可将GPU tensor映射到CPU或其它GPU上。

我们可以通过t.save(obj, file_name)等方法保存任意可序列化的对象,然后通过obj = t.load(file_name)方法加载保存的数据。对于Module和Optimizer对象,这里建议保存对应的state_dict,而不是直接保存整个Module/Optimizer对象。Optimizer对象保存的主要是参数,以及动量信息,通过加载之前的动量信息,能够有效地减少模型震荡。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值