利用pytorch进行深度学习(1)

学习深度学习之前,我们需要先了解一些概念

一. 基本框架

1.框架

       在深度学习初始阶段,每个深度学习研究者都需要写大量的重复代码。为了提高工作效率,这些研究者就将这些代码写成了一个框架放到网上让所有研究者一起使用。接着,网上就出现了不同的框架。随着时间的推移,最为好用的几个框架被大量的人使用从而流行了起来。全世界最为流行的深度学习框架有PaddlePaddle、Tensorflow、Caffe、Theano、MXNet、Torch和PyTorch,关于这些框架的对比网上有很多很详细的讲解,这里我只说说我所涉及的三个框架:

(1)TensorFlow

       这是一个非常底层的框架,但是他要重复写的代码也很多,系统设计过于复杂,不够灵活,凭借Google着强大的推广能力,TensorFlow已经成为当今最炙手可热的深度学习框架,社区强大,适合生产环境

(2)pytorch

      比较灵活,更少的抽象、更直观的设计使得PyTorch的源码十分易于阅读,PyTorch的源码甚至比许多框架的文档更容易理解,但覆盖范围没tensorflow广

(3)MXnet

2.集成开发环境(IDE)

        用于提供程序开发环境的应用程序,一般包括代码编辑器、编译器调试器和图形用户界面等工具。集成了代码编写功能、分析功能、编译功能、调试功能等一体化的开发软件服务套。所有具备这一特性的软件或者软件套(组)都可以叫集成开发环境 ,常见的有VS,Eclipse,Pycharm等。

3.工作环境

      工作环境是它可以提供各种语言库的底层,python中常用的工作环境包括 Anaconda,也是我目前所用的。Anaconda附带了一大批数据科学包,附带了conda,Python和150多个科学包及其依赖项,可以帮助我们快速处理数据,其中的conda是一个包管理器和环境管理器,作为包管理器可以很好的帮助我们在计算机上安装和管理这些包,那环境管理如何理解呢?比如在A项目中使用了python2,而新的项目要求使用python3,同时安装两个python版本可能导致许多混乱和错误,因此利用conda可以帮助不同的项目建立不同的运行环境,还有一些项目使用的包版本不同,例如要不同的Numpy版本,此时需要为每个Numpy创建一个环境,然后项目到对应的环境中工作,而这些工作conda可以帮到

