动手深度学习——Pytorch 入门语法一

持续更新ing

数据操作

import torch

x = torch.arange(12) # 创建⼀个⾏向量x。这个⾏向量包含从0开始的前12个整数
print(x.shape)  # 通过张量的shape属性来访问张量(沿每个轴的⻓度)的形状。
print(x.numel())  # 检查它的⼤小(size)

X = x.reshape(3,4)
print(X)
print(x.view(3,4))# 输出和上面一样。
# view()和reshape()功能一样,都可以改变张量形状。

z = torch.zeros((2,3,4)) # 全零张量
print(z)

z1 = torch.ones((2,3,4)) # 全1张量
print(z1)

randomNumber = torch.randn(3,4) # 创建⼀个形状为(3,4)的张量。其中的每个元素都从均值为0、标准差为1的标准⾼斯分布(正态分布)中随机采样

print(torch.tensor([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])) # 给张量直接赋值


import torch

x= torch.tensor([1.0, 2, 4, 8])
y = torch.tensor([2,2,2,2])
print(x+y,x-y,x*y,x/y, x**y) # **运算符是求幂运算

print(torch.exp(x)) # 计算e的幂

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) # 横向连接,增加列

print(X == Y) # 结果为Ture 和 False

print(X.sum())  # 张量内元素求和
a = torch.arange(3).reshape((3,1))
b = torch.arange(2).reshape((1,2))

print(a,b)
print(a + b) # 沿着数组中⻓度为1的轴进⾏⼴播,矩阵a将复制列,矩阵b将复制⾏,然后再按元素相加。

print(X[-1],X[1:3]) # 索引和切片,与列表相似

X[1,2] = 9 # 指定索引来将元素写⼊矩阵。
print(X)

X[0:2,:] = 12 # 为多个元素赋值相同的值
print(X)


A =X.numpy() # 将深度学习框架定义的张量转换为NumPy张量(ndarray)
B = torch.tensor(A)
print(type(A), type(B))

a = torch.tensor([3.5])
print(a,a.item(), float(a), int(a)) #将⼤小为1的张量转换为Python标量

A = torch.arange(20).reshape((5,4))

print(A)
print(A.T) # 转置

A = torch.arange(20,dtype=torch.float32).reshape(5,4)
B = A.clone() # 通过分配新内存,将A的⼀个副本分配给B
print(A,A+B)
Tensor的合并与拆分

在这里插入图片描述
对于需要拼接的张量,维度数量必须相同,进行拼接的维度的尺寸可以不同,但是其它维度的尺寸必须相同。

>>> import torch
>>> x = torch.randn(2, 3)
>>> x
tensor([[-0.1997, -0.6900,  0.7039],
        [ 0.0268, -1.0140, -2.9764]])
>>> torch.cat((x, x, x), 0)	# 在 0 维(纵向)进行拼接,可以将一个张量序列进行合并。
tensor([[-0.1997, -0.6900,  0.7039],
        [ 0.0268, -1.0140, -2.9764],
        [-0.1997, -0.6900,  0.7039],
        [ 0.0268, -1.0140, -2.9764],
        [-0.1997, -0.6900,  0.7039],
        [ 0.0268, -1.0140, -2.9764]])
>>> torch.cat((x, x, x), 1)	# 在 1 维(横向)进行拼接
tensor([[-0.1997, -0.6900,  0.7039, -0.1997, -0.6900,  0.7039, -0.1997, -0.6900,
          0.7039],
        [ 0.0268, -1.0140, -2.9764,  0.0268, -1.0140, -2.9764,  0.0268, -1.0140,
         -2.9764]])
>>> y1 = torch.randn(5, 3, 6)
>>> y2 = torch.randn(5, 3, 6)
>>> torch.cat([y1, y2], 2).size()
torch.Size([5, 3, 12])
>>> torch.cat([y1, y2], 1).size()
torch.Size([5, 6, 6])

沿着一个新维度对输入张量序列进行连接。 序列中所有的张量都应该为相同形状

