Pytorch(1)-torch.Tensor特性与操作(创建、索引、均值、方差)

1. 基本操作

Tensor是Pytorch的基本数据结构,Tensor具有dimension属性,也称为阶数(与矩阵的阶无关)。
每个维度(轴)有对应的长度,很多和张量相关的函数都有dim参数,指定对张量的某一维度(轴)进行操作。
0阶 - 标量 - scalor
1阶 - 向量 - vector
2阶 - 矩阵 - matrix
3阶 - 张量 - tensor

torch tensor 和numpy ndarray 操作映射表格
[todo]

import torch
import numpy as np

1.1 创建


def test_create_tensor():
    """
    Function: create tensor, dtype, from_numpy()
    """
    n = 4
    row, col = 2, 2
    # 1. 用List创建Tensor
    a = torch.tensor([0, 1, 2, 3])
    b = torch.tensor([[0, 1], [2, 3]])
    c = torch.tensor(range(n)).reshape(row, col)
    """print
        Tensor from List, a:  tensor([0, 1, 2, 3]) torch.LongTensor torch.int64
        Tensor from List, b:
        tensor([[0, 1],
                [2, 3]])
        Tensor from List, c:
        tensor([[0, 1],
                [2, 3]])
    """

    # 2. 随机Tensor, torch.randn(x, y, z)
    d = torch.randn(n)      # n个随机数,正态分布, 
    e = torch.rand(n)       # n个随机数,[0,1)间均匀分布
    f = torch.randperm(n)   # 随机打乱整数[0, n) 
    """print
        随机数 正态分布, d:  tensor([ 0.9517,  0.0963, -0.5927, -0.0353])
        随机数 [0, 1)均匀分布, e: tensor([0.6249, 0.8082, 0.2404, 0.7206])
        随机打乱 [0, n), f: tensor([0, 1, 2, 3])
    """

    # 3. 全0, 全1 Tensor
    g = torch.zeros(row, col)
    h = torch.ones(row, col)

    # 4. 对角矩阵, 只能是二维的,shape只能是int, 
    i = torch.eye(3)      # 对角方阵
    j = torch.eye(3, 4)   # 对角矩阵
    """print
        全0 Tensor, g:
        tensor([[0., 0.],
                [0., 0.]])
        全1 Tensor, h:
        tensor([[1., 1.],
                [1., 1.]])
        对角方阵, i:
        tensor([[1., 0., 0.],
                [0., 1., 0.],
                [0., 0., 1.]])
        对角矩阵, j:
        tensor([[1., 0., 0., 0.],
                [0., 1., 0., 0.],
                [0., 0., 1., 0.]])
    """

    # 5. 一维序列
    k = torch.arange(start=0, end=n, step=1)      # [0, n), 步长为step
    l = torch.linspace(start=0, end=n, steps=2)   # [0, n], 一共steps个, steps名称歧议!!
    """print
        Arange Tensor:, k: tensor([0, 1, 2, 3])
        Linspace Tensor:, l: tensor([0., 4.])
    """

    # 6. torch.tensor <=> np.array, 若Tensor为GPU类型数据,需要转换为CPU类型[.cpu()]才能转换成ndarray
    m = np.array([0, 1, 2, 3])
    m1 = torch.from_numpy(m)
    m2 = m1.numpy()
    """print
        type(m),  <class 'numpy.ndarray'>
        type(m1),  <class 'torch.Tensor'>
        type(m2),  <class 'numpy.ndarray'>
    """

    # 7. 数据类型未显式指定,默认torch.int64/torch.float32
    #    指定类型
    #       指定数据类型, dtype=torch.float/torch.bool, tensor(), zeros(), ones()等都接受dtype参数
    #       复制已有类型, type_as(), torch.IntTensor()
    #    查看类型(两种不同表达方式)
    #       tensor.dtype, torch.float/torch.bool
    #       tensor.type(), string='torch.FloatTensor'/'torch.cuda.FloatTensor' 可以看出CPU/GPUtensor
    n = torch.tensor([0, 1], dtype=torch.float)
    o = torch.tensor([0, 1], dtype=torch.bool)
    n1 = n.type_as(torch.IntTensor())     # torch.IntTensor([1])
    n2 = n1.type_as(n)
    """print
        n.type(): torch.FloatTensor, n.dtype: torch.float32, n.data: tensor([0., 1.])
        n1.type(): torch.IntTensor, n1.dtype: torch.int32, n1.data: tensor([0, 1], dtype=torch.int32)
        n2.type(): torch.FloatTensor, n2.dtype: torch.float32, n2.data: tensor([0., 1.])
        o.type(): torch.BoolTensor, o.dtype: torch.bool, 0.data: tensor([False,  True])
        p.type: torch.IntTensor, p.dtype: torch.int32, p.data: tensor([1, 2], dtype=torch.int32)
    """

