《动手学深度学习》(PyTorch版)
书本结构
书本结构

想短时间了解深度学习最基础的概念和技术,只需阅读第1章至第3章;

如果读者希望掌握现代深度学习技术,还需阅读第4章至第6章。

第7章至第10章读者可以根据兴趣选择阅读。

深度学习简介

机器学习是一门讨论各式各样的适用于不同问题的函数形式,如何使用数据来有效地获取函数参数具体值的学科。

深度学习是指机器学习中的一类函数,它们的形式通常为多层神经网络。

绝大多数神经网络都包含以下的核心原则

  • 交替使用线性处理单元与非线性处理单元,它们经常被称为“层”。
  • 使用链式法则(即反向传播)来更新网络的参数。

CPU和GPU区别:

CPU需要很强的通用性来处理各种不同的数据类型,同时又要逻辑判断又会引入大量的分支跳转和中断的处理。这些都使得CPU的内部结构异常复杂。GPU面对的则是类型高度统一的、相互无依赖的大规模数据和不需要被打断的纯净的计算环境。

Cache, local memory: CPU > GPU

Threads(线程数): GPU > CPU

Registers: GPU > CPU 多寄存器可以支持非常多的Thread,thread需要用到register,thread数目大,register也必须得跟着很大才行。

SIMD Unit(单指令多数据流,以同步方式,在同一时间内执行同一条指令): GPU > CPU。

参考:https://www.cnblogs.com/biglucky/p/4223565.html

存储容量没能跟上数据量增长的步伐,计算力的增长又盖过了数据量的增长。这样的趋势使得统计模型可以在优化参数上投入更多的计算力,但同时需要提高存储的利用效率,例如使用非线性处理单元。这也相应导致了机器学习和统计学的最优选择从广义线性模型及核方法变化为深度多层神经网络。

注意力机制使用了一个可学习的指针结构来构建出一个精妙的解决方法。

记忆网络神经编码器—解释器这样的多阶设计使得针对推理过程的迭代建模方法变得可能。

生成对抗网络,关键创新在于将采样部分替换成了任意的含有可微分参数的算法。

并行计算的能力也为至少在可以采用模拟情况下的强化学习的发展贡献了力量。


特点

机器学习研究如何使计算机系统利用经验改善性能。表征学习关注如何自动找出表示数据的合适方式,以便更好地将输入变换为正确的输出。在每一级(从原始数据开始),深度学习通过简单的函数将该级的表示变换为更高级的表示。

深度学习可以逐级表示越来越抽象的概念或模式。以图像为例,它的输入是一堆原始像素值。深度学习模型中,图像可以逐级表示为特定位置和角度的边缘、由边缘组合得出的花纹、由多种花纹进一步汇合得到的特定部位的模式等。最终,模型能够较容易根据更高级的表示完成给定的任务,如识别图像中的物体。作为表征学习的一种,深度学习将自动找出每一级表示数据的合适方式。

深度学习的一个外在特点是端到端的训练。也就是说,并不是将单独调试的部分拼凑起来组成一个系统,而是将整个系统组建好之后一起训练。

除端到端的训练以外,正在经历从含参数统计模型转向完全无参数的模型。当数据非常稀缺时,我们需要通过简化对现实的假设来得到实用的模型。当数据充足时,我们就可以用能更好地拟合现实的无参数模型来替代这些含参数模型。这也使我们可以得到更精确的模型,尽管需要牺牲一些可解释性。

相对其它经典的机器学习方法而言,深度学习的不同在于:对非最优解的包容、对非凸非线性优化的使用,以及勇于尝试没有被证明过的方法。

预备知识

环境配置

Anaconda

Anaconda中增加了conda install命令,conda install会比pip install更方便一些。

最省心的Python版本和第三方库管理——初探Anaconda

Anaconda是Python的一个开源发行版本,主要面向科学计算。

修改其包管理镜像为国内源

conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --set show_channel_urls yes

现在安装的是最新版Anaconda3,其自带的Python版本为3.6,如果我们需要添加2.7版本的Python,可以进行如下操作。

conda create -n py27 python=2.7

其中py27是新添加环境的名字,可以自定义修改。

之后通过activate py27和deactivate py27命令激活、退出该环境。(Linux和OS系统的命令似乎是source activate和source deactivate)

activate py27

在激活新环境后,我们所做的操作便都是在新环境下的,包括pip命令来安装第三方库。我们来试一下pip安装lxml。

pip install lxml

那么正确的做法是什么呢?一条命令就够了。

conda install -n py27 lxml

对于可以正常安装的库,自然可以使用pip命令。

pip install requests

通过conda info -e命令查看已有的环境

