iT邦幫忙

2021 iThome 鐵人賽

DAY 14
0
  • 程式語言會有一些常見的資料組單位,例如 python 會有 list,C、C++ 有 array 等等,Pytorch 也有一個自己的資料組單位,那就是 Tensor
  • 機器學習/深度學習領域鮮少只有單筆資料,因此 Tensor 是一個一維~多維度的運算基本單位,下面會詳細介紹 Tensor 的基礎使用和注意事項

What is Tensor

  • Tensor 中文翻譯叫做張量,是一個可用來表示在一些向量、純量和其他張量之間的線性關係的多線性函數
  • 可以想像成一個高維度向量,也是深度學習裡進行運算的基本元素。

Pytorch and Tensor

  • Pytorch 的基本元素都是基於 Tensor 為基礎元素

    Tensor 與 Pytorch 的關聯就類似於 Array 與 Python,就是一個元素,不用想太多

Usage

Create Tensor

  • 在開始運用 Tensor 之前,當然要學會創建一個 Tensor 來使用,所以一開始我們先來看看怎麼創建一個 Tensor

  • 創建空的 tensor torch.empty()

    x = torch.empty(2)
    print(x)
    # tensor([5.2430e+33, 5.4511e-43])
    
    • 也可以創建多維
    x = torch.empty(2, 3)
    print(x)
    # tensor([[0., 0., 0.],
    #         [0., 0., 0.]])
    
  • 創建 0 tensor torch.zeros()

    x = torch.zeros(2, 3)
    print(x)
    # tensor([[0., 0., 0.],
    #         [0., 0., 0.]])
    
  • 創建 random tensor torch.rand()

    x = torch.rand(2, 3)
    print(x)
    # tensor([[0.6430, 0.0116, 0.1679],
    #         [0.8597, 0.1615, 0.4508]])
    
  • emptyzeros 的差別在 zeros 是創建零元素,empty 則是單純宣告記憶體區塊,並沒有初始化參數,因此裡面的參數可以是任何值

  • 創建 1 tensor torch.ones()

    x = torch.ones(2, 3)
    print(x)
    # tensor([[1., 1., 1.],
    #         [1., 1., 1.]])
    
  • 資料型態 torch.dtype

    • 檢查資料型態
      x = torch.ones(2, 3)
      print(x.dtype)
      # torch.float32
      
      • 所以可以知道預設 dtype 是 torch.float32
    • 也可以賦予資料型態
      x = torch.ones(2, 3, dtype=torch.int)
      print(x.dtype)
      # torch.int
      
  • 資料大小 torch.size()

    x = torch.ones(2, 3)
    print(x.size())
    # torch.Size([2, 3])
    
  • 也可以直接賦值

    x = torch.tensor([2, 3])
    print(x)
    # tensor([2, 3])
    print(x.size())
    # torch.Size([2])
    

Basic + - * /

  • 那知道怎麼創建基本的 Tensor 之後,我們來聊聊如何做 Tensor 的加減乘除吧~
  • 兩個 Tensor 相加
    • ans = x1 + x2
    • ans = torch.add(x1, x2)
    • x1 加到 x2
      • x2.add_(x1)
  • 兩個 Tensor 相減
    • ans = x1 - x2
    • ans = torch.sub(x1, x2)
  • 兩個 Tensor 相乘
    • ans = x1 * x2
    • ans = torch.mul(x1, x2)
  • 兩個 Tensor 相除
    • ans = x1 / x2
    • ans = torch.div(x1, x2)