torch tensor 和numpy ndarray 结构基本一致,ndarray构建方式如下:

def test_create_ndarray():
    """
    Function: np 构建 ndarray Vs torch 构建 tensor
    """
    n, low = 4, 4
    row, col = 2, 2
    # 1. 用List创建ndarray
    a = np.array([0, 1, 2, 3])
    b = np.array([[0, 1], [2, 3]])
    c = np.array(range(n)).reshape(row, col)
    """print
        ndarray from List, a:  [0 1 2 3] int64
        ndarray from List, b:
        [[0 1]
        [2 3]]
        ndarray from List, c:
        [[0 1]
        [2 3]]
    """

    # 2. 随机ndarray, np.random.randn(x, y, z)
    d = np.random.randn(n)      # n个随机数,正态分布, 
    e = np.random.rand(n)       # n个随机数,[0,1)间均匀分布
    e1 = np.random.random((n))  # n个随机数,[0,1)间均匀分布, np.random.random((x, y, z)), 参数传递用tuple封装
    e2 = np.random.randint(low, high=None, size=None)   # n个随机整数,[0, low)/[low, high) 间的均匀分布
    f = np.arange(n)
    np.random.shuffle(f)   #  随机打乱整数[0, n) 
    """print
        随机数 正态分布, d:  [-0.05405188  1.32983551 -0.8320061   0.85252288]
        随机数 [0, 1)均匀分布, e: [0.62507954 0.62382814 0.47105695 0.79694156]
        随机打乱 [0, n), f: [3 0 2 1]
    """

    # 3. 全0, 全1 Tensor
    g = np.zeros((row, col))
    h = np.ones((row, col))
    # 4. 对角矩阵
    i = np.eye(3)      # 对角方阵
    j =  np.eye(3, 4)   # 对角矩阵
    """print
        全0 ndarray, g:
        [[0. 0.]
        [0. 0.]]
        全1 ndarray, h:
        [[1. 1.]
        [1. 1.]]
        对角方阵, i:
        [[1. 0. 0.]
        [0. 1. 0.]
        [0. 0. 1.]]
        对角矩阵, j:
        [[1. 0. 0. 0.]
        [0. 1. 0. 0.]
        [0. 0. 1. 0.]]
    """

    # 5. 一维序列
    k = np.arange(start=0, stop=n, step=1)      # [0, n), 步长为step
    l = np.linspace(start=0, stop=n, num=2)     # [0, n], 一共steps个, num参数名明了
    """print
        Arange Tensor:, k: [0 1 2 3]
        Linspace Tensor:, l: [0. 4.]
    """

    # 6. torch.tensor <=> np.array, 若Tensor为GPU类型数据,需要转换为CPU类型[.cpu()]才能转换成ndarray
    m = np.array([0, 1, 2, 3])
    m1 = torch.from_numpy(m)
    m2 = m1.numpy()
    """print
        type(m),  <class 'numpy.ndarray'>
        type(m1),  <class 'torch.Tensor'>
        type(m2),  <class 'numpy.ndarray'>
    """

    # 7. 数据类型未显式指定,默认np.int64/np.float64
    #    指定类型np.float/np.bool
    #       指定数据类型, dtype=xxx, array(), zeros(), ones()等都接受dtype参数
    #       复制已有类型, astype(xxx), 
    #    查看类型(两种不同表达方式)
    #       ndarray.dtype, return xxxx
    n = np.array([0, 1], dtype=np.float)
    o = np.array([0, 1], dtype=np.bool)
    n1 = n.astype(np.int32)     # 没有np.astype, n2 = n1.astype(n)
    print("n.dtype: {}, n data: {} ".format(n.dtype, n))
    print("n1.dtype: {}, n1 data: {} ".format(n1.dtype, n1))
    print("o.dtype: {}, 0 data: {}".format(o.dtype, o))
    """print
        n.dtype: float64, n data: [0. 1.]
        n1.dtype: int32, n1 data: [0 1]
        o.dtype: bool, 0 data: [False  True]
    """


