在你开始学习之前,首先要想清楚自己是为什么而学。

请一定给自己一个足够说服你行动的理由。

在开始我的分享之前,我想回答几个自问自答的问题:

  1. 为什么要用网站分享,而不是PPT? 答:这个问题我思考了很久,因为不使用PPT进行分享是不合常理的,甚至是对老师和同学不尊重的行为,但思考了很久之后我认为这个网站的存在是永久的,易于你在随时随地查看这些内容,甚至你在工作的时候需要查看某项函数的时候都可以点开看。从实用性来看,我坚持使用网站进行分享。

  2. 你的分享逻辑和原则是什么? 答:你可以通过网页右侧的目录来查看我的分享大纲,其中有些部分不适合展开细讲的,我都会给出一个链接适合有需要的同学点开钻研。

我的大致分享思路如下:

  1. 介绍conda
  2. 介绍Jupyter
  3. 介绍Pandas,Numpy,Matplotlib
  4. 预备知识的回顾
  5. 预备知识的继续

介绍conda

Conda是一个管理版本和Python环境的工具,它使用起来非常容易。

Conda包安装之后,需要添加环境变量才可以在命令行里调用。

  • 为什么要配置环境变量?

根据Windows系统在查找可执行程序的原理,只会从当前文件夹下执行目标文件(比如SDK中的解释器,用于语言的编译),因此只有加上环境变量,就能让操作系统方便在任何目录下都能执行目标文件。 -来自CSDN博主一夜星尘

关于环境变量的详细配置在这里

  • conda 创建环境
1
2
# 创建一个名为miaomiao的环境,指定Python版本是3.5
conda create --name miaomiao python=3.5
  • conda 激活环境
1
activate miaomiao
  • conda 删除环境
1
conda remove --name miaomiao --all
  • conda 查看系统中所有的环境
1
2
3
4
5
6
conda info -e
#outputs:
#
base * D:\study\Anaconda
d2l D:\study\Anaconda\envs\d2l
ding D:\study\Anaconda\envs\ding

Anaconda是一个免费、易于安装的包管理器、环境管理器(包含conda)和Python发行版。包含1,500多个开源包,并提供免费社区支持。

关于更详尽的conda介绍在这里

介绍Jupyter

Jupyter Notebook是基于网页的用于交互计算的应用程序。其可被应用于全过程计算:开发、文档编写、运行代码和展示结果。——Jupyter Notebook官方介绍

Z_981~LY7B_5GXD@_@_68XU.png

-Jupyter的操作页面

Jupyter Notebook以网页的形式打开,可以在网页页面中直接编写代码和运行代码,代码的运行结果也会直接在代码块下显示的程序。如在编程过程中需要编写说明文档,可在同一个页面中直接编写,便于作及时的说明和解释。 Jupyter的部分贡献者

-Jupyter的部分贡献者

Jupyter由网页应用和文档两部分组成,其中每一行代码都可以单独给出结果,适合于进行代码的学习和授课。

Jupyter的基本操作

事实上,我们在Jupyter上的很多操作都是利用快捷键完成的。常用的快捷键如下: 6KB0289IFZ_HXTTIFM5GB_1.png

-常用的Jupyter操作快捷键

我们可以使用os包来查看当前工作的目录

1
2
3
import os

os.getcwd()

完整版可以在Jupyter的操作页面的Help–Keyboard Shortcuts中找到。

如何在Jupyter Notebook中使用Python虚拟环境

Python虚拟环境的出现是因为Python目前有两个版本共存。

虽然Python 3有许多优于Python 2的特性,但是Python 2的生态系统更为完善,支持的包更多。因为生态系统内部的依赖关系,许多软件包的运行说明会直接指定“仅适用于Python 2.7版本”。

我们可以很容易的在电脑里建立起多个虚拟环境,利用conda即可完成,但是在这里建立的环境并不适用于Jupyter,为了让Jupyter Notebook支持虚拟运行环境,需要在Anaconda里安装一个插件。

