0_Pytorch中的張量操作

[引言]張量的概念

1.基本概念
  • 張量是一個通用的多維數組,可以表示標量(0 維)、向量(1 維)、矩陣(2 維)以及更高維度的數據。
  • 張量是 PyTorch 中的核心數據結構,用于表示和操作數據。

0維張量:標量(scalar)
1維張量:向量(vector)
2維張量:矩陣(matrix)
多維張量: 例如三維張量==>類比魔方

1.張量的創建

張量的基本創建

  • torch.tensor() 根據指定數據創建張量

    # 1.根據指定數據創建張量 - torch.tensor
    print('tensor 方式創建張量')# 1.1 創建張量標量
    data = torch.tensor(10)
    print(f'張量標量:{data}')# 1.2 根據 numpy數組 創建張量
    data = np.random.randn(3, 2)
    data = torch.tensor(data)
    print(f'根據numpy數組創建張量:\r\n{data}')# 1.3 根據 列表 創建張量
    data = [[1, 0, 0], [0, 1, 0]]
    data = torch.tensor(data)
    print(f'根據列表創建張量:\r\n{data}')
    
  • torch.Tensor() 根據形狀創建張量, 其也可用來創建指定數據的張量

    # 2. 根據形狀創建張量 - torch.Tensor
    print('Tensor 方式創建張量')
    #   2.1 創建 2 行 3 列的張量 默認的dtype為 float32
    data = torch.Tensor(2, 3)
    print(data)#   2.2 注意!! 如果 傳遞列表, 則創建包含指定元素的張量
    data = torch.Tensor([10])
    print(data)
    
  • torch.IntTensor()、torch.FloatTensor()、torch.DoubleTensor() 創建指定類型的張量

    # 3.創建指定類型的張量 - torch.IntTensor、torch.FloatTensor、torch.DoubleTensor
    print('創建指定類型的張量-> torch.IntTensor、torch.FloatTensor、torch.DoubleTensor')
    #   3.1 創建 2 行 3 列,dtype為 int32 的張量
    data = torch.IntTensor(2, 3)
    print(data)#   3.2 注意!! 如果傳遞的類型不正確,則會進行類型轉換
    data = torch.IntTensor([2.5, 3.3])
    print(data)
    """
    其他的一些類型
    class DoubleTensor(Tensor): ...
    class FloatTensor(Tensor): ...
    class BFloat16Tensor(Tensor): ...
    class LongTensor(Tensor): ...
    class IntTensor(Tensor): ...
    class ShortTensor(Tensor): ...
    class HalfTensor(Tensor): ...
    class CharTensor(Tensor): ...
    class ByteTensor(Tensor): ...
    class BoolTensor(Tensor): ...
    """
    
1-總結

小寫 t: 根據指定數據創建
大寫 T: 既可以根據指定數據創建,也可以根據形狀創建

Tensor: 不指定類型

(Type)Tensor: 指定類型

創建線性張量和隨機張量

  • torch.arange() 和 torch.linspace() 創建線性張量

    # 1. 創建線性張量
    print('=' * 50 + '創建線性張量' + '=' * 50)
    #   1.1 在指定區間內按照步長生成元素
    data = torch.arange(0, 10, 2)
    print(data)#   1.2 在指定區間按照元素個數生成
    data = torch.linspace(0, 10, 9)
    print(data)
    
  • torch.random.init_seed() 和 torch.random.manual_seed() 隨機種子設置

  • torch.randn() 創建隨機張量

# 2.創建隨機張量
print('=' * 50 + '創建隨機張量' + '=' * 50)
#   2.1 創建一個 2 行 3列的隨機張量
data = torch.randn(2, 3)
print(data)#   2.2 設置隨機數種子
#   - torch.random.init_seed
print(f'隨機數種子: {torch.random.initial_seed()}')  # 25338627685600
#   - torch.random.manual_seed
torch.random.manual_seed(200)
data = torch.randn(2, 3)
print(data)
print(f'隨機數種子: {torch.random.initial_seed()}')  # 100

創建0-1張量

  • torch.ones 和 torch.ones_like 創建全1張量
  • torch.zeros 和 torch.zeros_like 創建全0張量
  • torch.full 和 torch.full_like 創建全為指定值張量
