国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【深度學習】pytorch——Tensor(張量)詳解

這篇具有很好參考價值的文章主要介紹了【深度學習】pytorch——Tensor(張量)詳解。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

筆記為自我總結整理的學習筆記,若有錯誤歡迎指出喲~

簡介

Tensor,又名張量。它可以是一個數(shù)(標量)、一維數(shù)組(向量)、二維數(shù)組(矩陣)和更高維的數(shù)組(高階數(shù)據(jù))。Tensor和Numpy的ndarrays類似,但PyTorch的tensor支持GPU加速。
【深度學習】pytorch——Tensor(張量)詳解,深度學習,深度學習,pytorch,人工智能

官方文檔
https://pytorch.org/docs/stable/tensors.html

import torch  as t
t.__version__		# '2.1.0+cpu'

創(chuàng)建Tensor

創(chuàng)建方法 示例 輸出
通過給定數(shù)據(jù)創(chuàng)建張量 torch.Tensor([1, 2, 3]) tensor([1., 2., 3.])
通過指定tensor的形狀 torch.Tensor(2, 3) tensor([[1.1395e+23, 1.6844e-42, 0.0000e+00],[0.0000e+00, 0.0000e+00, 0.0000e+00]])
使用torch.arange()創(chuàng)建連續(xù)的張量 torch.arange(0, 10, 2) tensor([0, 2, 4, 6, 8])
使用torch.zeros()創(chuàng)建全零張量 torch.zeros((3, 4)) tensor([[0., 0., 0., 0.], [0., 0., 0., 0.], [0., 0., 0., 0.]])
使用torch.ones()創(chuàng)建全一張量 torch.ones((2, 2)) tensor([[1., 1.], [1., 1.]])
使用torch.randn()創(chuàng)建隨機張量 torch.randn((3, 3)) tensor([[ 1.0553, -0.4815, 0.6344], [-0.7507, 1.3891, 1.0460], [-0.5625, 1.9531, -0.5468]])
使用torch.rand()創(chuàng)建在0到1之間均勻分布的隨機張量 torch.rand((3, 3)) tensor([[1, 6, 5], [2, 0, 4], [8, 5, 7]])
使用torch.randint()創(chuàng)建在給定范圍內的整數(shù)隨機張量 torch.randint(low=0, high=10, size=(3, 3)) tensor([[0, 8, 9], [1, 8, 7], [4, 4, 4]])
使用torch.eye()創(chuàng)建單位矩陣 torch.eye(5) tensor([[1., 0., 0., 0., 0.], [0., 1., 0., 0., 0.], [0., 0., 1., 0., 0.], [0., 0., 0., 1., 0.], [0., 0., 0., 0., 1.]])
從Python列表或Numpy數(shù)組創(chuàng)建張量 torch.tensor([1, 2, 3])torch.tensor(np.array([1, 2, 3])) tensor([1, 2, 3])或tensor([1, 2, 3], dtype=torch.int32)
將整個張量填充為常數(shù)值 torch.full((3, 3), 3.14) tensor([[3.1400, 3.1400, 3.1400], [3.1400, 3.1400, 3.1400], [3.1400, 3.1400, 3.1400]])
創(chuàng)建指定大小的空張量 torch.empty((3, 3)) tensor([[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]])
創(chuàng)建長度為5的隨機排列張量 torch.randperm(5) tensor([1, 2, 0, 3, 4])

torch.Tensor( )和torch.tensor( )的區(qū)別

torch.Tensor( )

torch.Tensor([1, 2, 3]) 的創(chuàng)建方式會根據(jù)輸入的數(shù)據(jù)類型來確定張量的數(shù)據(jù)類型。
例如,如果輸入的是整數(shù)列表,那么創(chuàng)建的張量將使用默認的數(shù)據(jù)類型 torch.float32。這意味著即使輸入的數(shù)據(jù)是整數(shù),張的數(shù)據(jù)類型也會被轉換為浮點數(shù)類型。

a = t.Tensor([1, 2, 3])
a
# tensor([1., 2., 3.])

torch.Tensor(1,2) 通過指定tensor的形狀創(chuàng)建張量