他的名字叫做:ipykernel

1
2
3
4
5
6
7
8
9
10
11
12
conda create --name miaomiao python=3.9
#新建一个喵喵环境,注意这里一定要定好python版本

conda activate miaomiao
#激活你要的本地环境,例如:miaomiao

conda install ipykernel
#安装ipykernel

python -m ipykernel install --user --name 本地环境名称 --display-name "在jupyter上显示的环境名称"
#将你刚才激活的环境**注入**到Jupyter

之后我们点开任意文档都可以在kernel中切换成该环境。

我们可以直接使用anconda进行安装和使用,其中默认的环境是base,我们可以手动更改环境。

关于更详尽的Jupyter介绍在这里

简单介绍Pandas和Numpy,Matplotlib

  • Numpy是Python语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。最重要的一个特点是其 N 维数组对象ndarray,它是一系列同类型数据的集合,以0下标为开始进行集合中元素的索引。其ndarray与torch有相似之处且可以互相转化,torch被誉为神经网络界的numpy,torch本身利用GPU(图形处理器)进行加速,numpy则是利用CPU(中央处理器)进行加速。
  • Pandas也是Python语言的一个扩展程序库,是基于numpy的强大的分析结构化数据的工具集。主要数据结构是Series(一维数据)与DataFrame(二维数据)。
  • Matplotlib是Python的绘图库。

以上拓展库都可以使用pip(推荐)或者conda进行安装。

预备知识

数据操作

数据操作的基础:

  • 获取和存储数据
  • 处理数据

我们使用tensor(张量)进行操作,其类似于Numpy中的ndarray,但由于GPU加速计算和一些额外的重要功能使得tensor更适合深度学习。 那么为什么机器学习要使用GPU进行加速呢?GPU和CPU的区别在哪里? v2-75cdb098e645c614492746417b457c13_1440w.jpg

  • GPU与CPU的区别 关于更详尽的介绍在这里

  • 安装深度学习框架和d2l软件包 使用pip或conda安装PyTorch的CPU或GPU版本:

1
2
pip install torch
pip install torchvision #处理图像数据

然后安装d2l包,以方便调取机器学习中常用的函数和类:

1
pip install d2l

入门

在此用例子来复习一些tensor的基本用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import torch

import matplotlib as plt

x = torch.arange(12)

x.shape
#output: torch.Size([12])

X = x.reshape(3,4)
X
#output: tensor([[0,1,2,3],
[4,5,6,7],
[8,9,10,11]])

torch.zeros((2,3,4))
#这里类似于ndarray

Y = torch.randn(3,4)
Y

X[-1] #最后一个元素
X[1:3] #第二个元素
X[1,2] #第二行第三列的元素
X[0:2,:] #第一行到第二行,选择全部列。

在此需要注意,在numpy和torch创建列表的区别,两者都可以使用np.zeros()或者torch.zeros()创建空列表,但是np必须加上[],例如

np.zeros([1,2,3])

但是np.zeros(1,2,3)就会报错。

而torch则兼容,建议在日常中使用[]。

运算符

1
2
3
4
5
6
7
8
9
x = torch.tensor([1.0, 2, 4, 8])

y = torch.tensor([2, 2, 2, 2])

x + y, x - y, x * y, x / y, x ** y
# **运算符是求幂运算,基础运算

torch.exp(x)
#求幂

除按照元素计算,我们还可以以执行线性代数运算,包括向量点积和矩阵乘法。

如下介绍张量连接:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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)

#outputs:
(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.]
]))

dim=0按照轴0,即行进行连接,dim=1按照轴1,即列连接。

X.sum()表示求和

广播机制

在张量形状不同的情况下,我们仍然可以通过调用广播机制(broadcasting mechanism)来执行按元素操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
a = torch.arange(3).reshape((3, 1))
b = torch.arange(2).reshape((1, 2))
a, b
#outputs:
(tensor([[0],
[1],
[2]]),
tensor([[0, 1]]))