import torch# - torch.ones 和 torch.ones_like 創建全1張量
data = torch.ones(2, 3)
print(f'data:\r\n{data}')
data1 = torch.ones_like(data)
print(f'data1:\r\n{data1}')# - torch.zeros 和 torch.zeros_like 創建全0張量
data = torch.zeros(2, 3)
print(f'data:\r\n{data}')
data1 = torch.zeros_like(data)
print(f'data1:\r\n{data1}')# - torch.full 和 torch.full_like 創建全為指定值張量
data = torch.full([2, 3], 10, dtype=torch.float32)
print(f'data:\r\n{data}')
data1 = torch.full_like(data, 20)
print(f'data1:\r\n{data1}')
print(f'data1.dtype:{data1.dtype}')  # float32

2.張量的類型轉換

張量的元素類型轉換
  • data.type(torch.DoubleTensor)
  • data.double()
import torch
# 1. data.type(torch.類型)
print('===============data.type(torch.類型)================')
data = torch.full([2, 3], 10)
print(data.dtype)data = data.type(torch.DoubleTensor)
print(data.dtype)# data = data.type(torch.IntTensor)
# print(data.dtype)
# data = data.type(torch.LongTensor)
# print(data.dtype)# 2. data.double()
print('===============data.double()=================')
data = torch.full([2, 3], 20)
print(data.dtype)data = data.double()
print(data.dtype)# data = data.int()
# print(data.dtype)

張量的類型轉換

  1. 張量轉換為Numpy數組的方法
  • 使用 Tensor.numpy 函數可以將張量轉換為 ndarray 數組,但是共享內存,可以使用 copy 函數避免共享。

    # 1. 張量轉換為Numpy數組的方法
    # - 使用 Tensor.numpy 函數可以將張量轉換為 ndarray 數組,但是共享內存,可以使用 copy 函數避免共享.
    print('=' * 30 + '使用 Tensor.numpy但不進行copy' + '=' * 30)
    data_tensor = torch.tensor([2, 3, 4])
    data_numpy = data_tensor.numpy()
    print(type(data_tensor))
    print(type(data_numpy))data_numpy[0] = 100
    print(data_tensor)
    print(f'ndarray:{data_numpy}')print('=' * 30 + '使用 Tensor.numpy并進行copy' + '=' * 30)
    data_tensor = torch.tensor([2, 3, 4])
    data_numpy = data_tensor.numpy().copy()
    print(type(data_tensor))
    print(type(data_numpy))data_numpy[0] = 100
    print(data_tensor)
    print(f'ndarray:{data_numpy}')
    
    1. Numpy數組轉換為張量的方法
    • 使用 from_numpy 可以將 ndarray 數組轉換為 Tensor,默認共享內存,使用 copy 函數避免共享。

    • 使用 torch.tensor 可以將 ndarray 數組轉換為 Tensor,默認不共享內存。

      # 2. Numpy數組轉換為張量的方法
      """
      將numpy數組轉換為張量2.1 from_numpy 默認共享內存,使用 copy 函數避免共享。2.2 torch.tensor(ndarray) 默認不共享內存。
      """
      # - 2.1 使用 from_numpy:會共享內存,可以使用 copy 函數避免共享。
      print('=' * 30 + '使用from_numpy但不進行copy' + '=' * 30)
      data_numpy = np.array([2, 3, 4])
      data_tensor = torch.from_numpy(data_numpy)
      data_tensor[0] = 100
      print(data_tensor)
      print(f'ndarray:{data_numpy}')print('=' * 30 + '使用from_numpy且進行copy' + '=' * 30)
      data_numpy = np.array([2, 3, 4])
      data_tensor = torch.from_numpy(data_numpy.copy())
      data_tensor[0] = 100
      print(data_tensor)
      print(f'ndarray:{data_numpy}')# - 2.2 使用 torch.tensor(ndarray) 默認不共享內存。
      data_numpy = np.array([2, 3, 4])
      data_tensor = torch.tensor(data_numpy)data_tensor[0] = 100
      print(data_tensor)
      print(f'ndarray:{data_numpy}')
      
      1. 標量張量和數字轉換方法
      • 對于只有一個元素的張量,使用item()函數將該值從張量中提取出來

        官方文檔解釋: Returns the value of this tensor as a standard Python number.
        This only works for tensors with one element.

# 3. 標量張量和數字轉換方法
# - 對于只有一個元素的張量,使用item()函數將該值從張量中提取出來
data_tensor = torch.tensor([30, ])
print(data_tensor.item())data_tensor = torch.tensor(30)
print(data_tensor.item())