a= t.Tensor(1,2) # 注意和t.tensor([1, 2])的區(qū)別
a.shape
# torch.Size([1, 2])

torch.tensor( )

torch.tensor([1, 2, 3]) 的創(chuàng)建方式會根據(jù)輸入的數(shù)據(jù)類型靈活地選擇張量的數(shù)據(jù)類型。它可以接受各種數(shù)據(jù)類型的輸入,包括整數(shù)、浮點數(shù)、布爾值等,并根據(jù)輸入的數(shù)據(jù)類型自動確定創(chuàng)建張量使用的數(shù)據(jù)類型。

a = t.tensor([1, 2, 3])
a
# tensor([1, 2, 3])

tensor可以是一個數(shù)(標量)、一維數(shù)組(向量)、二維數(shù)組(矩陣)和更高維的數(shù)組(高階數(shù)據(jù))。

標量(scalar )

scalar = t.tensor(3.14) 
print('scalar: %s, shape of sclar: %s' %(scalar, scalar.shape))

輸出為:

scalar: tensor(3.1400), shape of sclar: torch.Size([])

向量(vector)

vector = t.tensor([1, 2, 3])
print('vector: %s, shape of vector: %s' %(vector, vector.shape))

輸出為:

vector: tensor([1, 2, 3]), shape of vector: torch.Size([3])

矩陣(matrix)

matrix = t.tensor([[0.1, 1.2], [2.2, 3.1], [4.9, 5.2]])
matrix,matrix.shape

輸出為:

(tensor([[0.1000, 1.2000],
         [2.2000, 3.1000],
         [4.9000, 5.2000]]), torch.Size([3, 2]))

常用Tensor操作

方法 描述
tensor.view(*args) 改變張量形狀
tensor.reshape(*args) 改變張量形狀
tensor.size() 返回張量形狀
tensor.dim() 返回張量維度
tensor.unsqueeze(dim) 在指定維度上添加一個新的維度
tensor.squeeze(dim) 壓縮指定維度的大小為1的維度
tensor.transpose(dim0, dim1) 交換兩個維度
tensor.permute(*dims) 重新排列張量的維度
tensor.flatten() 展平所有維度
tensor.mean(dim) 沿指定維度計算張量的平均值
tensor.sum(dim) 沿指定維度計算張量的和
tensor.max(dim) 沿指定維度返回張量的最大值
tensor.min(dim) 沿指定維度返回張量的最小值
tensor.argmax(dim) 沿指定維度返回張量最大元素的索引
tensor.argmin(dim) 沿指定維度返回張量最小元素的索引
tensor.add(value) 將標量加到張量中的每個元素
tensor.add(tensor) 將另一個張量加到該張量
tensor.sub(value) 將標量從張量中的每個元素減去
tensor.sub(tensor) 從該張量中減去另一個張量
tensor.mul(value) 將張量中的每個元素乘以標量
tensor.mul(tensor) 將該張量與另一個張量相乘
tensor.div(value) 將張量中的每個元素除以標量
tensor.div(tensor) 將該張量除以另一個張量

調整tensor的形狀

tensor.view

通過tensor.view方法可以調整tensor的形狀,但必須保證調整前后元素總數(shù)一致。view不會修改自身的數(shù)據(jù),返回的新tensor與原tensor共享內存,也即更改其中的一個,另外一個也會跟著改變。

a = t.arange(0, 6)
a.view(2, 3)

輸出結果為:

tensor([[0, 1, 2],
        [3, 4, 5]])
  • 案例1
b = a.view(-1, 2) # 當某一維為-1的時候,會自動計算它的大小
b.shape		# torch.Size([3, 2])
  • 案例2
b = a.view(-1, 3) # 當某一維為-1的時候,會自動計算它的大小
b.shape		# torch.Size([2,3])

tensor.squeeze與tensor.unsqueeze

tensor.squeeze(dim)

tensor.squeeze(dim) 方法用于壓縮張量中指定維度大小為1的維度,即將大小為1的維度去除。如果未指定 dim 參數(shù),則會去除所有大小為1的維度。