通过conda remove -n env_name --all来删除指定的环境(如果不添--all参数,而是指明某个库名,则是删除该库)

如果想要给Jupyter添加多个Python版本的kernel,有两种做法。

如果这个Python版本已经存在(比如我们刚才添加的py27环境),那么你可以直接为这个环境安装ipykernel包。即:

conda install -n py27 ipykernel

然后激活这个环境,输入

python -m ipykernel install --user

初学 Python 者自学 Anaconda 的正确姿势-猴子的回答

Anaconda 和 Jupyter(包括Jupyter Notebook和JupyterLab,其中JupyterLab是从Notebook发展而来的)已成为数据分析的标准环境。

Anaconda是包管理器和环境管理器,Jupyter可以将数据分析的代码、图像和文档全部组合到一个web文档中。

你可能已经安装了 Python,那么为什么还需要 Anaconda?有以下3个原因:

1)Anaconda 附带一大批常用数据科学包

附带了 conda、Python 和 150 多个科学包及其依赖项。

2)管理包

Anaconda 是在 conda(一个包管理器和环境管理器)上发展出来的。

在数据分析中,你会用到很多第三方的包,而conda(包管理器)可以很好的帮助你在计算机上安装和管理这些包,包括安装、卸载和更新包。

3)管理环境

比如你在A项目中用了 Python 2,而新的项目B老大要求使用Python 3,而同时安装两个Python版本可能会造成许多混乱和错误。这时候 conda就可以帮助你为不同的项目建立不同的运行环境。

还有很多项目使用的包版本不同,比如不同的pandas版本,不可能同时安装两个 Numpy 版本,你要做的应该是,为每个 Numpy 版本创建一个环境,然后项目的对应环境中工作。这时候conda就可以帮你做到。

Jupyter

notebook可以直接在代码旁写出叙述性文档,而不是另外编写单独的文档。也就是它可以能将代码、文档等这一切集中到一处,让用户一目了然。能让用户将说明文本、数学方程、代码和可视化内容全部组合到一个易于共享的文档中。

jupyter notebook-猴子的回答

打开jupyter notebook

jupyter notebook 

这时在浏览器打开 http://localhost:8888 (通常会自动打开)位于当前目录的jupyter服务。

PyTorch

2.2数据操作

在PyTorch中,torch.Tensor是存储和变换数据的主要工具。Tensor和NumPy的多维数组非常类似。然而,Tensor提供GPU计算自动求梯度等更多功能,这些使Tensor更加适合深度学习。

2.2.1创建Tensor

2.2.2操作

  • 算术操作

    加法

  • 索引

    索引出来的结果与原数据共享内存,也即修改一个,另一个会跟着修改。

  • **改变形状 **

    注意view()返回的新Tensor与源Tensor虽然可能有不同的size,但是是共享data的,也即更改其中的一个,另外一个也会跟着改变。(顾名思义,view仅仅是改变了对这个张量的观察角度,内部数据并未改变) 推荐先用clone创造一个副本然后再使用view 另外一个常用的函数就是item(), 它可以将一个标量Tensor转换成一个Python number

  • 线性代数

2.2.3广播机制

当对两个形状不同的Tensor按元素运算时,可能会触发广播(broadcasting)机制:先适当复制元素使这两个Tensor形状相同后再按元素运算。

2.2.4运算的内存开销

索引操作是不会开辟新内存的,而像y = x + y这样的运算是会新开内存的,然后将y指向新内存。可以使用Python自带的id函数:如果两个实例的ID一致,那么它们所对应的内存地址相同;反之则不同。

2.2.5 Tensor和NumPy相互转换

用numpy()和from_numpy()将Tensor和NumPy中的数组相互转换。但是需要注意的一点是: 这两个函数所产生的的Tensor和NumPy中的数组共享相同的内存(所以他们之间的转换很快),改变其中一个时另一个也会改变!!!

还有一个常用的将NumPy中的array转换成Tensor的方法就是torch.tensor(), 需要注意的是,此方法总是会进行数据拷贝(就会消耗更多的时间和空间),所以返回的Tensor和原来的数据不再共享内存。

  • Tensor转NumPy

    使用numpy()将Tensor转换成NumPy数组

  • NumPy转Tensor

    使用from_numpy()将NumPy数组转换成Tensor

    所有在CPU上的Tensor(除了CharTensor)都支持与NumPy数组相互转换。

    此外上面提到还有一个常用的方法就是直接用torch.tensor()将NumPy数组转换成Tensor,需要注意的是该方法总是会进行数据拷贝,返回的Tensor和原来的数据不再共享内存。

2.2.6 Tensor on GPU

用方法to()可以将Tensor在CPU和GPU(需要硬件支持)之间相互移动。