1.2 索引, 切片, cat, stack, reshape, transpos, squeeze, flatten

def test_shape_operate():
    """
    Function: 索引、切片、拼接、堆叠、reshape(), transpos(), squeeze()
    """
    a = torch.randn(4, 5)

    # 1. 索引,取出某轴/某分量
    # 1.1 index_select(), index 1-D IntTensor/LongTensor
    b1 = torch.index_select(a, dim=0, index=torch.tensor([0, 2]))   # [4, 5] -> [2, 5]
    b2 = torch.index_select(a, dim=1, index=torch.tensor([0, 2]))   # [4, 5] -> [4, 2]
    # 1.2 np风格下标索引
    b3 = a[[0, 2], :]   # [4, 5] -> [2, 5]
    b4 = a[:, [0, 2]]   # [4, 5] -> [4, 2]
    # 1.3 masked_select(a, mask), a.shape 和 mask.shape 符合广播规范即可, boolen index
    masked_a = a > 0                            # [4, 5] 
    masked_a2 = a.sum(dim=1, keepdim=True) > 0  # [4, 1]
    b5 = torch.masked_select(a, mask=masked_a)  # [4, 5] -> [k]    1-D Tensor
    b6 = torch.masked_select(a, mask=masked_a2) # [4, 5] -> [k * 5], 配合reshape 可以实现用bool mask index行  
    """print
        [origin] a.shape: torch.Size([4, 5]), a.data:
        tensor([[-0.1340, -1.0141, -0.4921,  0.5482, -0.8680],
                [ 1.1184,  0.3712, -0.2858,  2.2291, -1.0631],
                [ 0.8453,  2.1079, -0.8402,  0.2716,  1.2784],
                [-0.9252,  0.0023,  0.5246, -1.1401, -1.0689]])
        [index_select] b1.shape: torch.Size([2, 5]), b1.data:
        tensor([[-0.1340, -1.0141, -0.4921,  0.5482, -0.8680],
                [ 0.8453,  2.1079, -0.8402,  0.2716,  1.2784]])
        [index_select] b2.shape: torch.Size([4, 2]), b2.data:
        tensor([[-0.1340, -0.4921],
                [ 1.1184, -0.2858],
                [ 0.8453, -0.8402],
                [-0.9252,  0.5246]])
        [index_select] b3.shape: torch.Size([2, 5]), b3.data:
        tensor([[-0.1340, -1.0141, -0.4921,  0.5482, -0.8680],
                [ 0.8453,  2.1079, -0.8402,  0.2716,  1.2784]])
        [index_select] b4.shape: torch.Size([4, 2]), b4.data:
        tensor([[-0.1340, -0.4921],
                [ 1.1184, -0.2858],
                [ 0.8453, -0.8402],
                [-0.9252,  0.5246]])
        [masked_select] masked_a.shape: torch.Size([4, 5]), masked_a.data:
        tensor([[False, False, False,  True, False],
                [ True,  True, False,  True, False],
                [ True,  True, False,  True,  True],
                [False,  True,  True, False, False]])
        [masked_select] masked_a2.shape: torch.Size([4, 1]), masked_a2.data:
        tensor([[False],
                [ True],
                [ True],
                [False]])
        [masked_select] b5.shape: torch.Size([10]), b5.data:
        tensor([0.5482, 1.1184, 0.3712, 2.2291, 0.8453, 2.1079, 0.2716, 1.2784, 0.0023,
                0.5246])
        [masked_select] b6.shape: torch.Size([10]), b6.data:
        tensor([ 1.1184,  0.3712, -0.2858,  2.2291, -1.0631,  0.8453,  2.1079, -0.8402,
                0.2716,  1.2784])
    """

    # 2. 切块, tuple(trunk0, truank1, ....), 向上取整,最后一块比较小
    a = torch.randn(5, 4)
    c1 = torch.chunk(a, chunks=2)             # ((3, 4), (2, 4))
    c2 = torch.chunk(a, chunks=2, dim=1)      # ((5, 2), (5, 2))
    c3 = torch.split(a, split_size_or_sections=2, dim=0)      # ((2, 4), (2, 4), (1, 4))
    c4 = torch.split(a, split_size_or_sections=[1, 4], dim=0) # ((1, 4), (4, 4))
    """print
        [origin] a.shape: torch.Size([5, 4])
        [chunk] len(c1): 2, c1[0].shape: torch.Size([3, 4]), c1[1].shape: torch.Size([2, 4])
        [chunk] len(c2): 2, c2[0].shape: torch.Size([5, 2]), c2[1].shape: torch.Size([5, 2])
        [split] len(c3): 3, c3[0].shape: torch.Size([2, 4]), c3[1].shape: torch.Size([2, 4]), cd[2],shape: torch.Size([1, 4])
        [split] len(c4): 2, c4[0].shape: torch.Size([1, 4]), c4[1].shape: torch.Size([4, 4])
    """

    # 3. 拼接cat() - 不扩张维度, 
    a = torch.randn(2, 3)
    d1 = torch.cat([a, a], dim=0)  # [4, 3]
    d2 = torch.cat([a, a], dim=1) # [2, 6]
    #    堆叠stack() - 扩张维度
    d3 = torch.stack([a, a], dim=0) # [2, 2, 3]
    d4 = torch.stack([a, a], dim=2) # [2, 3, 2]  很难看出原来张量的样子了[2, 3, 1]
    """print
        [origin] a.shape: torch.Size([2, 3]), a.data:
        tensor([[ 0.9315, -0.8230, -0.4260],
                [ 0.6940, -0.6632, -0.0699]])
        [cat] d1.shape: torch.Size([4, 3]), d1.data:
        tensor([[ 0.9315, -0.8230, -0.4260],
                [ 0.6940, -0.6632, -0.0699],
                [ 0.9315, -0.8230, -0.4260],
                [ 0.6940, -0.6632, -0.0699]])
        [cat] d2.shape: torch.Size([2, 6]), d2.data:
        tensor([[ 0.9315, -0.8230, -0.4260,  0.9315, -0.8230, -0.4260],
                [ 0.6940, -0.6632, -0.0699,  0.6940, -0.6632, -0.0699]])
        [stack] d3.shape: torch.Size([2, 2, 3]), d3.data:
        tensor([[[ 0.9315, -0.8230, -0.4260],
                [ 0.6940, -0.6632, -0.0699]],

                [[ 0.9315, -0.8230, -0.4260],
                [ 0.6940, -0.6632, -0.0699]]])
        [stack] d4.shape: torch.Size([2, 3, 2]), d4.data:
        tensor([[[ 0.9315,  0.9315],
                [-0.8230, -0.8230],
                [-0.4260, -0.4260]],

                [[ 0.6940,  0.6940],
                [-0.6632, -0.6632],
                [-0.0699, -0.0699]]])
    """

    # 4. .reshape() 
    a = torch.randn(2, 1, 3)
    e = torch.reshape(a, shape=(2, 3))       # a.rehape(2, 3)
    """print
        [origin]  a.shape: torch.Size([2, 1, 3]), a.data:
        tensor([[[ 1.7180, -0.3074,  0.4583]],

                [[-1.6315,  1.0407,  0.1717]]])
        [reshape] e.shape: torch.Size([2, 3]), e.data:
        tensor([[ 1.7180, -0.3074,  0.4583],
                [-1.6315,  1.0407,  0.1717]])
    """

    # 5. .transpose()转置, 仅仅影响了张量的形状和步长
    f1 = torch.transpose(a, dim0=0, dim1=1)  # [2, 1, 3] -> [1, 2, 3]
    f2 = torch.transpose(a, dim0=1, dim1=2)  # [2, 1, 3] -> [2, 3, 1]
    """print
        [origin]    a.shape: torch.Size([2, 1, 3]), a.data:
        tensor([[[ 1.7180, -0.3074,  0.4583]],

                [[-1.6315,  1.0407,  0.1717]]])
        [transpose] f1.shape: torch.Size([1, 2, 3]), f1.data:
        tensor([[[ 1.7180, -0.3074,  0.4583],
                [-1.6315,  1.0407,  0.1717]]])
        [transpose] f2.shape: torch.Size([2, 3, 1]), f2.data:
        tensor([[[ 1.7180],
                [-0.3074],
                [ 0.4583]],

                [[-1.6315],
                [ 1.0407],
                [ 0.1717]]])
    """

    # 6. .squeeze(), .unsqueeze()
    g1 = torch.squeeze(a, dim=1)    # dim=None, 压缩所有长度为1的维度
    g2 = torch.unsqueeze(g1, dim=1) # 扩张指定的维度长度为1
    """print
        [origin]    a.shape: torch.Size([2, 1, 3]), a.data:
        tensor([[[ 1.7180, -0.3074,  0.4583]],

                [[-1.6315,  1.0407,  0.1717]]])
        [squeeze]   g1.shape: torch.Size([2, 3]), g1.data:
        tensor([[ 1.7180, -0.3074,  0.4583],
                [-1.6315,  1.0407,  0.1717]])
        [unsqueeze] g2.shape: torch.Size([2, 1, 3]), g2.data:
        tensor([[[ 1.7180, -0.3074,  0.4583]],

                [[-1.6315,  1.0407,  0.1717]]])
    """

    # 7. flatten(input, start_dim=0, end_dim=-1)
    h0 = torch.arange(8).reshape(2, 2, 2)
    h1 = torch.flatten(h0, start_dim=1)  # [2, 4]
    h2 = torch.flatten(h0) # [8]
    """print
        [origin]  h0.shape: torch.Size([2, 2, 2]), h0.data:
        tensor([[[0, 1],
                [2, 3]],

                [[4, 5],
                [6, 7]]])
        [flatten] h1.shape: torch.Size([2, 4]), h1.data:
        tensor([[0, 1, 2, 3],
                [4, 5, 6, 7]])
        [flatten] h2.shape: torch.Size([8]), h2.data:
        tensor([0, 1, 2, 3, 4, 5, 6, 7])
    """
    # np demo 
    h0 = np.arange(8).reshape(2, 2, 2)
    h1 = np.matrix.flatten(h0, order='K')  # [2, 4]
    h2 = np.matrix.flatten(h0) # [8]
    # Parameters: (没搞懂)
    # order{‘C’, ‘F’, ‘A’, ‘K’}, optional
            # ‘C’ means to flatten in row-major (C-style) order. 
            # ‘F’ means to flatten in column-major (Fortran-style) order. 
            # ‘A’ means to flatten in column-major order if m is Fortran contiguous in memory, row-major order otherwise. 
            # ‘K’ means to flatten m in the order the elements occur in memory. The default is ‘C’.
    """print
        [origin]  array h0.shape: (2, 2, 2), h0.data:
        [[[0 1]
        [2 3]]

        [[4 5]
        [6 7]]]
        [flatten] array h1.shape: (8,), h1.data:
        [0 1 2 3 4 5 6 7]
        [flatten] array h2.shape: (8,), h2.data:
        [0 1 2 3 4 5 6 7]
    """


