动手学深度学习笔记第二章(预备知识)

研0深度学习小白,python也忘了很多,学习沐神的课程顺便记录一下笔记和自己遇到的一些疑问

2.1数据操作

  1. 求张量的形状和元素总数
x=torch.arange(12)
x.shape #  torch.size(12)
x.numel() # 12
  1. reshape 中的-1自动计算维度
x.reshape(-1,4)==x.reshape(3,4)
  1. torch.randn
torch.randn(3,4) #3行4列的均值为0标准差为1的正态分布矩阵
  1. 设置张量数据32位数
torch.arange(12,dtype=torch.float32)
  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.]]))
  1. x.sum()求和会得到一个单元素的张量
x.sum()
tensor(66.)
  1. 索引:区间左闭右开
  2. Y=Y+X会给Y分配新的内存,也就是换个位置,如果使用Y+=X或者创建一个与Y形状相同新矩阵Z,然后Z[:]=X+Y也可以。
Z=torch.zeros_like(Y)  #Z的创造方法
  1. tensor转化为ndarray和ndarray转化为tensor以及将大小为1的tensor转化为python标量
A=X.numpy() #X是张量
B=torch.tensor(A)
type(A),type(B)
a=torch.tensor([3.5])
a,a.item(),float(a),int(a)
(numpy.ndarray, torch.Tensor)
(tensor([3.5000]), 3.5, 3.5, 3)

2.2数据预处理

  1. 按位置取csv文件数据,并且用均值替换NaN项
inputs,outputs=data.iloc[:,0:2],data.iloc[:,2] #data就是取好的csv文件
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
  1. 离散值或类别值的NaN的处理方法
inputs=pd.get_dummies(inputs,dummy_na=True)
print(inputs)

dummy_na=True表示将NaN也设为一列,认为是NaN是数据的一种。

3.dataframe转化为tensor

X,y=torch.tensor(inputs.values),torch.tensor(outputs.values)
X,y
(tensor([[3., 1., 0.],
         [2., 0., 1.],
         [4., 0., 1.],
         [3., 0., 1.]], dtype=torch.float64),
 tensor([127500, 106000, 178100, 140000]))

2.3线性代数

  1. 分配新内存,将A克隆一份给B
B=A.clone()
  1. 两个矩阵相乘(A*B):对应元素相乘。
    如果将张量加上或者乘上一个标量:张量的每个元素都与标量相加或者相乘。
  2. sum的本质就是降维,axis=0:沿着第一个维度相加,最后第一个维度消失。axis=1:就是沿着第二个维度相加。
A.shape
A_sum_axis0=A.sum(axis=0)
A_sum_axis1=A.sum(axis=1)
A_sum_axis1,A_sum_axis0.shape
A_sum_axis0,A_sum_axis1.shape
(torch.Size([5, 4])
tensor([40., 45., 50., 55.]), torch.Size([4])
tensor([ 6., 22., 38., 54., 70.]), torch.Size([5]))

而sum(axis=[0,1])就是对前两个维度进行求和降维

A.sum(axis=[0,1])
tensor(190.)

同理,求平均值的函数也可以按维度降维:

A.mean(axis=0),A.sum(axis=0)/A.shape[0]
(tensor([ 8.,  9., 10., 11.]), tensor([ 8.,  9., 10., 11.]))

如果不想降维且求和,这样可以利用广播(标量不行):

sum_A=A.sum(axis=1,keepdims=True)
sum_A
tensor([[ 6.],
        [22.],
        [38.],
        [54.],
        [70.]])

此外递归求和函数cumsum也不会降低维度:

A
A.cumsum(axis=0)
tensor([[ 0.,  1.,  2.,  3.],
        [ 4.,  5.,  6.,  7.],
        [ 8.,  9., 10., 11.],
        [12., 13., 14., 15.],
        [16., 17., 18., 19.]])
tensor([[ 0.,  1.,  2.,  3.],
        [ 4.,  6.,  8., 10.],
        [12., 15., 18., 21.],
        [24., 28., 32., 36.],
        [40., 45., 50., 55.]])
  1. 点积:对于元素相乘并相加,也就是说会降维
x,y,torch.dot(x,y)
(tensor([0., 1., 2., 3.]), tensor([1., 1., 1., 1.]), tensor(6.))
  1. 矩阵和向量乘法和矩阵和矩阵乘法:
A.shape,x.shape,torch.mv(A,x)
B=torch.ones(4,3)
torch.mm(A,B)
(torch.Size([5, 4]), torch.Size([4]), tensor([ 14.,  38.,  62.,  86., 110.]))
tensor([[ 6.,  6.,  6.],
        [22., 22., 22.],
        [38., 38., 38.],
        [54., 54., 54.],
        [70., 70., 70.]])
  1. 范数可以简单理解成对向量的大小或者距离的估量,L2范数就是向量元素相加然后开平方,代码表示就是:
u=torch.tensor([3.0,-4.0])
torch.norm(u)
tensor(5.)

L1范数是绝对值之和:

torch.abs(u).sum()
tensor(7.)

矩阵F范数:所有元素的平方求和,很像矩阵形向量的L2范数:

torch.norm(torch.ones((4,9)))
tensor(6.)

2.4 微积分

  1. %matplotlib inline 语句作用:内嵌绘图,并且省略掉plt.show()。
  2. 绘图知识:
def use_svg_display():
    backend_inline.set_matplotlib_formats('svg')#矢量图表示,可以理解为让绘图更加清楚
def set_axes(axes,xlabel,ylabel,xlim,ylim,xscale,yscale,legend):
    axes.set_xlabel(xlabel)#xlabel是X轴的名称
    axes.set_ylabel(ylabel)
    axes.set_xscale(xscale)#x轴的缩放类型,一般默认是linear
    axes.set_yscale(yscale)
    axes.set_xlim(xlim)#X轴的数值范围
    axes.set_ylim(ylim)
    if legend:
        axes.legend(legend)#如果有legend(图例位置和名称是label和matlab不一样)
    axes.grid()#添加网格线
def plot(X,Y=None,xlabel=None,ylabel=None,legend=None,xlim=None,ylim=None,xscale='linear',yscale='linear',fmts=('-','m--','g-.','r:'),figsize=(3.5,2.5),axes=None):
    if legend is None:
        legend=[]
    set_figsize(figsize)
    axes=axes if axes else d2l.plt.gca()
    def has_one_axis(X):
        return (hasattr(X,"ndim")and X.ndim==1 or isinstance(X,list)
               and not hasattr(X[0],"__len__"))#数字没有len属性,这个就是要保证X轴是数字的
    if has_one_axis(X):
        X=[X]
    if Y is None:
        X,Y=[[]]*len(X),X#如果没有Y轴,那么画出X轴是X列表的个数Y轴是X列表值的图,将X置为空列表后续传参就可以了,是函数内部的约定。
    elif has_one_axis(Y):
        Y=[Y]
    if len(X)!=len(Y):
        X=X*len(Y)#如果不只有一个Y,那么就把X复制乘Y份,即一个函数一个X列表相对应。
    axes.cla()#axes.cla()只清理绘图区
    for x,y,fmt in zip(X,Y,fmts):
        if len(x):
            axes.plot(x,y,fmt)
        else:
            axes.plot(y,fmt)#X轴是空列表
    set_axes(axes,xlabel,ylabel,xlim,ylim,xscale,yscale,legend)             

2.5自动微分

  1. 求梯度很耗内存,所以要对参数指定,后面才能求导:
x=torch.arange(4.0)
x.requires_grad_(True)#等价于x=torch.arange(4.0,requires_grad=True)

然后就可以开始求导:

x.grad#此时是默认值:None
y=2*torch.dot(x,x)
y
tensor(28., grad_fn=<MulBackward0>)#grad_fn表示记录了y由x计算的过程,后面就可以反向传播了。
y.backward()#反向传播
x.grad#计算x的梯度
tensor([ 0.,  4.,  8., 12.])
  1. 由于pytorch会累积梯度,所以我们计算新的x的梯度的时候就要清除之前的值
x.grad.zero_()
  1. python控制流函数一样可以计算梯度:
def f(a):
    b=a*2
    while b.norm()<1000:
        b=b*2
    if b.sum()> 0:
        c=b
    else:
        c=100*b
    return c
a=torch.randn(size=(),requires_grad=True)
d=f(a)
d.backward()
a.grad==d/a
tensor(True)
  1. detach()函数可以丢弃计算图中信息,生成一个常数,反向传播的时候就会停止到detach的tensor这里,不会向后流经到最底层的参数。
y=x*x
u=y.detach()
z=u*x
z.sum().backward()
x.grad==u
tensor([True, True, True, True])

2.6概率论

  1. 模拟骰子函数:
from torch.distributions import multinomial
fair_probs=torch.ones([6])/6
multinomial.Multinomial(10,fair_probs).sample()
multinomial.Multinomial(1000,fair_probs).sample() #1000是指实验次数,fair_probs是指给每一种的结果进行概率赋值
counts/1000
tensor([2., 3., 2., 2., 0., 1.])
tensor([0.1660, 0.1540, 0.1560, 0.1900, 0.1700, 0.1640])
  1. help查找特定函数的用法
    动手学深度学习笔记第二章(预备知识)_第1张图片

你可能感兴趣的:(我的动手学深度学习笔记,深度学习,python,numpy)