>>> x1 = torch.randn(2, 3)
>>> x2 = torch.randn(2, 3)
>>> torch.stack((x1, x2), 0).size()	# 在 0 维插入一个维度,进行区分拼接。也可以对一个张量序列进行拼接,即将多个相同维度的张量合并到一个高维度的张量中。
torch.Size([2, 2, 3])
>>> torch.stack((x1, x2), 1).size()	# 在 1 维插入一个维度,进行组合拼接
torch.Size([2, 2, 3])
>>> torch.stack((x1, x2), 2).size()
torch.Size([2, 3, 2])
>>> torch.stack((x1, x2), 0)
tensor([[[-0.3499, -0.6124,  1.4332],
         [ 0.1516, -1.5439, -0.1758]],

        [[-0.4678, -1.1430, -0.5279],
         [-0.4917, -0.6504,  2.2512]]])
>>> torch.stack((x1, x2), 1)
tensor([[[-0.3499, -0.6124,  1.4332],
         [-0.4678, -1.1430, -0.5279]],

        [[ 0.1516, -1.5439, -0.1758],
         [-0.4917, -0.6504,  2.2512]]])
>>> torch.stack((x1, x2), 2)
tensor([[[-0.3499, -0.4678],
         [-0.6124, -1.1430],
         [ 1.4332, -0.5279]],

        [[ 0.1516, -0.4917],
         [-1.5439, -0.6504],
         [-0.1758,  2.2512]]])

数据预处理

import torch

A = torch.arange(20,dtype=torch.float32).reshape(5,4)
B = A.clone() # 通过分配新内存,将A的⼀个副本分配给B
print(A,'\n',A+B)

print(A*B) # 两个矩阵的按元素乘法称为Hadamard积

# 将张量乘以或加上⼀个标量不会改变张量的形状,其中张量的每个元素都将与标量相加或相乘。
a = 2
X = torch.arange(24).reshape(2,3,4)
print(a+X,'\n', (a*X).shape)

x= torch.arange(4,dtype=torch.float32)
print(x,'\n',x.sum())

'''为了通过求和所有⾏的元素来降维(轴0),我们可以在调⽤函数时指定axis=0。
由于输⼊矩阵沿0轴降维以⽣成输出向量,因此输⼊轴0的维数在输出形状中消失。'''
A_sum_axis0=A.sum(axis=0)
print(A_sum_axis0)
print(A_sum_axis0.shape)

# 指定axis=1将通过汇总所有列的元素降维(轴1)。因此,输⼊轴1的维数在输出形状中消失。
A_sum_axis1=A.sum(axis=1)
print(A_sum_axis1)
print(A_sum_axis1.shape)

# 沿着⾏和列对矩阵求和,等价于对矩阵的所有元素进⾏求和。
print(A.sum(axis=[0,1]))
print(A.sum()) # 和上面一句等价,所有元素求和

# 平均值
print(A.mean(),A.sum()/A.numel())

# 计算平均值的函数也可以沿指定轴降低张量的维度。
print(A.mean(axis=0),A.sum(axis=0)/A.shape[0])

# 计算总和或均值时保持轴数不变
sum_A = A.sum(axis=1,keepdims=True)
print(sum_A)

# 由于sum_A在对每⾏进⾏求和后仍保持两个轴,我们可以通过⼴播将A除以sum_A。
print(A/sum_A)

'''如果我们想沿某个轴计算A元素的累积总和,⽐如axis=0(按⾏计算),我们可以调⽤cumsum函数。此函数
不会沿任何轴降低输⼊张量的维度'''
print(A.cumsum(axis=0))

# 点积
y = torch.ones(4,dtype=torch.float32)
print(x)
print(y)
print(torch.dot(x,y))

'''在代码中使⽤张量表⽰矩阵-向量积,我们使⽤与点积相同的mv函数.
注意,A的列维数(沿轴1的⻓度)必须与x的维数(其⻓度)相同。'''
print('矩阵向量积')
print(A.shape)
print(x.shape)
print(torch.mv(A,x))


'''将矩阵-矩阵乘法AB看作是简单地执⾏m次矩阵-向量积,并将结果拼接在⼀起,形成⼀个n*m矩阵。'''
B = torch.ones(4,3)
print(torch.mm(A,B))

# 范数
u = torch.tensor([3.0, -4.0])
print(torch.norm(u)) #这里使用的范数默认是第二范数L2

print(torch.abs(u).sum()) # 计算第一范数L1

# Frobenius范数(Frobenius norm)是矩阵元素平⽅和的平⽅根,它就像是矩阵形向量的L2范数
print(torch.norm(torch.ones((4,9))))
torch.matmul(a,b)——高维矩阵乘积
import torch