1.3 storage, device

def test_storage():
    """
    Function:
    1. 同一块内存 可以被多个张量'索引',从不同的地方引用, points 和 second_point 是不同的索引。
        '索引'具有三个属性: 
        大小(size): 每个维度上有多少个元素
        偏移(storage offset):每个元素与第一个元素之间的偏移
        步长(stride):沿着存储的每个维度获取下一个元素需要跳过的元素数量
    2. 更改子张量 会影响原张量
    3. 连续张量 沿最右边的维开始存放在内存的张量,用tensor.is_contiguous判断
    """
    points = torch.tensor([[1.0, 4.0], [2.0, 5.0], [3.0, 6.0]])  # [3, 2]
    second_point = points[1]
    print("[points] size(): {}, torage_offset(): {}, stride(): {}, is_contiguous: {}".format(
            points.size(), points.storage_offset(), points.stride(), points.is_contiguous()))
    print("[second points] size(): {}, torage_offset(): {}, stride(): {}, is_contiguous: {}".format(
            second_point.size(), second_point.storage_offset(), second_point.stride(), second_point.is_contiguous()))
    """print
        [points] size(): torch.Size([3, 2]), torage_offset(): 0, stride(): (2, 1), is_contiguous: True
        [second points] size(): torch.Size([2]), torage_offset(): 2, stride(): (1,), is_contiguous: True
    """