3.張量數值計算

  1. 張量基本運算
  • 不修改原數據

    • add、sub、mul、div、neg
  • 修改源數據

    • add_、sub_、mul_、div_、neg_(帶下劃線的版本會修改原數據)
    # 1.張量基本運算
    print('=' * 30 + '基本運算' + '=' * 30)
    data = torch.randint(0, 10, [2, 3])
    print(f'原數據data:\r\n{data}')#   1.1 不修改原數據
    print('=' * 10 + 'add' + '=' * 10)
    new_data = data.add(10)
    print(f'new_data:\r\n{new_data}')
    print(f'data:\r\n{data}')#   1.2 直接修改原數據
    print('=' * 10 + 'add_' + '=' * 10)
    data.add_(10)
    print(f'data:\r\n{data}')# print(data.sub(10))
    # print(data.mul(10))
    # print(data.div(10))
    # print(data.neg())
    
  1. 張量點乘運算

    • 點乘指(Hadamard積)的是兩個 同維[同型]矩陣 對應位置的元素相乘,使用mul 和運算符 * 實現。

      # 2. 張量點乘運算
      print('=' * 30 + '張量點乘運算' + '=' * 30)
      A = torch.tensor([[1, 2], [3, 4]])
      B = torch.tensor([[5, 6], [7, 8]])# - 2.1 使用 mul(A,B)
      print('=' * 10 + 'mul 點乘' + '=' * 10)
      res = torch.mul(A, B)
      print(f'點乘后的結果:{res}')# - 2.2 使用 * 運算符
      print('=' * 10 + '* 點乘' + '=' * 10)
      res = A * B
      print(f'點乘后的結果:{res}')
      
  2. 張量矩陣乘法運算

    矩陣乘法運算要求第一個矩陣 shape: (n, m),第二個矩陣 shape: (m, p), 兩個矩陣點積運算 shape 為: (n, p)。

    • 1.運算符 @ 用于進行兩個矩陣的乘積運算
    • 2.torch.matmul 對進行乘積運算的兩矩陣形狀沒有限定.對數輸入的 shape 不同的張量, 對應的最后幾個維度必須符合矩陣運算規則
# 3. 張量矩陣乘法運算
print('=' * 30 + '張量矩陣乘法運算' + '=' * 30)
A = torch.tensor([[1, 2], [3, 4], [5, 6]])
B = torch.tensor([[5, 6], [7, 8]])#   3.1 使用 matmul(A,B)
# - torch.matmul 對進行乘積運算的兩矩陣形狀沒有限定.對數輸入的 shape 不同的張量, 對應的最后幾個維度必須符合矩陣運算規則
print(f'matmul(A,B) ={torch.matmul(A, B)}')#   3.2 使用@ 運算符
print(f'A @ B = {A @ B}')

4.張量運算函數

"""
- 均值
- 平方根
- 求和
- 指數計算
- 對數計算
.......
"""
import torchdata = torch.randint(0, 10, [2, 3], dtype=torch.float64)
print(data)# 1.均值
# 注意!! tensor必須為 float 或者 Double類型
print('=' * 10 + 'mean' + '=' * 10)
print(data.mean())
print(data.mean(dim=0))  # 按列求均值
print(data.mean(dim=1))  # 按行求均值# 2.求和
print('=' * 10 + 'sum' + '=' * 10)
print(data.sum())
print(data.sum(dim=0))
print(data.sum(dim=1))# 3.計算平方
print('=' * 10 + 'pow' + '=' * 10)
print(torch.pow(data, 2))
print(data.pow(2))# 4.計算平方根
print('=' * 10 + 'sqrt' + '=' * 10)
print(data.sqrt())
print(torch.sqrt(data))# 5.指數計算 e^n 次方
print('=' * 10 + 'exp' + '=' * 10)
print(data.exp())
print(torch.exp(data))# 6.對數計算 :以 e 為底數
print('=' * 10 + 'log' + '=' * 10)
print(data.log())
print(torch.log(data))
print(data.log2())
print(data.log10())