a = torch.ones(3,4)
print("a:",a)
b = torch.ones(4,2)
print("b:", b)

print(torch.matmul(a, b))

运行截图
在这里插入图片描述

维数相同的高维张量相乘
要求第一维度相同,后两个维度能满足矩阵相乘条件。
A.shape =(b,m,n);B.shape = (b,n,k)
numpy.matmul(A,B) 结果shape为(b,m,k)

import torch

a = torch.ones(3,1,2)
print(a)
b = torch.ones(3,2,2)
print(b)

print(torch.matmul(a, b))

运行截图
在这里插入图片描述

维数不同的高维张量相乘
比如 A.shape =(m,n); B.shape = (b,n,k); C.shape=(k,l)
numpy.matmul(A,B) 结果shape为(b,m,k)
numpy.matmul(B,C) 结果shape为(b,n,l)
2D张量要和3D张量的后两个维度满足矩阵相乘条件。

import torch

a = torch.ones(1, 2)
print("a:",a)
b = torch.ones(2, 2, 3)
print("b:",b)
c = torch.ones(3, 1)
print("c:",c)

print("a*b:",torch.matmul(a, b))
print("b*c:",torch.matmul(b, c))

运行截图
在这里插入图片描述

微积分

import torch

import numpy as np
from IPython import display
from d2l import torch as d2l


def f(x):
    return 3*x**2-4*x

def numerical_lim(f,x,h):
    return (f(x+h)-f(x))/h

h=0.1
for i in range(5):
    print(f'h={h:.5f},numerical_lim={numerical_lim(f,1,h):.5f}')
    h *= 0.1



def use_svg_display(): #@sava
    '''使用svg格式显示绘图'''
    display.set_matplotlib_formats('svg')

def set_figsize(figsize=(3.5,2.5)): #@save
    '''设置matplotlib的图表大小'''
    use_svg_display()
    d2l.plt.rcParams['figure.figsize'] = figsize

def set_axes(axes,xlabel, ylabel,xlim, ylim, xscale, yscale, legend):
    '''设置matplotlib的轴'''
    axes.set_xlabel(xlabel)
    axes.set_ylabel(ylabel)
    axes.set_xscale(xscale)
    axes.set_yscale(yscale)
    axes.set_xlim(xlim)
    axes.set_ylim(ylim)
    if legend:
        axes.legend(legend)
    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()


    #如果'X'有一个轴,输出True
    def has_one_axis(X):
        return (hasattr(X, 'ndim') and X.ndim == 1 or isinstance(X, list) and not
                hasattr(X[0], '__len__'))
    if has_one_axis(X):
        X=[X]
    if Y is None:
        X,Y = [[]]*len(X),X
    elif has_one_axis(Y):
        Y = [Y]
    if len(X) != len(Y):
        X = X*len(Y)
    axes.cla()
    for x, y, fmt in zip(X, Y, fmts):
        if len(x):
            axes.plot(x,y, fmt)
        else:
            axes.plot(y,fmt)
    set_axes(axes,xlabel,ylabel,xlim, ylim,xscale,yscale,legend)
    d2l.plt.show()

x = np.arange(0,3,0.1)
plot(x,[f(x), 2*x-3], 'x', 'f(x)', legend=['f(x)', 'Tangent line (x=1)'])

在这里插入图片描述

自动微分
'''
python3.7
-*- coding: UTF-8 -*-
@Project -> File   :Code -> __init__.py
@IDE    :PyCharm
@Author :YangShouWei
@USER: 296714435
@Date   :2022/2/19 10:19:49
@LastEditor:
'''

import torch

x = torch.arange(4.0)
print("x:",x)

x.requires_grad_(True) # 等价于x = torch.arange(4.0, requires_grad=True)
print("x.grad:",x.grad) # 默认值是None

y = 2*torch.dot(x,x)
print("y:",y)

# 调⽤反向传播函数来⾃动计算y关于x每个分量的梯度.
y.backward() # 反向传播
x.grad
print("x.grad:",x.grad)

x.grad.zero_()
y = x.sum()
y.backward()
print("x.grad:",x.grad)

# 非标量变量的反向传播
#对⾮标量调⽤`backward`需要传⼊⼀个`gradient`参数,该参数指定微分函数关于`self`的梯度。
# 在我们的例⼦中,我们只想求偏导数的和,所以传递⼀个1的梯度是合适的
x.grad.zero_()
y = x*x