a + b
#outputs:
tensor([[0, 1],
[1, 2],
[2, 3]])

需要注意的是,广播机制的扩展是有一定规律的,其详细的广播机制可以在这个网站里找到。

其大致方式为:

  1. 比较两个数组从后往前,维度是否相等或者为1。否则无法广播。
  2. 若为1,则扩展到相同的维度,以此依次进行,直到维度相等。

索引

在前面已经提过

内存节省

Y = X + Y

1
2
3
4
5
6
7
before = id(kitty)
kitty = kitty + neutered
id(kitty) == before

#output:
False
小猫被分到了另一个房间,这样就造成房间的不必要分配。

我们使用切片表示来将操作结果分配给先前数组:

1
2
3
4
5
6
7
8
9
10
11
12
Z = torch.zeros_like(Y)
print('id(Z):',id(Z))
Z[:] = X + Y
print('id(Z):',id(Z))
#outputs:
两个Z的地址一样
如果后续不需要使用X,那么我们使用X[:] = X + Y或者X += Y(Python本身的赋值运算符)也同样可以节省内存:
before = id(X)
X += Y
id(X) == before
#output:
True

转换为其他python对象

深度学习中,我们使用定义的张量可以转化为Numpy中的ndarray,并且共享同一个内存(部分共享)。会同时被更改:

1
2
3
4
5
6
7
8
9
10
11
A = X.numpy()
B = torch.tensor(A)

type(A),type(B),
#outputs:
(numpy.ndarray,torch.tensor)

a = torch.tensor([3.5])
a, a.item, float(a), int(a)
#outputs:
(tensor([3.5000], 3.5, 3.5, 3))

其实我们也可以从numpy中创建tensor,利用torch.from_numpy进行创建:

1
2
3
4
5
6
7
8
9
10
11
12
13
ndarray1 = np.array([[1,2,3],[4,5,6]])

tensor1 = torch.from_numpy(ndarray1)

ndarray1

tensor1
#outputs:
array([[1,2,3],
[4,5,6]])

tensor([[1, 2, 3],
[4, 5, 6]], dtype=torch.int32)

数据预处理

我们使用pandas包(与tensor兼容)进行数据的原始预处理:

读取数据集

我们利用os包进行操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import os

os.getcwd()#查看当前工作目录

os.makedirs(os.path.join('..','data'),exist_ok = True)
my_file = os.path.join('..','data','houses.csv')
with open(my_file,'w') as f:#'w'和'wb'表示写入文本文件或者二进制文件
f.write('NumRooms,Alley,Price\n') # 列名
f.write('NA,Pave,127500\n')
f.write('2,NA,106000\n')
f.write('4,NA,178100\n')
f.write('NA,NA,140000\n')

import pandas as pd

data = pd.read_csv(my_file)
print(data)

处理缺失值

我们在此考虑插值法处理缺失值。 通过位置索引iloc,我们将data分成inputs和outputs,其中前者为data的前两列,⽽后者为data的最后一列。对于inputs中缺少的数值,我们用同一列的均值替换“NaN”项。

1
2
3
inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]
inputs = inputs.fillna(inputs.mean())
print(inputs)

结果如下:

NumRooms Alley
0 3.0 Pave
1 2.0 NaN
2 4.0 NaN
3 3.0 NaN

由于“巷子类型”(“Alley”)列只有两种类型的类别值“Pave”和“NaN”,pandas自动将此列转换为两列“Alley_Pave”和“Alley_nan”。

巷子类型为“Pave”的行会将“Alley_Pave”的值设置为1,“Alley_nan”的值设置为0。

缺少巷子类型的行会将“Alley_Pave”和“Alley_nan”分别设置为0和1。

1
2
inputs = pd.get_dummies(inputs, dummy_na=True)
print(inputs)
NumRooms Alley_Pave Alley_nan
0 3.0 1 0
1 2.0 0 1
2 4.0 0 1
3 3.0 0 1