# 創(chuàng)建一個形狀為 (1, 3, 1, 4) 的張量
x = torch.arange(12).reshape(1, 3, 1, 4)
print(x.shape)  # 輸出: torch.Size([1, 3, 1, 4])

# 使用 squeeze 去除大小為1的維度
y = x.squeeze()
print(y.shape)  # 輸出: torch.Size([3, 4])

# 指定 dim 參數(shù)去除指定維度大小為1的維度
z = x.squeeze(0)
print(z.shape)  # 輸出: torch.Size([3, 1, 4])
tensor.unsqueeze(dim)

tensor.unsqueeze(dim) 方法用于在指定維度上添加一個新的維度,新的維度大小為1。

# 創(chuàng)建一個形狀為 (3, 4) 的張量
x = t.randn(3, 4)
print(x.shape)  # 輸出: torch.Size([3, 4])

# 使用 unsqueeze 在維度0上添加新維度
y = x.unsqueeze(0)
print(y.shape)  # 輸出: torch.Size([1, 3, 4])

# 使用 unsqueeze 在維度2上添加新維度
z = x.unsqueeze(2)
print(z.shape)  # 輸出: torch.Size([3, 4, 1])

None 可以為張量添加一個新的軸(維度)

在 PyTorch 中,使用 None 可以為張量添加一個新的軸(維度)。這個新的軸可以在任何位置添加,從而改變張量的形狀。以下是一個示例:

# 創(chuàng)建一個形狀為 (3, 4) 的二維張量
a = t.tensor([[1, 2, 3, 4],
                  [5, 6, 7, 8],
                  [9, 10, 11, 12]])

# 使用 None 在第一維度上新增一個軸
b = a[None, :, :]

print(b.shape)  # 輸出: torch.Size([1, 3, 4])

在上面的例子中,使用 None 將張量 a 在第一維度上擴展,結果得到了一個形狀為 [1, 3, 4] 的三維張量 b。通過為 a 添加新的軸,我們可以改變張量的維度和形狀,從而為其提供更多的靈活性。

索引操作

索引出來的結果與原tensor共享內存,也即修改一個,另一個會跟著修改。

切片索引

# 創(chuàng)建一個形狀為 (3, 4) 的二維張量
a = t.tensor([[1, 2, 3, 4],
            [5, 6, 7, 8],
            [9, 10, 11, 12]])

# 使用切片操作訪問其中的元素
b = a[:, 1:3]
print(b)
# tensor([[ 2,  3],
#         [ 6,  7],
#         [10, 11]])


# 可以使用 step 參數(shù)控制步長
c = a[::2, ::2]
print(c)
# tensor([[ 1,  3],
#         [ 9, 11]])


# 可以使用負數(shù)索引從后往前訪問元素
d = a[:, -2:]
print(d)
# tensor([[ 3,  4],
#         [ 7,  8],
#         [11, 12]])

gather( )

gather() 是 PyTorch 中的一個張量索引函數(shù),可以用于按照給定的索引從輸入張量中檢索數(shù)據(jù)。它的語法如下:

torch.gather(input, dim, index, out=None, sparse_grad=False) -> Tensor

其中,參數(shù)含義如下:

  • input:輸入張量,形狀為 (N*,*C) 或 (N,C,d1,d2,…,dk)。
  • dim:要檢索的維度。
  • index:用于檢索的索引張量,形狀為 (M,) 或(M,d1,d2,…,dk)。
  • out:輸出張量,形狀與 index 相同。
  • sparse_grad:是否在反向傳播時啟用稀疏梯度計算。

gather() 函數(shù)主要用于按照給定的索引從輸入張量中檢索數(shù)據(jù)。具體來說,對于二維輸入張量 input 和一維索引張量 index,gather() 函數(shù)會返回一個一維張量,其中每個元素是 input 中相應行和 index 中相應列的交點處的數(shù)值。對于更高維度的輸入,索引張量 index 可以選擇任何維度的元素。

示例1

# 創(chuàng)建一個形狀為 (3, 4) 的二維張量
input = t.tensor([[1, 2, 3, 4],
                  [5, 6, 7, 8],
                  [9, 10, 11, 12]])