def test_device():
    """
    Function:
      1. tensor 创建后设备转换
            返回GPU张量副本: tensor.cuda() / tensor.cuda(0),
            返回CPU张量副本: tensor.cpu()
            device属性指定: tensor.to(device="cuda"), 'cuda'/'cpu'/'gpu:0'/'cpu:0'
      3. 不同设备中的张量不能直接参与同一个运算
    """
    print("orch.cuda.is_available(): {}".format(torch.cuda.is_available()))  # False
    print("torch.cuda.device_count(): {}".format(torch.cuda.device_count()))  # 0
    # print(torch.cuda.current_device())  

    # 自适应设置device
    device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
    data = torch.tensor([[1, 2], [3, 4]], device=device)

1.4 广播机制

def test_broadcast():
    """
    Function:
        torch 很多操作都支持广播机制:无需显示复制数据,可以将参与运算的张量自动扩展为相同的形状
        广播三条法则如下:
    """
    # 1. tensor + scalar
    a1 = torch.arange(3)
    r1 = a1 + 3
    """prin
        [broadcast] tensor + scalar: tensor([0, 1, 2]) + 3 = tensor([3, 4, 5])
    """

    # 2. 两个tensor dims数量一致,且其中存在长度为1的轴
    a1 = torch.arange(12).reshape((3, 4))  # [3, 4]
    a2 = torch.ones(1, 4)                  # [1, 4]
    r1 = a1 + a2
    """print
        [broadcast] a1.shape: torch.Size([3, 4]), a1.data:
        tensor([[ 0,  1,  2,  3],
                [ 4,  5,  6,  7],
                [ 8,  9, 10, 11]])
        [broadcast] a2.shape: torch.Size([1, 4]), a2.data:
        tensor([[1., 1., 1., 1.]])
        [broadcast] r1.shape: torch.Size([3, 4]), r1.data:
        tensor([[ 1.,  2.,  3.,  4.],
                [ 5.,  6.,  7.,  8.],
                [ 9., 10., 11., 12.]])
    """

    # 3. 两个tensor dims数量不一致,尾部对齐后,某个tensor较短
    a1 = torch.arange(6).reshape(3, 2)   # [3, 2]
    a2 = torch.arange(4, 6)              # [2]
    r1 = a1 + a2
    """print
        [broadcast] a1.shape: torch.Size([3, 2]), a1.data:
        tensor([[0, 1],
                [2, 3],
                [4, 5]])
        [broadcast] a2.shape: torch.Size([2]), a2.data:
        tensor([4, 5])
        [broadcast] r1.shape: torch.Size([3, 2]), r1.data:
        tensor([[ 4,  6],
                [ 6,  8],
                [ 8, 10]])
    """