Tensor items

  • 一般程式語言中,我們操作 array 或是 list 的時候往往也會選取部分資料,那如何取得 Tensor 之中的 items 呢?下面我們會基於
    x = torch.rand(5, 3)
    print(x)
    # tensor([[0.8033, 0.7967, 0.0952],
    #         [0.0960, 0.2553, 0.9135],
    #         [0.5835, 0.1997, 0.4466],
    #         [0.7153, 0.9609, 0.7458],
    #         [0.1914, 0.5431, 0.2532]])
    
    來介紹各種資料的取法,那由於中文的那個 row column 的行列問題,我們這邊就直接用英文表示
  • 取得第一 row 的 Tensor
    print(x[0, :])
    # tensor([0.8033, 0.7967, 0.0952])
    
  • 取得第一 column 的 Tensor
    print(x[:, 0])
    # tensor([0.8033, 0.0960, 0.5835, 0.7153, 0.1914])
    
  • 取得第一 row, 取得第一 column 的 Tensor
    print(x[0, 0])
    # tensor(0.8033)
    
  • 取得第一 row, 取得第一 column 的 item
    print(x[0, 0].item())
    # 0.8032872080802917
    
  • Reshape Tensor
    y = x.view(15)
    print(y)
    # tensor([0.8033, 0.7967, 0.0952, 0.0960, 0.2553, 0.9135, 0.5835, 0.1997, 0.4466,
    #         0.7153, 0.9609, 0.7458, 0.1914, 0.5431, 0.2532])
    
    • 自動分配
      y = x.view(-1, 5)
      print(y.size())
      # torch.Size([3, 5])
      

Tensor <-> Numpy

  • Numpy 是 Python 數學操作的過程中常見的套件,有精準的數學工具和方便的運算函式,因此很多資料的前處理也往往會用到,所以如何把 numpy array 的資料和 Tensor 做靈活的轉換就非常重要了
  • Change Tensor to Numpy array
    a = torch.ones(5)
    print(a)
    b = a.numpy()
    print(b)
    # tensor([1., 1., 1., 1., 1.])
    # [1. 1. 1. 1. 1.]
    
  • Change Numpy array to Tensor
    a = np.ones(5)
    print(a)
    b = torch.from_numpy(a)
    print(b)
    # [1. 1. 1. 1. 1.]
    # tensor([1., 1., 1., 1., 1.], dtype=torch.float64)
    
  • ==如果你是使用 CPU 來操作 Tensor,在這裡你的 Tensor a 跟 Numpy b 會共享同一個 memory address ,所以操作會被同步,要特別注意==
    a.add_(1)
    print(a)
    print(b)
    # tensor([2., 2., 2., 2., 2.])
    # [2. 2. 2. 2. 2.]
    
    a += 1
    print(a)
    print(b)
    # [2. 2. 2. 2. 2.]
    # tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
    

使用 GPU

  • 我們有說過 Pytorch 有準備好 GPU 的操作套件,因此可以非常簡單的利用宣告來起用 GPU 來達到加速運算的功能
  • 利用 torch.cuda.is_available() 來檢查是否可以使用 GPU cuda
    if torch.cuda.is_available():
        device = torch.device("cuda")
        x = torch.ones(5, device=device)
        y = torch.ones(5)
        y = y.to(device)
        z = x + y
        print(z)
    
  • 在這裡特別提醒,numpy 只能在 CPU 上面坐使用,因此如果需要轉回 numpy ,需要先把 Tensor 送回 CPU
    z = z.to("cpu")
    z = z.numpy()
    

每日小結

  • Tensor 聽起來像是一個全新的東西,但是其實真的不用想得太複雜,就是一個基礎的資料組單位,因此只要記住 Pytorch 的基礎運算單位是 Tensor 就沒問題了
  • Tensor 的操作有一些記憶體上的使用問題,需要被特別注意,其他就是當作一般程式撰寫的方式去做操作即可
  • 明天我們來聊聊在 Python 中如何實作之前提到非常重要的 Grandient Descent 和 Pytorch 中的 Grandient Descent

上一篇
Day-12 Pytorch 介紹
下一篇
Day-14 Pytorch 的 Gradient 計算
系列文
Deep Learning 從零開始到放棄的 30 天 PyTorch 數字辨識模型31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言