# 創(chuàng)建一個索引張量,用于按列檢索元素
index = t.tensor([[0, 2, 3],
                  [1, 3, 2]])

# 使用 gather 函數(shù)按列檢索元素,返回一個二維張量
output = t.gather(input, dim=1, index=index)

print(output)
# 輸出:
# tensor([[ 1,  3,  4],
#         [ 6,  8,  7]])

在上面的示例中:

  • 創(chuàng)建了一個形狀為 (3, 4) 的二維輸入張量 input
  • 創(chuàng)建了一個形狀為 (2, 3) 的索引張量 index,用于檢索元素。
  • 使用 gather() 函數(shù)按列檢索元素,并將結果存儲到輸出張量 output 中。

示例2

# 創(chuàng)建一個形狀為 (2, 3, 4) 的三維張量
input = t.tensor([[[1, 2, 3, 4],
                       [5, 6, 7, 8],
                       [9, 10, 11, 12]],
                      
                      [[13, 14, 15, 16],
                       [17, 18, 19, 20],
                       [21, 22, 23, 24]]])

# 創(chuàng)建一個形狀為 (2, 3) 的索引張量
index = t.tensor([[0, 2, 1],
                      [2, 1, 0]])

# 添加一個維度到索引張量
index = index.unsqueeze(2)

# 使用 gather 函數(shù)按第二個維度檢索元素
output_dim_1 = t.gather(input, dim=1, index=index)

# 使用 gather 函數(shù)按第三個維度檢索元素
output_dim_2 = t.gather(input, dim=2, index=index)

print(output_dim_1)
print(output_dim_2)
'''
輸出:
tensor([[[ 1],
         [ 9],
         [ 5]],

        [[21],
         [17],
         [13]]])
tensor([[[ 1],
         [ 7],
         [10]],

        [[15],
         [18],
         [21]]])
'''

高級索引

高級索引可以看成是普通索引操作的擴展,但是高級索引操作的結果一般不和原始的Tensor共享內存。

x = t.arange(0,27).view(3,3,3)
print(x)

a = x[[1, 2], [1, 2], [2, 0]] # x[1,1,2]和x[2,2,0]
print(a)

b = x[[2, 1, 0], [0], [1]] # x[2,0,1],x[1,0,1],x[0,0,1]
print(b)

c = x[[0, 2], ...] # x[0] 和 x[2]
print(c)

輸出結果為:

tensor([[[ 0,  1,  2],
         [ 3,  4,  5],
         [ 6,  7,  8]],

        [[ 9, 10, 11],
         [12, 13, 14],
         [15, 16, 17]],

        [[18, 19, 20],
         [21, 22, 23],
         [24, 25, 26]]]) 

tensor([14, 24]) 

tensor([19, 10,  1]) 

tensor([[[ 0,  1,  2],
         [ 3,  4,  5],
         [ 6,  7,  8]],

        [[18, 19, 20],
         [21, 22, 23],
         [24, 25, 26]]])

Tensor數(shù)據(jù)類型

以下是常見的 Tensor 數(shù)據(jù)類型及其相應的字符串表示:

數(shù)據(jù)類型 字符串表示
32 位浮點數(shù) ‘torch.float32’ 或 ‘torch.float’
64 位浮點數(shù) ‘torch.float64’ 或 ‘torch.double’
16 位浮點數(shù)(半精度) ‘torch.float16’ 或 ‘torch.half’
8 位整數(shù)(無符號) ‘torch.uint8’
8 位整數(shù)(有符號) ‘torch.int8’
16 位整數(shù) ‘torch.int16’ 或 ‘torch.short’
32 位整數(shù) ‘torch.int32’ 或 ‘torch.int’
64 位整數(shù) ‘torch.int64’ 或 ‘torch.long’
布爾型 ‘torch.bool’

使用 PyTorch 中的 dtype 屬性可以獲取 Tensor 的數(shù)據(jù)類型。例如:

x = t.randn(3, 4) # 創(chuàng)建一個隨機的 FloatTensor

print(x.dtype) # 輸出 torch.float32

Tensor逐元素

以下是 PyTorch 支持的逐元素操作及其相應的函數(shù)名:

操作 函數(shù)名
加法 torch.add()、torch.add_()
減法 torch.sub()、torch.sub_()
乘法 torch.mul()、torch.mul_()
除法 torch.div()、torch.div_()
冪運算 torch.pow()、torch.pow_()
取整 torch.floor()torch.floor_()
取整(向上) torch.ceil()、torch.ceil_()
取整(四舍五入) torch.round()torch.round_()
指數(shù)函數(shù) torch.exp()、torch.exp_()
對數(shù)函數(shù) torch.log()torch.log_()
平方根函數(shù) torch.sqrt()、torch.sqrt_()
絕對值 torch.abs()、torch.abs_()
正弦函數(shù) torch.sin()torch.sin_()
余弦函數(shù) torch.cos()、torch.cos_()
正切函數(shù) torch.tan()torch.tan_()
反正弦函數(shù) torch.asin()、torch.asin_()
反余弦函數(shù) torch.acos()torch.acos_()
反正切函數(shù) torch.atan()、torch.atan_()

下面是三個逐元素操作的示例:

  1. 加法操作:
x = t.tensor([1, 2, 3])
y = t.tensor([4, 5, 6])

result = t.add(x, y)

print(result)  # 輸出 tensor([5, 7, 9])
  1. 平方根函數(shù)操作:
x = t.tensor([4.0, 9.0, 16.0])

result = t.sqrt(x)

print(result)  # 輸出 tensor([2., 3., 4.])
  1. 絕對值操作:
x = t.tensor([-1, -2, 3, -4])

result = t.abs(x)

print(result)  # 輸出 tensor([1, 2, 3, 4])

Tensor歸并操作

以下是 PyTorch 支持的歸并操作及其相應的函數(shù)名:

操作 函數(shù)名
求和 torch.sum()
平均值 torch.mean()
方差 torch.var()
標準差 torch.std()
最小值 torch.min()
最大值 torch.max()
中位數(shù) torch.median()
排序 torch.sort()

下面是三個歸并操作的示例:

  1. 求和操作:
x = t.tensor([[1, 2], [3, 4]])

result = t.sum(x)

print(result)  # 輸出 tensor(10)
  1. 平均值操作:
x = t.tensor([[1, 2], [3, 4]], dtype=t.float)

result = t.mean(x)

print(result)  # 輸出 tensor(2.5000)
  1. 最小值操作:
x = t.tensor([[1, 2], [3, 4]])

result = t.min(x)

print(result)  # 輸出 tensor(1)

Tensor比較操作

以下是 PyTorch 支持的比較、排序和取最大/最小值的操作及其相應的函數(shù)名:

操作 函數(shù)名 功能
大于/小于/大于等于/小于等于/等于/不等于 torch.gt()/torch.lt()/torch.ge()/ torch.le()/torch.eq()/torch.ne() 對兩個張量進行比較,返回一個布爾型張量。
最大的k個數(shù) torch.topk() 返回輸入張量中最大的 k 個元素及其對應的索引。
排序 torch.sort() 對輸入張量進行排序。
比較兩個 tensor 最大/最小值 torch.max()/torch.min() 比較兩個張量之間的最大值或最小值,返回一個張量。

下面是三個操作的示例:

  1. topk 操作:
x = t.tensor([1, 3, 2, 4, 5])
result = t.topk(x, k=3)

print(result)  
'''輸出:
torch.return_types.topk(
values=tensor([5, 4, 3]),
indices=tensor([4, 3, 1]))
'''

上述代碼中,使用 topk() 函數(shù)獲取張量 x 中的前三個最大值及其索引。

  1. sort 操作:
x = t.tensor([1, 3, 2, 4, 5])
result = t.sort(x)

print(result)  
'''輸出:
torch.return_types.sort(
values=tensor([1, 2, 3, 4, 5]),
indices=tensor([0, 2, 1, 3, 4]))
'''

上述代碼中,使用 sort() 函數(shù)對張量 x 進行排序,并返回排好序的張量及其索引。

  1. max 操作:
x = t.tensor([1, 3, 2, 4, 5])
y = t.tensor([2, 3, 1, 5, 4])

result = t.max(x, y)