# 等价于y.backward(torch.ones(len(x)))
y.sum().backward()
print("x.grad:",x.grad)

x.grad.zero_() # 梯度置0
y = x*x
u = y.detach()
z = u*x
z.sum().backward()
print("x.grad==u:",x.grad==u)

# 由于记录了y的计算结果,我们可以随后在y上调⽤反向传播,得到y=x*x关于的x的导数,即2*x。
x.grad.zero_()
y.sum().backward()
print("x.grad == 2*x:",x.grad == 2*x)

# 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()

print("a.grad == d/a:",a.grad == d/a)


运行截图
在这里插入图片描述

概率

基本概率论
'''
python3.7
-*- coding: UTF-8 -*-
@Project -> File   :Code -> probability
@IDE    :PyCharm
@Author :YangShouWei
@USER: 296714435
@Date   :2022/2/19 14:46:22
@LastEditor:
'''

import torch
from torch.distributions import multinomial
from d2l import torch as d2l

# 为了抽取⼀个样本,即掷骰⼦,我们只需传⼊⼀个概率向量。
# 输出是另⼀个相同⻓度的向量:它在索引i处的值是采样结果中i出现的次数。

fair_prob = torch.ones([6]) / 6 # 表示骰子的六个面被掷到的概率都是1/6
print(multinomial.Multinomial(1,fair_prob).sample()) # 相当于掷骰子一次,掷到哪个数字,对应位置就显示1,

print(multinomial.Multinomial(10,fair_prob).sample()) # 相当于掷骰子10次,打印的结果是每个面被掷到的次数

counts = multinomial.Multinomial(1000,fair_prob).sample()
print(counts/1000) # 相对频率作为估计值


# 进行500组实验,每组抽取10个样本
counts = multinomial.Multinomial(10,fair_prob).sample((500,))
cum_counts = counts.cumsum(dim=0)
estimates = cum_counts / cum_counts.sum(dim=1, keepdims=True)

d2l.set_figsize((6, 4.5))
for i in range(6):
    d2l.plt.plot(estimates[:, i].numpy(),
                 label=("P(die="+str(i+1)+")"))
d2l.plt.axhline(y=0.167,color='black',linestyle='dashed')
d2l.plt.gca().set_xlabel("Groups of experiments")
d2l.plt.gca().set_ylabel("Estimated probability")
d2l.plt.legend();
d2l.plt.show()

运行截图
在这里插入图片描述

在这里插入图片描述

正太分布与平方损失
import math
import numpy as np
from d2l import torch as d2l

def normal(x, mu, sigma):
    """
    计算正太分布
    """
    p = 1/math.sqrt(2 * math.pi * sigma**2)
    return p*np.exp(-0.5/sigma**2 * (x-mu)**2)

if __name__ == '__main__':
    #使用numpy进行可视化
    x = np.arange(-7, 7, 0.01)

    #均值和标准差对
    params = [(0, 1),(0, 2),(3,1)]
    d2l.plot(x, [normal(x, mu, sigma) for mu, sigma in params], xlabel='x',
             ylabel='p(x)', figsize=(5.5, 4.0),
             legend=[f'mean {mu}, std{sigma}'for mu, sigma in params])
    d2l.plt.show()

运行截图
在这里插入图片描述

生成数据集
from d2l import torch as d2l
import torch

def synthetix_data(w,b, num_examples):
    """⽣成y = Xw + b + 噪声。"""

    """返回一个张量,包含从给定参数means,std的离散正态分布中抽取随机数。 均值means是一个张量,包含每个输出元素相关的正态分布的均值。
    std是一个张量,包含每个输出元素相关的正态分布的标准差。 均值和标准差的形状不须匹配,但每个张量的元素个数须相同。"""
    X = torch.normal(0, 1, (num_examples, len(w)))
    # print(X)
    y = torch.matmul(X, w) +b # 张量乘法
    # print(y)
    y += torch.normal(0, 0.01, y.shape)
    return X, y.reshape((-1, 1))


true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = synthetix_data(true_w, true_b, 1000)

d2l.set_figsize()
d2l.plt.scatter(features[:,(1)].detach().numpy(), labels.detach().numpy(),1)
d2l.plt.show()

数据分布图
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值