4.notebook(笔记本)

       在没有notebook前,IT领域工作是这样的:在普通的python shell或者IDE(如pycharm)里面写代码,然后在word里面写文档来说明项目,这个过程很繁琐,通常是写完代码,在写文档的时候还需要重头回顾一遍代码,有些时候数据分析的中间结果还需要重新跑代码。而有了notebook后,可以直接在notebook旁边写叙述性文档,而不是另外单独编写文档,可以将代码,文档集中到一处,常见的notebook有notepad++,还有Anaconda中的Jupyter notebook,其中Jupyter notebook是一个交互式笔记本,以网页的形式打开,可以在网页页面中直接编写代码和运行代码,代码的运行结果也会直接在代码块下显示。如在编程过程中需要编写说明文档,可在同一个页面中直接编写,便于作及时的说明和解释。(参考https://www.py.cn/tools/anaconda/16875.html


二. 数据操作——学习Tensor的相关操作
1. 特点:
       在深度学习中需要频繁的对数据进行操作,在pytorch中一般使用Tensor进行存储和变化数据,是一种包含单一数据类型元素的多维矩阵,但提供了GPU计算和自动求梯度等更多功能,使得Tensor更加适合深度学习,某种意义上来说Tensor就是一个特殊的多维数组。数据包torch 包含了多维张量的数据结构以及基于其上的多种数学操作。另外,它也提供了多种工具,其中一些可以更有效地对张量和任意类型进行序列化。它有CUDA 的对应实现,可以在NVIDIA GPU上进行张量运算(计算能力>=2.0)。
       要注意的是:
       torch.Tensor()是Python类,更明确的说,是默认张量类型torch.FloatTensor()的别名,torch.Tensor([1,2]) 会调用Tensor类的构造函数__init__,生成单精度浮点类型的张量。
       torch.tensor()仅仅是Python的函数,函数原型是:
torch.tensor(data, dtype=None, device=None, requires_grad=False)

其可以用来直接输出数据

 

2. 创建:其中data的表示形式是[a,b...m,n],sizes表示的是张量形状,其中第一个数表示向量个数,第二个数表示向量维数,device是指可以指定CPU还是GPU

torch.empty(*sizes, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)empty()返回一个包含未初始化数据的张量。

torch.rand(*sizes, out=None)       返回一个张量,包含了从区间[0, 1)的均匀分布中抽取的一组随机数。

torch.randn(*sizes, out=None)     返回一个张量,包含了从标准正态分布(均值为0,方差为1,即高斯白噪声)中抽取的一组随机数。

torch.zeros(*size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)    返回一个形状为为size,类型为torch.dtype,里面的每一个值都是0的tensor

torch.ones(*size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)    返回一个形状为为size,类型为torch.dtype,里面的每一个值都是1的tensor

x.new_ones(*sizes, dytype=None)   返回一个dtype和device与x都相同,性状为sizes的tensor(X是一个tensor的变量名)

torch.eye(n,m=None,out=None)   生成对角线为1,其余全为0的二维数组(类似单位矩阵),n是行,m是列

3. 操作:

(1)加法

y = torch.rand(5,3)
x = torch.rand(5,3)
result = torch.empty(5,3)
print(x+y) //法一
print(torch.add(x,y)) //法二
torch.add(x,y,out=result)
print(result) //法三:指定输出

 

(2)索引

可用类似NumPy的操作访问Tensor的一部分,的索引出来的结果与原数据共享内存,即修改一个,另一个也会跟着修改

y[ start : stop : step ]  表示y中从a开始到b,步长为c,的向量

(3)形状

常见的改变形状的方式有view(),resharp(),resize()

     ① view()

     view()返回的新Tensor与源Tensor共享内存,即更改其中一个,另外一个也会跟着改变(view仅仅是改变了对这个张量的观察视角)其次view()相当于把原张量中的所有向量都铺平展开为一个一维的向量,然后根据后面的参数进行重新组成新的性状。

x.view(a,b)    //其中a为向量数量,b为向量维数

若出现x.view(-1)或者x.view(length)其中length为tensor的一维结构长度,则原张量变为一维结构,若为x.view(a,-1),则表示在参数b未知,参数a已知的情况下自动补齐列向量长度。想要返回的是副本而且还改变了形状,可以使用clone()创造一个副本后再使用view:x_cp = x.clone().view()   使用clone还有好处就是会被记录在计算图中,梯度回传到副本时也会传到源Tensor

    ②resharp()

    所以若想返回一个真正新的副本,即不共享内存的,可以使用resharp()来改变形状,但此函数不能保证返回的是其拷贝,所以不推荐使用

    ③resize()

    ④item()可将一个标量Tensor转换成一个python number

 

(5)广播机制

       两个形状不同的Tensor按元素进行运算,会触发广播机制(broadcasting),例如x和y分别为1x2的张量与3x1的张量相加,则会将x中第一行的两个元素复制到第二行和第三行,而y中第一列的三个元素会复制到第二列,由此两个3x2的矩阵就可以按元素相加

(6)运算的内存开销

       索引,view这类运算不会开辟新内存,但是像y = x+y这类运算会开辟新内存,可以用id()函数来查看运算前后的对象的内存地址,会发现不一样,若想运算结果存到原来内存

       ① y[:] = x+y   可利用[:]来将结果写进y对应内存中

       ②torch.add(x,y,out=y)设置out属性来输出到y中

       ③y += x  或者   y.add_(x)    两者是一样的,pytorch中自增运算符和展开的加法算式不同

 (7)Tensor与Numpy中数组互相转换

     ①Tensor转Numpy:numpy()

     ②Numpy转Tensor:from_numpy()

     注:numpy(),from_numpy()产生的Tensor与Numpy中数组共享相同的内存,所以其中一个改变,另外一个也会改变,若想创建一个新内存,则可以用torch.tensor()将Numpy数组转              化为Tensor,其和原来数组不会共享内存

(8)Tensor在GPU上运行

     利用函数 to()来进行转换

(9)求梯度

    Tensor有一个属性为.requires_grad,若将其设置为true,则他可以追踪在其上的所有操作,完成计算后,可以利用

posted @ 2021-01-21 21:50  gausstu  阅读(426)  评论(0)    收藏  举报