5.張量索引操作

  1. 簡單行列索引的使用

    格式:data[row,col]
    

    代碼

    data = torch.randint(0, 10, [4, 5])
    print('data->\r\n', data)# 1. 簡單行列索引的使用
    print('=' * 20, '簡單行列索引', '=' * 20)
    print(f'data[0, 0] -> {data[0, 0]}')
    print(f'data[:,0] -> {data[:, 0]}')
    
  2. 列表索引的使用

    格式:rows = [a,b,...]cols = [c,d...]訪問:data[rows,cols]
    含義:訪問 [a,c] | [b,d]....的值
    

    代碼:

    data = torch.randint(0, 10, [4, 5])
    print('data->\r\n', data)# 2. 列表索引的使用
    print('=' * 20, '列表索引', '=' * 20)
    #   2.1 返回 (0, 2)、(1, 3) 兩個位置的元素
    rows = [0, 1]
    cols = [2, 3]
    print(f'data[rows,cols] ->', data[rows, cols])
    #   2.2 返回行索引為 0 的第 1、2、3 列的值
    print(f'data[[0],[1,2]] ->', data[[0], [1, 2]])#   2.3 range()方式訪問元素:返回 (0, 1) 和 (1, 2) 兩個位置的元素
    print(f'data[rows,cols] ->', data[range(2), range(1, 3)])#   2.4 返回行索引為 0 和 1 的第 1、2、3 列的值
    print(f'data[[[0], [1]], [1, 2, 3]] ->', data[[[0], [1]], [1, 2, 3]])#   2.5 返回行索引為 0、1、2 的第 0、1、2 列的值 和 行索引為 1、2、3 的第 1、2、3 列的值
    print(f'data[[[0, 1, 2], [1, 2, 3]], [[0, 1, 2], [1, 2, 3]]] ->', data[[[0, 1, 2], [1, 2, 3]], [[0, 1, 2], [1, 2, 3]]])# print('data[[[0],[1,2,3]], [0,1,2]] ->',{data[0, 0]}) # 報錯, 因為索引的維度不匹配
    
  3. 范圍索引的使用

    • Numpy大致相同,但不 支持反向索引
    data = torch.randint(0, 10, [4, 5])
    print('data->\r\n', data)# 3. 范圍索引的使用
    print('=' * 20, '范圍索引', '=' * 20)
    # 3.1   獲取前三行前兩列元素的值
    print('data[:3,:2]->', data[:3, :2])# 3.2   獲取后兩行后兩列元素的值
    print('data[-2:,-2:]->', data[-2:, -2:])# print('data[3:1:-1,-2:]->', data[3:1:-1, -2:]) # 報錯,tensor不支持反向切片
    
  4. 布爾索引的使用

     - 和`Numpy`,`Pandas`大致相同
    
    # 4. 布爾索引的使用
    print('=' * 20, '布爾索引', '=' * 20)
    #   4.0 理解布爾索引的原理
    bool_index = [True, False, False, True, False]
    """
    注意它取元素時的方式!!!!第一行中滿足布爾索引的拿出來,當作一行第二行中滿足布爾索引的拿出來,當作一行以此類推
    """
    print('data[:,bool_index] ->\r\n', data[:, bool_index])#   4.1 獲取第三行大于 5的元素
    print(data[data[:, 2] > 5])#   4.2 獲取第二行大于 5的 列
    print('data[:,data[1]>5] ->\r\n', data[:, data[1] > 5])
    
  5. 多維索引的使用

    • Numpy,Pandas大致相同
data = torch.randint(0, 10, [4, 5])
print('data->\r\n', data)# 5. 多維索引的使用
print('=' * 20, '多維索引', '=' * 20)
data = torch.randint(0, 10, [3, 4, 5])
print('data->\r\n', data)
#   5.1 獲取第一維元素
print(data[0, :, :])
#   5.2 獲取第二維元素
print(data[:, 0, :])
#   5.3 獲取第三維元素 # 注意它取元素的方式!!!
print(data[:, :, 0])

6.張量形狀操作

0.形狀信息獲取
使用 shape 屬性或者 size 方法都可以獲得張量的形狀

data = torch.tensor([[10, 20, 30], [40, 50, 60]])# 1. 使用 shape 屬性或者 size 方法都可以獲得張量的形狀
print('使用 shape 屬性或者 size 方法都可以獲得張量的形狀')
print(data.shape, data.shape[0], data.shape[1])
print(data.size(), data.size(0), data.size(1))
print()

1.reshape方式修改形狀

? - reshape()

reshape 函數可以在保證張量數據不變的前提下改變數據的維度,將其轉換成指定的形狀
轉換順序:左右上下