print(result)  # 輸出 tensor([2, 3, 2, 5, 5])

上述代碼中,使用 max() 函數(shù)比較張量 xy 中的最大值,并返回一個新的張量。

Tensor線性代數(shù)

函數(shù)名 功能
torch.trace() 計算矩陣的跡
torch.diag() 提取矩陣的對角線元素
torch.triu() 提取矩陣的上三角部分,可指定偏移量
torch.tril() 提取矩陣的下三角部分,可指定偏移量
torch.mm() 計算兩個2維張量的矩陣乘法
torch.bmm() 計算兩個3維張量的批量矩陣乘法
torch.addmm() 將兩個矩陣相乘并加上一個矩陣
torch.addbmm() 批量矩陣相乘并加上一個矩陣
torch.addmv() 矩陣和向量相乘并加上一個向量
torch.addr() 計算兩個向量的外積
torch.badbmm() 批量進行矩陣乘法操作的累積和
torch.t() 轉置張量或矩陣
torch.dot() 計算兩個1維張量的點積
torch.cross() 計算兩個3維張量的叉積
torch.inverse() 計算方陣的逆矩陣
torch.svd() 計算矩陣的奇異值分解

以下是幾個線性代數(shù)操作的示例:

  1. torch.trace() 計算矩陣的跡:
x = t.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

result = t.trace(x)

print(result)  # 輸出 tensor(15)

上述代碼中,我們使用 trace() 函數(shù)計算矩陣 x 的跡。

  1. torch.diag() 提取矩陣的對角線元素:
x = t.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

result = t.diag(x)

print(result)  # 輸出 tensor([1, 5, 9])

上述代碼中,我們使用 diag() 函數(shù)提取矩陣 x 的對角線元素。

  1. torch.mm() 計算兩個2維張量的矩陣乘法:
x = t.tensor([[1, 2], [3, 4]])
y = t.tensor([[5, 6], [7, 8]])

result = t.mm(x, y)

print(result)  # 輸出 tensor([[19, 22], [43, 50]])

上述代碼中,我們使用 mm() 函數(shù)計算張量 xy 的矩陣乘法。

Tensor和Numpy

Tensor和Numpy數(shù)組之間具有很高的相似性,彼此之間的互操作也非常簡單高效。需要注意的是,Numpy和Tensor共享內存。

當遇到Tensor不支持的操作時,可先轉成Numpy數(shù)組,處理后再轉回tensor,其轉換開銷很小。

Numpy和Tensor共享內存

import numpy as np
a = np.ones([2, 3],dtype=np.float32)
print("\na:\n",a)

# Tensor——>Numpy
b = t.from_numpy(a)
print("\nb:\n",b)

a[0, 1]=100
print("\n改變后的b:\n",b)

# Numpy——>Tensor
c = b.numpy() # a, b, c三個對象共享內存
print("\nc:\n",c)

輸出結果為:

a:
 [[1. 1. 1.]
 [1. 1. 1.]]

b:
 tensor([[1., 1., 1.],
        [1., 1., 1.]])

改變后的b:
 tensor([[  1., 100.,   1.],
        [  1.,   1.,   1.]])

c:
 [[  1. 100.   1.]
 [  1.   1.   1.]]

注意:numpy的數(shù)據(jù)類型和Tensor的類型不一樣的時候,數(shù)據(jù)會被復制,不會共享內存

import numpy as np
a = np.ones([2, 3])
print("\na:\n",a)

# Tensor——>Numpy
b = t.Tensor(a)
print("\nb:\n",b)

# Tensor——>Numpy
c = t.from_numpy(a)
print("\nc:\n",c)

a[0, 1]=100
print("\n改變后的b:\n",b,"\n\n改變后的c:\n",c)

輸出結果為:

a:
 [[1. 1. 1.]
 [1. 1. 1.]]

b:
 tensor([[1., 1., 1.],
        [1., 1., 1.]])

c:
 tensor([[1., 1., 1.],
        [1., 1., 1.]], dtype=torch.float64)

改變后的b:
 tensor([[1., 1., 1.],
        [1., 1., 1.]]) 