2. Tensor 数据分析统计量

数据统计功能: 求和、均值,方差

2.1 加减, 乘除, 幂pow()


def test_cal():
    """
    Function: 
        数据   a shape = [x, y, z]
        tensor 对应dim =  0, 1, 2
        ndarray对应axis = 0, 1, 2
    """
    # 1. Tensor求和
    a = torch.ones(2, 3)         # a.shape = (2, 3), dim=0, 是长度为2的轴
    sum0 = torch.sum(a, dim=0)   # [3], 列和, 沿着地零个轴求和
    sum1 = torch.sum(a, dim=1)   # [2], 行和
    sum2 = torch.sum(a)          # [1], 全部和
    """print
        [Tensor origin] a.shape: torch.Size([2, 3]), a.data:
        tensor([[1., 1., 1.],
                [1., 1., 1.]])
        [Tensor col sum] sum0.shape: torch.Size([3]), sum0.data:
        tensor([2., 2., 2.])
        [Tensor row sum] sum1.shape: torch.Size([2]), sum1.data:
        tensor([3., 3.])
        [Tensor total sum] sum2.shape: torch.Size([]), sum2.data:
        6.0
    """
    #    np demo - Ndarra求和
    a = np.ones((2, 3))         # a.shape = (2, 3), dim=0, 是长度为2的轴
    sum0 = np.sum(a, axis=0)   # [3], 列和, 沿着地零个轴求和
    sum1 = np.sum(a, axis=1)   # [2], 行和
    sum2 = np.sum(a)           # [1], 全部和
    """print
        [Ndarray origin] a.shape: (2, 3), a.data:
        [[1. 1. 1.]
        [1. 1. 1.]]
        [Ndarray col sum] sum0.shape: (3,), sum0.data:
        [2. 2. 2.]
        [Ndarray row sum] sum1.shape: (2,), sum1.data:
        [3. 3.]
        [Ndarray total sum] sum2.shape: (), sum2.data:
        6.0
    """

    # 2. elements wise mul
    a = torch.ones(2, 3)   # [2, 3]
    b = a * 2              # [2, 3], 广播机制
    mul1 = a * b
    mul2 = np.multiply(a, b)
    """print
        [Tensor] a.shape: torch.Size([2, 3]), a.data:
        tensor([[1., 1., 1.],
                [1., 1., 1.]])
        [Tensor] b.shape: torch.Size([2, 3]), b.data:
        tensor([[2., 2., 2.],
                [2., 2., 2.]])
        [Tensor] mul1.shape: torch.Size([2, 3]), mul1.data:
        tensor([[2., 2., 2.],
                [2., 2., 2.]])
        [Tensor] mul2.shape: torch.Size([2, 3]), mul2.data:
        tensor([[2., 2., 2.],
                [2., 2., 2.]])
    """
    # np demo 
    a = np.ones((2, 3))
    b = a * 2
    mul1 = a * b
    mul2 = np.multiply(a, b)
    """print
        [Ndarray] a.shape: (2, 3), a.data:
        [[1. 1. 1.]
        [1. 1. 1.]]
        [Ndarray] b.shape: (2, 3), b.data:
        [[2. 2. 2.]
        [2. 2. 2.]]
        [Ndarray] mul1.shape: (2, 3), mul1.data:
        [[2. 2. 2.]
        [2. 2. 2.]]
        [Ndarray] mul2.shape: (2, 3), mul2.data:
        [[2. 2. 2.]
        [2. 2. 2.]]
    """

    # 3.  矩阵乘法 两个矩阵需要满足行列尺寸关系
    t1 = torch.ones(2, 3)    
    t2 = torch.arange(6).reshape(3, 2).type_as(t1)
    mul = torch.matmul(t1, t2)   # [2, 3]
    """print
        [Tensor] t1.shape: torch.Size([2, 3]), t1.data:
        tensor([[1., 1., 1.],
                [1., 1., 1.]])
        [Tensor] t2.shape: torch.Size([3, 2]), t2.data:
        tensor([[0., 1.],
                [2., 3.],
                [4., 5.]])
        [Tensor] mul.shape: torch.Size([2, 2]), mul.data:
        tensor([[6., 9.],
                [6., 9.]])
    """
    # np demo 
    t1 = np.ones((2, 3))    
    t2 = np.arange(6).reshape(3, 2).astype(np.float32)
    mul = np.matmul(t1, t2)   # [2, 3]
    """print
        [Ndarray] t1.shape: (2, 3), t1.data:
        [[1. 1. 1.]
        [1. 1. 1.]]
        [Ndarray] t2.shape: (3, 2), t2.data:
        [[0. 1.]
        [2. 3.]
        [4. 5.]]
        [Ndarray] mul.shape: (2, 2), mul.data:
        [[6. 9.]
        [6. 9.]]
    """

    # 4. 幂运算 torch.pow()
    a = torch.arange(6).reshape(2, 3)
    e = torch.arange(6).reshape(2, 3)
    p0 = torch.pow(a, 2)  # a^2
    p1 = torch.pow(a, e)  # a^e
    """print
        [Tensor] a.shape: torch.Size([2, 3]), a.data:
        tensor([[0, 1, 2],
                [3, 4, 5]])
        [Tensor] e.shape: torch.Size([2, 3]), e.data:
        tensor([[0, 1, 2],
                [3, 4, 5]])
        [Tensor] p0.shape: torch.Size([2, 3]), p0.data:
        tensor([[ 0,  1,  4],
                [ 9, 16, 25]])
        [Tensor] p1.shape: torch.Size([2, 3]), p1.data:
        tensor([[   1,    1,    4],
                [  27,  256, 3125]])
    """
    # np demo
    a = np.arange(6).reshape(2, 3)
    e = np.arange(6).reshape(2, 3)
    p0 = np.power(a, 2)  # a^2
    p1 = np.power(a, e)  # a^e
    """print
        [Ndarray] a.shape: (2, 3), a.data:
        [[0 1 2]
        [3 4 5]]
        [Ndarray] e.shape: (2, 3), e.data:
        [[0 1 2]
        [3 4 5]]
        [Ndarray] p0.shape: (2, 3), p0.data:
        [[ 0  1  4]
        [ 9 16 25]]
        [Ndarray] p1.shape: (2, 3), p1.data:
        [[   1    1    4]
        [  27  256 3125]]
    """
    