data = torch.tensor([[10, 20, 30], [40, 50, 60]])# 2. 使用 reshape() 修改張量的形狀
print('使用 reshape() 修改張量的形狀')
reshape_data = data.reshape(1, data.shape[0] * data.shape[1])
print(f'reshape_data:{reshape_data}')
print(f'reshape_data:{data.reshape(1, -1)}')
print()
  1. 升維與降維

    • squeeze()

    • unsqueeze()

      - squeeze函數 刪除形狀為 1 的維度(降維)
      - unsqueeze函數 添加形狀為1的維度(升維)
      

      unsqueeze(dim=i):在索引為i的位置添加一個形狀為1的維度

      data = torch.tensor([[10, 20, 30], [40, 50, 60]])# 3. squeeze()和unsqueeze()函數
      print('squeeze()和unsqueeze()函數')
      mydata1 = torch.tensor([1, 2, 3, 4, 5, 6])
      print('mydata1->', mydata1.shape, mydata1)  # torch.Size([6])mydata2 = mydata1.unsqueeze(dim=0)
      print('在0維度上 擴展維度:', mydata2, mydata2.shape)  # torch.Size([1, 6])mydata3 = mydata1.unsqueeze(dim=1)
      print('在1維度上 擴展維度:\r\n', mydata3, mydata3.shape)  # torch.Size([6, 1])mydata4 = mydata1.unsqueeze(dim=-1)
      print('在-1維度上 擴展維度:\r\n', mydata3, mydata3.shape)  # torch.Size([6, 1])mydata5 = mydata4.squeeze()
      print('壓縮維度:', mydata5, mydata5.shape)  # torch.Size([6])
      print()
      
  2. 修改形狀

    • transpose()

    • permute()

      transpose 函數可以實現交換張量形狀的指定維度, 例如: 一個張量的形狀為 (2, 3, 4) 可以通過 transpose 函數把 3 和 4進行交換, 將張量的形狀變為 (2, 4, 3) 。
      permute 函數可以一次交換更多的維度。

      data = torch.tensor([[10, 20, 30], [40, 50, 60]])# 4.transpose() 和 permute()
      print('transpose() 和 permute()')
      data = torch.tensor(np.random.randint(0, 10, [2, 3, 3]))
      print(f'data shape:{data.size()}')
      print(data)
      #   4.1 交換1 和 2維度
      data_transpose = torch.transpose(data, 1, 2)
      print(f'data_transpose shape:{data_transpose.size()}')#   4.2 將data 的形狀修改為 (4, 5, 3), 需要變換多次
      data_transpose1 = torch.transpose(data, 0, 1)
      print(data_transpose1)
      data_transpose1 = torch.transpose(data_transpose1, 1, 2)
      print(f'data_transpose1 shape:{data_transpose1.size()}')#   4.3 使用 permute 函數將形狀修改為 (4, 5, 3)
      data_transpose2 = torch.permute(data, (1, 2, 0))
      print(f'data_transpose1 shape:{data_transpose2.size()}')
      
    • view()

      view 函數也可以用于修改張量的形狀,只能用于存儲在整塊內存中的張量。
      在 PyTorch 中,有些張量是由不同的數據塊組成的,它們并沒有存儲在整塊的內存中,view 函數無法對這樣的張量進行變形處理.
      例如: 一個張量經過了transpose 或者 permute 函數的處理之后,就無法使用 view 函數進行形狀操作。

    • contiguous()

      若要使用view函數, 需要使用contiguous() 變成連續以后再使用view函數
      is_contiguous() 判斷是否 連續存儲