改變后的c:
 tensor([[  1., 100.,   1.],
        [  1.,   1.,   1.]], dtype=torch.float64)

Tensor的數(shù)據(jù)結構

tensor分為頭信息區(qū)(Tensor)和存儲區(qū)(Storage),信息區(qū)主要保存著tensor的形狀(size)、步長(stride)、數(shù)據(jù)類型(type)等信息,而真正的數(shù)據(jù)則保存成連續(xù)數(shù)組。由于數(shù)據(jù)動輒成千上萬,因此信息區(qū)元素占用內存較少,主要內存占用則取決于tensor中元素的數(shù)目,也即存儲區(qū)的大小。
【深度學習】pytorch——Tensor(張量)詳解,深度學習,深度學習,pytorch,人工智能

一個tensor有著與之相對應的storage, storage是在data之上封裝的接口,不同tensor的頭信息一般不同,但卻可能使用相同的數(shù)據(jù)。

a = t.arange(0, 6)
print(a.storage())

b = a.view(2, 3)
print(b.storage())

# 一個對象的id值可以看作它在內存中的地址
# storage的內存地址一樣,即是同一個storage
id(b.storage()) == id(a.storage())

輸出結果為:

0
 1
 2
 3
 4
 5
[torch.storage.TypedStorage(dtype=torch.int64, device=cpu) of size 6]

 0
 1
 2
 3
 4
 5
[torch.storage.TypedStorage(dtype=torch.int64, device=cpu) of size 6]

True

絕大多數(shù)操作并不修改tensor的數(shù)據(jù),而只是修改了tensor的頭信息。這種做法更節(jié)省內存,同時提升了處理速度。在使用中需要注意。 此外有些操作會導致tensor不連續(xù),這時需調用tensor.contiguous方法將它們變成連續(xù)的數(shù)據(jù),該方法會使數(shù)據(jù)復制一份,不再與原來的數(shù)據(jù)共享storage。

思考:高級索引一般不共享stroage,而普通索引共享storage,為什么?

在 PyTorch 中,高級索引(advanced indexing)和普通索引(basic indexing)的行為是不同的,這導致了對存儲(storage)共享的處理方式也不同。

普通索引是指使用整數(shù)、切片或布爾掩碼進行索引,例如 tensor[0]、tensor[1:3]tensor[mask]。在這種情況下,返回的索引結果與原來的 Tensor 共享相同的存儲空間。這意味著對返回的索引結果進行修改會影響到原來的 Tensor,因為它們實際上指向相同的內存位置。

示例代碼:

import torch

x = torch.tensor([1, 2, 3, 4, 5])
y = x[1:3]

y[0] = 10

print(x)  # 輸出 tensor([ 1, 10,  3,  4,  5])

在上述代碼中,對索引結果 y 進行修改后,原始 Tensor x 也被修改了,這是因為它們共享了相同的存儲空間。

而對于高級索引,情況不同。高級索引是指使用整數(shù)數(shù)組或布爾數(shù)組進行索引,例如 tensor[[0, 2]]tensor[mask]。在這種情況下,返回的索引結果與原來的 Tensor 不再共享相同的存儲空間。返回的索引結果將會創(chuàng)建一個新的 Tensor,其存儲空間是獨立的。

示例代碼:

import torch

x = torch.tensor([1, 2, 3, 4, 5])
indices = torch.tensor([0, 2])
y = x[indices]

y[0] = 10

print(x)  # 輸出 tensor([1, 2, 3, 4, 5])

在上述代碼中,對索引結果 y 進行修改后,原始 Tensor x 并沒有被修改,因為它們不再共享相同的存儲空間。

這種差異是由于普通索引和高級索引的底層機制不同所導致的。普通索引可以通過在存儲中使用偏移量和步長來定位對應的元素,因此共享存儲;而高級索引需要創(chuàng)建一個新的 Tensor 來存儲索引結果,因此不共享存儲。

了解這種差異很重要,因為它會影響到對原始 Tensor 和索引結果進行操作時是否會相互影響。文章來源地址http://www.zghlxwxcb.cn/news/detail-738838.html

到了這里,關于【深度學習】pytorch——Tensor(張量)詳解的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包