2.2 均值、方差

numpy 与torch .std()计算公式差别
numpy:
s t d = 1 N ∑ i = 1 N ( x i − x ‾ ) 2 std=\sqrt{\frac{1}{N}\sum_{i=1}^N(x_i-\overline{x})^2} std=N1i=1N(xix)2

torch:
s t d = 1 N − 1 ∑ i = 1 N ( x i − x ‾ ) 2 std=\sqrt{\frac{1}{N-1}\sum_{i=1}^N(x_i-\overline{x})^2} std=N11i=1N(xix)2
4.1 torch tensor.mean() .std()

>a.mean()  # a为Tensor型变量
>a.std()

>torch.mean(a)  # a为Tensor型变量
>torch.std(a)

>>> torch.Tensor([1,2,3,4,5])
tensor([1., 2., 3., 4., 5.])
>>> a=torch.Tensor([1,2,3,4,5])
>>> a.mean()
tensor(3.)
>>> torch.mean(a)
tensor(3.)
>>> a.std()
tensor(1.5811)
>>>> torch.std(a)
tensor(1.5811)       # 注意和numpy求解的区别

torch.mean(input) 输出input 各个元素的的均值,不指定任何参数就是所有元素的算术平均值,指定参数可以计算每一行或者 每一列的算术平均数