data = torch.tensor([[10, 20, 30], [40, 50, 60]])# 5.view()和contiguous()函數"""
1. 一個張量經過了 transpose 或者 permute 函數的處理之后,就無法使用view 函數進行形狀操作若要使用view函數, 需要使用contiguous() 變成連續以后再使用view函數
2. 判斷張量是否使用整塊內存 is_contiguous
"""
print('view()和is_contiguous()函數')
data = torch.tensor([[10, 20, 30], [40, 50, 60]])
print('data--->', data, data.shape)# 5.1 判斷是否使用整塊內存
print(data.is_contiguous())  # True# 5.2 view
data_view = data.view(3, 2)
print('data_view ->', data_view, data_view.shape)# 5.3 判斷是否使用整塊內存
print('data_view.is_contiguous->', data_view.is_contiguous())
print()# 5.4 使用 transpose 函數修改形狀
print('view()和contiguous()函數')
data_transpose = data.transpose(0, 1)
print('data_transpose->', data_transpose, data_transpose.shape)
print('data_transpose.is_contiguous->', data_transpose.is_contiguous())
print(data_transpose.contiguous().is_contiguous())
data_view = data_transpose.contiguous().view(2, 3)
print('data_view->', data_view.shape, data_view)
print('')

7.張量拼接操作

張量拼接(Concatenation)是將多個張量按指定的維度連接起來的操作。

  • torch.cat()

    • torch.cat 是按指定維度將多個張量連接起來,拼接后的維度大小會變化,但總維數保持不變。

    • 使用時,所有張量在指定的拼接維度上必須形狀一致。

      # 1. torch.cat()
      print('================cat 方式拼接=====================')
      data1 = torch.randint(0, 10, [1, 2, 3])
      data2 = torch.randint(0, 10, [1, 2, 3])
      print(f'data1:{data1}')
      print(f'data2:{data2}')
      print()
      #   1.1 按 0維拼接
      new_data = torch.cat([data1, data2], dim=0)
      print('按 0維 拼接->', new_data, new_data.size())#   1.2 按 1維拼接
      new_data = torch.cat([data1, data2], dim=1)
      print('按 1維 拼接->', new_data, new_data.size())#   1.3 按 2維拼接
      new_data = torch.cat([data1, data2], dim=2)
      print('按 2維 拼接->', new_data, new_data.size())
      print()
      
  • torch.stack() [了解]

    • torch.stack 是在新維度上將多個張量連接起來,拼接后的總維數會增加 1。

    • 使用時,所有張量的形狀必須完全一致。

      # 2.stack
      print('================stack 方式拼接=====================')
      data1 = torch.randint(0, 10, [1, 2, 3])
      data2 = torch.randint(0, 10, [1, 2, 3])
      print(f'data1:{data1}')
      print(f'data2:{data2}')#   2.1 按 0維連接
      new_data = torch.stack([data1, data2], dim=0)
      print('按 0維 連接->', new_data, new_data.size())#   2.2 按 1維連接
      new_data = torch.stack([data1, data2], dim=1)
      print('按 1維 連接->', new_data, new_data.size())#   2.3 按 2維連接
      new_data = torch.stack([data1, data2], dim=2)
      print('按 2維 連接->', new_data, new_data.size())
      print()
      
torch.cattorch.stack 的區別
q特性torch.cattorch.stack
總維數變化不增加維數增加 1 個維數
形狀要求指定維度一致所有維度必須完全一致
典型應用沿某個軸擴展數據創建新的批量或時間步維度

8.自動微分模塊

- 反向傳播算法```properties在該算法中,參數(模型權重)會根據損失函數關于對應參數的梯度進行調整。為了計算這些梯度,PyTorch內置了名為 torch.autograd 的微分引擎。它支持任意計算圖的自動梯度計算, 使用 backward 方法、grad 屬性來實現梯度的計算和訪問.```

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

示例:

# 1. 當X為標量時梯度的計算
def scaler_grad_compute():x = torch.tensor(5)# 目標值: labely = torch.tensor(0.)# 設置要更新的權重和偏置的初始值w = torch.tensor(1, requires_grad=True, dtype=torch.float32)b = torch.tensor(3, requires_grad=True, dtype=torch.float32)# 設置網絡的輸出值z = w * x + b  # 矩陣乘法?# 設置損失函數,并進行損失的計算loss = torch.nn.MSELoss()loss = loss(z, y)# 自動微分loss.backward()# 打印 w,b 變量的梯度# backward 函數計算的梯度值會存儲在張量的 grad 變量中print(f'w->{w.grad}')print(f'b->{b.grad}')
# 2.非標量下時梯度的計算
def grad_compute():# 輸入張量(2,5)x = torch.ones(2, 5)# 輸出張量(2,3)y = torch.zeros(2, 3)# 設置要更新的權重和偏置的初始值w = torch.randn(5, 3, requires_grad=True)b = torch.randn(3, requires_grad=True)# 設置神經網絡的輸出值z = torch.matmul(x, w) + b# 設置損失函數,并進行損失的計算loss = torch.nn.MSELoss()loss = loss(z, y)  # 底層實現了__call__()方法print(y)# 自動微分loss.backward()# 打印 w,b 變量的梯度# backward 函數計算的梯度值會存儲在張量的 grad 變量中print("W的梯度:", w.grad)print("b的梯度", b.grad)

矩陣乘法?

# 設置損失函數,并進行損失的計算
loss = torch.nn.MSELoss()
loss = loss(z, y)# 自動微分
loss.backward()
# 打印 w,b 變量的梯度
# backward 函數計算的梯度值會存儲在張量的 grad 變量中
print(f'w->{w.grad}')
print(f'b->{b.grad}')

2.非標量下時梯度的計算

def grad_compute():
# 輸入張量(2,5)
x = torch.ones(2, 5)
# 輸出張量(2,3)
y = torch.zeros(2, 3)
# 設置要更新的權重和偏置的初始值
w = torch.randn(5, 3, requires_grad=True)
b = torch.randn(3, requires_grad=True)

# 設置神經網絡的輸出值
z = torch.matmul(x, w) + b
# 設置損失函數,并進行損失的計算
loss = torch.nn.MSELoss()
loss = loss(z, y)  # 底層實現了__call__()方法
print(y)
# 自動微分
loss.backward()
# 打印 w,b 變量的梯度
# backward 函數計算的梯度值會存儲在張量的 grad 變量中
print("W的梯度:", w.grad)
print("b的梯度", b.grad)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/75109.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75109.shtml
英文地址,請注明出處:http://en.pswp.cn/web/75109.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LS-LINUX-002 簡易創建SSH

LS-LINUX-002 簡易創建SSH 1. CentOS 8 創建和配置SSH服務 1.1 安裝SSH服務 CentOS 8 默認已經安裝了OpenSSH服務。如果沒有安裝,可以使用以下命令安裝: sudo dnf install -y openssh-server1.2 啟動SSH服務 安裝完成后,需要啟動SSH服務…

計算機專業求職面試的常見題目分類整理

以下是計算機專業求職面試的常見題目分類整理,每個大類精選20道高頻問題,結合參考內容進行解析與擴展,幫助系統化備考: 一、數據結構與算法 解釋時間復雜度和空間復雜度 時間復雜度衡量算法執行時間隨輸入規模的增長趨勢&#xf…

腳本啟動 Java 程序

如果你想在后臺啟動一個 Java 程序,并在終端窗口中顯示一個自定義的名字,可以通過編寫一個簡單的腳本來實現。以下是一個基于 Linux/macOS 的解決方案,使用 Bash 腳本啟動 Java 程序,并在終端窗口中顯示自定義標題。 示例腳本 創建…

CentOS禁用nouveau驅動

1、驗證 nouveau 是否在運行 lsmod | grep nouveau如果命令返回結果,說明 nouveau 驅動正在運行。 2、編輯黑名單文件 通過編輯黑名單配置文件來禁用 nouveau 驅動,這樣在系統啟動時不會加載它。 vi /etc/modprobe.d/blacklist-nouveau.conf修改以下…

Linux: network: tcpdump: packets dropped by kernel

文章目錄 最近遇到一個問題原因libpcap/tcpdump 接口linux/libpcap 接口內核的處理原因可能有以下幾種:解決方法:man pcap_stats最近遇到一個問題 tcpdump命令顯示有dropped的包,而且是被內核drop的。 [root@-one-01 ~]# tcpdump -i any udp and port 8080 -v -w /root/udp…

WEB安全--提權思路

一、情形 在我們成功上傳webshell到服務器中并拿到權限時,發現我們的權限很低無法執行特定的命令,這時為了能做更多的操作,我們就需要提升權限。 二、方式 2.1、Windows提權 1、普通用戶執行systeminfo命令獲取服務器的基本信息&#xff0…

001 vue

https://cn.vuejs.org/ 文章目錄 v-bindv-modelv-on修飾符條件渲染/控制:v-if v-show列表渲染 M:即Model,模型,包括數據和一些基本操作 V:即View,視圖,頁面渲染結果 VM:即View-Mode…

Tomcat 負載均衡

目錄 二、Tomcat Web Server 2.1 Tomcat 部署 2.1.1 Tomcat 介紹 2.1.2 Tomcat 安裝 2.2 Tomcat 服務管理 2.2.1 Tomcat 啟停 2.2.2 目錄說明 2.2.3編輯主頁 2.3 Tomcat管理控制臺 2.3.1開啟遠程管理 2.3.2 配置遠程管理密碼 三、負載均衡 3.1 重新編譯Nginx 3.1.1 確…

使用SpringSecurity下,發生重定向異常

使用SpringSecurity下,發生空轉異常 環境信息: Spring Boot 3.4.4 , jdk 17 , springSecurity 6.4.4 問題背景: 沒有自定義controller ,改寫了login 頁面,并且進行了成功后的跳轉處理&#xf…

S130N-ISI 全棧方案與云平臺深度協同:重構 PLC 開發新范式

一、什么是 PLC? 1.技術定義 PLC(Power Line Communication)是一種創新的通信技術,它以電力線作為天然的傳輸介質,通過先進的信號調制技術將高頻數據信號疊加于工頻電流之上,實現電力輸送與數據通信的雙頻共…

SU-YOLO:基于脈沖神經網絡的高效水下目標檢測模型解析

論文地址:https://arxiv.org/pdf/2503.24389 目錄 一、論文概述 二、創新點解析 1. 基于脈沖的水下圖像去噪(SpikeDenoiser) 原理與結構 2. 分離批歸一化(SeBN) 原理與結構 3. 優化的殘差塊(SU-Block) 原理與結構 三、代碼復現指南 環境配置 模型訓練 四、…

實現阿里云服務器上的文字聊天程序以及C語言寫的進程間通信(IPC)程序

實現阿里云服務器上的文字聊天程序以及C語言寫的進程間通信(IPC)程序 1. 基于 Linux 中的管道進行進程間通信 我們首先使用管道進行進程間通信,這對于簡單的聊天程序來說是一個比較簡單且實用的方法。 步驟: 創建管道&#xf…

COMSOL 與人工智能融合的多物理場應用:28個案例的思路、方法與工具概述

應用案例概述 基于 COMSOL 與人工智能(AI)結合的應用案例涵蓋了 28 個多領域場景,包括工程(如熱傳導優化、結構力學預測)、能源(如電池熱管理、燃料電池性能)、生物醫學(如藥物傳遞…

SAN及其ZONE

目錄 一、什么是SAN? 二、什么是ZONE? 三、配置ZONE 2.1 核心概念 2.2 劃分原則 2.3 Zone劃分最佳實踐 2.4 配置語法 1). 基于端口(Domain,Port)的zone語法 2). 基于WWN(World Wide Name)的Zone語法 3). 使用Alias簡化配置 4).…

Springboot框架—單元測試操作

Springboot單元測試的操作步驟: 1.添加依賴spring-boot-starter-test 在pom.xml中添加依賴spring-boot-starter-test 2.在src/test/java下新建java class 3.單元測試入口代碼結構 import org.junit.Test; import org.junit.runner.RunWith; import org.springfra…

用AbortController取消事件綁定

視頻教程 React - 🤔 Abort Controller 到底是什么神仙玩意?看完這個視頻你就明白了!💡_嗶哩嗶哩_bilibili AbortController的好處之一是事件綁定的函數已無需具名函數,匿名函數也可以被取消事件綁定了 //該代碼2秒后點擊失效…

JavaScript性能優化(上)

1. 減少 DOM 操作 減少 DOM 操作是優化 JavaScript 性能的重要方法,因為頻繁的 DOM 操作會導致瀏覽器重繪和重排,從而影響性能。以下是一些具體的策略和技術,可以幫助有效減少 DOM 操作: 1.1. 批量更新 DOM 親切與母體&#xff…

OpenCV 圖形API(14)用于執行矩陣(或圖像)與一個標量值的逐元素乘法操作函數mulC()

操作系統:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 編程語言:C11 描述 將矩陣與標量相乘。 mulC 函數將給定矩陣 src 的每個元素乘以一個給定的標量值: dst ( I ) saturate ( src1 ( I ) ? multiplier ) \…

持續集成與Jenkins安裝使用教程

一、持續集成與Jenkins 持續集成(Continuous integration,簡稱CI)指的是,頻繁地(一天多次)將代碼集成到主干。 持續集成的目的,就是讓產品可以快速迭代,同時還能保持高質量。 它的…

TIM定時器

一、TIM定時器 STM32高級定時器實戰:PWM、捕獲與死區控制詳解-CSDN博客 玩轉STM32_rivencode的博客-CSDN博客 二、相關函數 1.TIM_TimeBaseInitTypeDef結構體講解 typedef struct {uint16_t TIM_Prescaler; // 預分頻器,用于設置定時器計數頻…