> a = torch.randn(4, 4)
>>tensor([[-0.3841,  0.6320,  0.4254, -0.7384],
        [-0.9644,  1.0131, -0.6549, -1.4279],
        [-0.2951, -1.3350, -0.7694,  0.5600],
        [ 1.0842, -0.9580,  0.3623,  0.2343]])
# 每一行的平均值
> torch.mean(a, 1, True)  #dim=true,计算每一行的平均数,输出与输入有相同的维度:两维度(4,1)
>>tensor([[-0.0163],
        [-0.5085],
        [-0.4599],
        [ 0.1807]])
 
> torch.mean(a, 1)   # 不设置dim,默认计算每一行的平均数,内嵌了一个torch.squeeze(),将数值为1的维度压缩(4,)
>>tensor([-0.0163, -0.5085, -0.4599,  0.1807])

4.2 numpy array.mean() .std()

>a.mean()  # a为np array型变量
>a.std()

>numpy.mean(a)   # a为np array型变量
>numpy.std(a)
>>> import numpy
>>> c=numpy.array([1,2,3,4,5])
>>> c.mean()
3.0
>>> numpy.mean(c)
3.0
>>> c.std()
1.4142135623730951
>>> numpy.std(c)
1.4142135623730951

>>> d=numpy.array([1,1,1,1])
>>> d.mean()
1.0
>>> d.std()
0.0

2.3 最大/最小/非零 值索引

tensor.argmax()

tensor.argmax(dim)

返回tensor最大的值对应的index。dim 不设置-全部元素的最大值,dim = 0 每列的最大值,dim = 1每行的最大值。

>>> a = torch.randn(3,4)
>>> a
tensor([[ 1.1360, -0.5890,  1.8444,  0.6960],
        [ 0.3462, -1.1812, -1.5536,  0.4504],
        [-0.4464, -0.5600, -0.1655,  0.3914]])
>>> a.argmax()
tensor(2)               # 按行拉成一维向量,对应的小次奥
>>> a.argmax(dim = 0)
tensor([0, 2, 0, 0])    # 每一列最大值的索引
>>> a.argmax(dim = 1)
tensor([2, 3, 3])       # 每一行最大值索引

8.2 tensor.argmin()
与tensor.argmax() 用法相同,在多分类问题求准确率时会用到。

output_labels = outputs.argmax(dim = 1)
train_acc = (output_labels == labels).float().mean()

8.3 tensor.nonzero()
返回非零元素对应的下标

>>> a = torch.tensor([[1,0],[0,3]])
>>> a.nonzero()
tensor([[0, 0],
        [1, 1]])
>>> a= torch.tensor([1,2,3,0,4,5,0])
>>> a.nonzero()
tensor([[0],
        [1],
        [2],
        [4],
        [5]])

Reference:

  1. np.random.random()和np.random.rand()
  2. 【PyTorch】 查看张量的数据类型
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值