テンソルは配列や行列によく似たデータ構造です テンソルは配列や行列によく似たデータ構造です。テンソルは、配列や行列によく似たデータ構造です。PyTorch
では、モデルの入力と出力、およびモデルのパラメーターをエンコードするためにテンソルを使用します。
1. テンソルの初期化
torch.tensor(data, dtype=None, device=None, requires_grad=False, pin_memory=False) → Tensor
·data: データのデータ型は、リスト、タプル、numpy 配列 ndarray、スカラー (スカラーとも呼ばれます)、およびその他のデータ型です。
·dtype: このパラメータはオプションであり、デフォルトは None です。設定されていない場合、生成された Tensor データ型は、データに渡されたパラメータのデータ型をコピーします。たとえば、data のデータ型が float の場合、データ型は次のようになります。デフォルトで生成される torch.FloatTensor の Tensor。
·device: このパラメータはオプションであり、デフォルトは None です。設定されていない場合、メモリは現在のデバイス上で生成された Tensor に割り当てられます。
·requires_grad: このパラメータはオプションであり、デフォルトは False です。False の場合、作成された Tensor は勾配演算を実行できません。True に変更すると、勾配を計算できます。
·pin_memory: このパラメータはオプションであり、デフォルトは False です。True に設定すると、現在の Tensor は固定メモリに割り当てられますが、CPU 内の Tensor にのみ適用されます。
require_grad パラメータを設定する関数
Tensor.requires_grad_(requires_grad=True) → Tensor
autograd がこの tensor に対する操作を記録する必要があるかどうかを変更します。この tensor の require_grad 属性をその場で設定します。このテンソルを返します。
torch.no_grad の役割
このモジュールでは、計算されたすべてのテンソルのrequirements_gradが自動的にFalseに設定され、ビデオメモリを大幅に節約できます。
torch.no_grad で計算されたテンソル (x という名前) が require_grad = True であっても、x から取得された新しいテンソル (w という名前) は False で、grad_fn も None です。つまり、 w は微分されません。以下に例を示します。
x = torch.rand(10, 5, requires_grad = True)
y = torch.rand(10, 5, requires_grad = True)
with torch.no_grad():
w = x + y
print(w.requires_grad)
print(w.grad_fn)
#False
#None
data=[[1,2],[3,4]]
x_data=torch.tensor(data)
2. Numpy配列から変換
np_array=np.array(data)
x_np=torch.from_numpy(np_array)
t = torch.ones(5)
print(f"t: {
t}")
n = t.numpy()#反之Numpy array也可以由tensor转化而来
print(f"n: {
n}")
#t: tensor([1., 1., 1., 1., 1.])
#n: [1. 1. 1. 1. 1.]
t.add_(1)
print(f"t: {
t}")
print(f"n: {
n}")
#t: tensor([2., 2., 2., 2., 2.])
#n: [2. 2. 2. 2. 2.]
#CPU上的张量和NumPy数组可以共享它们的底层内存位置,所以改变一个的同时可以改变另一个。
3. 別のテンソルの形状から変換
x_ones = torch.ones_like(x_data)
print(f"Ones Tensor: \n {
x_ones} \n")
x_rand = torch.rand_like(x_data, dtype=torch.float)
print(f"Random Tensor: \n {
x_rand} \n")
#Ones Tensor:
# tensor([[1, 1],
# [1, 1]])
#Random Tensor:
# tensor([[0.5900, 0.9701],
# [0.3483, 0.4137]])
4. ランダムな値または定数を使用し、形状タプルを使用してテンソルを定義します
shape = (2,3,)
rand_tensor = torch.rand(shape)
ones_tensor = torch.ones(shape)
zeros_tensor = torch.zeros(shape)
print(f"Random Tensor: \n {
rand_tensor} \n")
print(f"Ones Tensor: \n {
ones_tensor} \n")
print(f"Zeros Tensor: \n {
zeros_tensor}")
#Random Tensor:
# tensor([[0.8330, 0.5998, 0.8980],
# [0.6941, 0.3293, 0.7102]])
#
#Ones Tensor:
# tensor([[1., 1., 1.],
# [1., 1., 1.]])
#
#Zeros Tensor:
# tensor([[0., 0., 0.],
# [0., 0., 0.]])
torch.Tensor(data): 入力データを torch.FloatTensor() に変換する
torch.Tensor() は空の FloatTensor を作成できますが、torch.tensor() を使用するとエラーが報告されます。
a=torch.tensor(1)
print(a)
print(a.type())
a=torch.Tensor(1)
print(a)
print(a.type())
#tensor(1)
#torch.LongTensor
#tensor([1.0010e-38])
#torch.FloatTensor
2. テンソルの性質
Tensor.shape[i] は i 番目の次元の値を表します
tensor = torch.rand(3,4)
print(f"Shape of tensor: {
tensor.shape}")
print(f"Shape of tensor: {
tensor.shape[0]}")
print(f"Shape of tensor: {
tensor.shape[1]}")
print(f"Datatype of tensor: {
tensor.dtype}")
print(f"Device tensor is stored on: {
tensor.device}")
print(tensor.requires_grad) #表示autograd时是否需要计算此tensor的梯度,默认False
print(tensor.grad) #存储梯度的值,初始为None
print(tensor.grad_fn) #反向传播时,用来计算梯度的函数
print(tensor.is_leaf) #该张量节点在计算图中是否为叶子节点
'''
当这个 tensor 是用户创建的时候,它是一个叶子节点,
当这个 tensor 是由其他运算操作产生的时候,它就不是一个叶子节点
'''
print(f"mean of tensor: {
Tensor.mean(tensor)}")
print(f"variance of tensor: {
Tensor.var(tensor)}")
#Shape of tensor: torch.Size([3, 4])
#Shape of tensor: 3
#Shape of tensor: 4
#Datatype of tensor: torch.float32
#Device tensor is stored on: cpu
#False
#None
#None
#True
Required_grad: テンソルの勾配を計算する必要がある場合は True、それ以外の場合は False。テンソルを作成するとき、requires_grad を True として指定できます (デフォルトは False)。
grad_fn: grad_fn は、勾配の計算を容易にするために変数の由来を記録するために使用されます。y = x*3、y.grad_fn は、x から y を計算するプロセスを記録します。grad_fn=None を指定してリーフ ノードを直接作成します。
grad:backward() を実行した後、x から x.grad までの勾配値を確認します。
require_grad、grad、grad_fn、is_leaf の詳細については、この記事を参照してください。
3. テンソルの演算
1. Tensor はデフォルトで CPU 上に作成されます。(GPU の可用性を確認した後) .to メソッドを使用して Tensor を明示的に GPU に移動する必要があります。
if torch.cuda.is_available():
tensor = tensor.to("cuda")
2 インデックス付け、スライス、転置(並べ替え、転置)操作
tensor = torch.ones(4, 4)
print(f"First row: {
tensor[0]}")
print(f"First column: {
tensor[:, 0]}")
print(f"Last column: {
tensor[..., -1]}")#此处用:或...都行
tensor[:,1] = 2
print(tensor)
#First row: tensor([1., 1., 1., 1.])
#First column: tensor([1., 1., 1., 1.])
#Last column: tensor([1., 1., 1., 1.])
#tensor([[1., 2., 1., 1.],
# [1., 2., 1., 1.],
# [1., 2., 1., 1.],
# [1., 2., 1., 1.]])
'''
def transpose(self, dim0, dim1): -> Tensor
def permute(self, *dims): -> Tensor
transpose:只能选择tensor中两个维度进行转置
permute:可以让tensor按照任意指定维度顺序进行转置
'''
tensor1=tensor.transpose(0,1)#例原本坐标为(0,1,1,0)的点就会变成(1,0,1,0)
tensor2=tensor.permute(1,0,3,2)#例原本坐标为(0,1,1,0)的点就会变成(1,0,0,1)
注: ただし、numpy の def transpose(self, *axes) : この方法は、numpy.array() を指定された次元の順序で転置することです。
3. 次元数を減らしたり次元数を増やしたりする、圧縮操作と圧縮解除操作
松明 。unsqueeze ( input , dim ) → Tensor \text torch.unsqueeze(input, dim) → Tensorトーク。_ _ uns queeze (入力, _ _ _ _ _ _ _ディム)_→テンソル_ _ _
指定された位置に挿入されたサイズ 1 の次元を持つ新しいテンソルを返します。
返されたテンソルは、このテンソルと同じ基になるデータを共有します。
[-input.dim() - 1, input.dim() + 1) の範囲内の dim 値を使用できます。負の dim は、 dim = dim + input.dim() + 1 で適用される unsqueeze() に対応します。
>>> x = torch.tensor([1, 2, 3, 4])#shape为4
>>> torch.unsqueeze(x, 0)#shape变为1×4
tensor([[ 1, 2, 3, 4]])
>>> torch.unsqueeze(x, 1)#shape变为4×1
tensor([[ 1],
[ 2],
[ 3],
[ 4]])
松明 。スクイーズ ( input , dim = N one ) → テンソル \text torch.squeeze(input, dim=None) → テンソルトーク。_ _ squeeze (入力、_ _ _ _ _ _私は=なし)_ _ _→テンソル_ _ _
size の入力のすべての次元が削除されたテンソルを返します。
たとえば、入力の形状が次の場合: ( A × 1 × B × C × 1 × D ) (A \times 1 \times B \times C \times 1 \times D)( A×1×B×C×1×D )の場合、出力テンソルの形状は次のようになります:( A × B × C × D ) (A \times B \times C \times D)( A×B×C×D )
dim が指定された場合、指定された次元でのみスクイーズ操作が実行されます。入力が形状の場合:( A × 1 × B ) (A \times 1 \times B)( A×1×B )、squeeze(input, 0) はテンソルを変更しないままにしますただし、squeeze(input, 1) はテンソルを形状( A × B ) (A \times B)に圧縮します。( A×B )
>>> x = torch.zeros(2, 1, 2, 1, 2)
>>> x.size()
torch.Size([2, 1, 2, 1, 2])
>>> y = torch.squeeze(x)
>>> y.size()
torch.Size([2, 2, 2])
>>> y = torch.squeeze(x, 0)#leaves the tensor unchanged
>>> y.size()
torch.Size([2, 1, 2, 1, 2])
>>> y = torch.squeeze(x, 1)
>>> y.size()
torch.Size([2, 2, 1, 2])
4. 四則演算 torch.matmul, ±*/
基本四則演算
a + b は torch.add() と同等
a - b は torch.sub() と同等
a * b は torch.mul() と同等
a / b は torch.div() と同等
直接加算、減算、乗算、除算、累乗、平方根 torch.sqrt
a=10000**(torch.arange(0, 256, 2).float() / 256)
*メソッドの操作は mul で、 / メソッドの操作も同様で、次のように分類されます。
(1). Tensor*scalar k の結果は、Tensor の各要素に k を乗算したものです。
>>> a = torch.ones(3,4)
>>> a
tensor([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
>>> a * 2
tensor([[2., 2., 2., 2.],
[2., 2., 2., 2.],
[2., 2., 2., 2.]])
(2)Tensor* 1 次元テンソル
Tensor* 行ベクトルの結果は、各列に行ベクトルの対応する列の値を乗算したもの
Tensor* と列ベクトルの結果は、各行を乗算したもの列ベクトルの対応する行の値によって決まります。
>>> a = torch.ones(3,4)
>>> a
tensor([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
>>> b = torch.Tensor([1,2,3,4])
>>> b
tensor([1., 2., 3., 4.])
>>> a * b
tensor([[1., 2., 3., 4.],
[1., 2., 3., 4.],
[1., 2., 3., 4.]])
>>> b = torch.Tensor([1,2,3]).reshape((3,1))
>>> b
tensor([[1.],
[2.],
[3.]])
>>> a * b
tensor([[1., 1., 1., 1.],
[2., 2., 2., 2.],
[3., 3., 3., 3.]])
(3)Tensor1*Tensor2
乗算する 2 つの tensor の次元が一致しないが、Tensor2 の次元が Tensor1 の後者の次元と等しい場合、それらを乗算することができます。
乗算すると、Tensor2 は繰り返して Tensor1 の形状に拡張されます。
Tensor1 と Tensor2 の次元が同じである場合、対応する次元の値は同じである必要があります。対応する次元の値が異なる場合は、いずれか 1 つが 1 である必要があり、そうでない場合はエラーが報告されます。
+ メソッドの演算は add、 - メソッドの演算も同様で次のように分類されます
(1) (2) 状況は上記と同じ
(3) Tensor1+Tensor2
加算された 2 つのテンソルの次元が一致しない場合、 Tensor2 の次元は Tensor1 の後者の次元と同じです。対応する値が等しい場合、それらを加算できます。
追加する場合、Tensor2 は繰り返して Tensor1 の形状に拡張されます。
a = torch.ones([8, 4, 5, 6])
b = torch.ones([5, 6])
c = a+b
print(c.shape)#(8, 4, 5, 6)
a = torch.ones([8, 4, 5, 6])
b = torch.ones([8, 1, 5, 6])
c = torch.ones([8, 2, 5, 6])
a+b可以。相加过程也是先将b重复扩充为与a相同shape
a+c报错
マムル操作
y1 = tensor @ tensor.T
y2 = tensor.matmul(tensor.T)#类似矩阵乘法
y3 = torch.rand_like(y1)
torch.matmul(tensor, tensor.T, out=y3)
#y1,y2,y3是相同的
z1 = tensor * tensor
z2 = tensor.mul(tensor)#两个tensor的对应位置相乘
z3 = torch.rand_like(tensor)
torch.mul(tensor, tensor, out=z3)
#z1,z2,z3是相同的
#tensor([[1., 4., 1., 1.],
# [1., 4., 1., 1.],
# [1., 4., 1., 1.],
# [1., 4., 1., 1.]])
5、torch.reshape(入力, 形状) → テンソル
'''
Parameters
input (Tensor) – the tensor to be reshaped
shape (tuple of python:ints) – the new shape
A single dimension may be -1, in which case it’s inferred from the remaining dimensions and
the number of elements in input.
一个单一的维度可能是-1,在这种情况下,它是由其余的维度和输入的元素数量推断出来的。
'''
应用举例:假设当我们的dataloader的batch_size设置为64。并且经过卷积(out_channels=6)之后,
我们需要使用tensorboard可视化,而彩色图片的writer.add.images(output)的彩色图片是in_channels=3的。
那么则需要对卷积后的图片进行reshape,Torch.size(64,6,30,30)---->torch.size(-1,3,30,30),-1的意思为最后自动计算其batch_size。
输出通道由6变成了3,从而每一个通道的数量增加,因而结果为torch.size(128,3,30,30)
6. Tensor.view(*shape) → Tensor、使用前に contiguous() メソッドを追加する必要がある場合があります。
自己テンソルと同じデータを持つ、異なる形状の新しいテンソルを返します。
x = torch.randn(4, 4)
x.size()#torch.Size([4, 4])
y = x.view(16)
y.size()#torch.Size([16])
z = x.view(-1, 8) # the size -1 is inferred from other dimensions
z.size()#torch.Size([2, 8])
主な例: 3 × 4 次元のテンソル → t の場合、reshape (t, (4, 3)) および t = t.transpose (− 1, − 2) を実行します。得られた新しい次元は一貫していますが、その中で対応する位置の値が一致していません。再形成して表示するには、新しい次元に従って値を入力するだけです。転置は、行列\color{red}を転置するための鍵です。例: 3×4の場合次元テンソル→t, reshape(t, (4,3)) と t=t.transpose(-1,-2) では、得られた新しい次元は一致していますが、対応する位置の値は一致していません。再形成して表示するには、新しい次元に従って値を入力するだけです。transpose は転置行列です。主な例: 3の場合×4次元テンソル_ _ _→t 、結果( t 、_ _ _( 4 、3 ))とt=と。トランスポーズ( − 1 , _ _ _ _− 2 )では、取得された新しい寸法は一致していますが、対応する位置の値が一致していません。res hapeとview では、単に新しい寸法に従って値を入力し、トランザクションを実行します。s poseは行列を転置します。
7、トーチ.キャット、トーチ.スプリット
torch.cat(tensors, dim=0, *, out=None) → Tensor 指定さ
れた次元の seq テンソルの指定されたシーケンスを連結します。すべてのテンソルは同じ形状 (連結次元を除く) であるか、空である必要があります。
パラメータ:
tensor (テンソルのシーケンス) – 同じタイプのテンソルの任意の Python シーケンス。提供される空でないテンソルは、cat 次元を除き、同じ形状でなければなりません。
dim (int、オプション) – テンソルが連結される次元
dim=-1 は、最後の次元から最初の次元を意味します。
>>> x = torch.randn(2, 3)
>>> x
tensor([[ 0.6580, -1.0969, -0.4614],
[-0.1034, -0.5790, 0.1497]])
>>> torch.cat((x, x, x), 0)#shape是6×3
tensor([[ 0.6580, -1.0969, -0.4614],
[-0.1034, -0.5790, 0.1497],
[ 0.6580, -1.0969, -0.4614],
[-0.1034, -0.5790, 0.1497],
[ 0.6580, -1.0969, -0.4614],
[-0.1034, -0.5790, 0.1497]])
>>> torch.cat((x, x, x), 1)#shape是2×9
tensor([[ 0.6580, -1.0969, -0.4614, 0.6580, -1.0969, -0.4614, 0.6580,
-1.0969, -0.4614],
[-0.1034, -0.5790, 0.1497, -0.1034, -0.5790, 0.1497, -0.1034,
-0.5790, 0.1497]])
8、torch.clamp(input, min=None, max=None, *, out=None) → Tensor
入力内のすべての要素を範囲 [ min, max ] にクランプします。min_value と max_value をそれぞれ min と max とすると、次の値が返されます。
计算公式: y i = min ( max ( x i , min_value i ) , max_value i ) 计算公式:y_i = \min(\max(x_i, \text{min\_value}_i), \text{max\_value}_i) 計算式:y私は=最小(最大( x私は、min_value私は)、最大値私は) は
、最小値と最大値の範囲外の数値が最小値または最大値に制限され、範囲内の数値は変更されないことを意味します。
min が None の場合、下限はありません。または、max が None の場合、上限はありません。
>>> a = torch.randn(4)
>>> a
tensor([-1.7120, 0.1734, -0.0478, -0.0922])
>>> torch.clamp(a, min=-0.5, max=0.5)
tensor([-0.5000, 0.1734, -0.0478, -0.0922])
>>> min = torch.linspace(-1, 1, steps=4)
>>> torch.clamp(a, min=min)
tensor([-1.0000, 0.1734, 0.3333, 1.0000])
9、torch.linspace(start、end、steps、*、out=None、dtype=None、layout=torch.strided、device=None、requires_grad=False) → Tensor
値が開始点から終了点まで等間隔であるサイズ ステップの 1 次元テンソルを作成します。つまり、値は次のとおりです。
( start , start + end − 開始ステップ − 1 , … , start + ( ステップ − 2 ) ∗ end − 開始ステップ − 1 , end ) (\text{start}, \text{start} + \frac{\text{ end} - \text{start}}{\text{steps} - 1}, \ldots, \text{start} + (\text{steps} - 2) * \frac{\text{end} - \text{開始}}{\text{ステップ} - 1}、\text{終了})(開始、始める+ステップ− 1終了−開始、…、始める+(ステップ−2 )∗ステップ− 1終了−開始、終了)
>>> torch.linspace(3, 10, steps=5)
tensor([ 3.0000, 4.7500, 6.5000, 8.2500, 10.0000])
>>> torch.linspace(-10, 10, steps=5)
tensor([-10., -5., 0., 5., 10.])
>>> torch.linspace(start=-10, end=10, steps=5)
tensor([-10., -5., 0., 5., 10.])
>>> torch.linspace(start=-10, end=10, steps=1)
tensor([-10.])
10. 繰り返して展開する
* Tensor.repeat( sizes) → Tensor
このテンソルを指定された次元に沿って繰り返します。
>>> x = torch.tensor([1, 2, 3])
>>> x.repeat(4, 2)#把x看作1×3了,然后1乘4,3乘2
tensor([[ 1, 2, 3, 1, 2, 3],
[ 1, 2, 3, 1, 2, 3],
[ 1, 2, 3, 1, 2, 3],
[ 1, 2, 3, 1, 2, 3]])
>>> x.repeat(4, 2, 1).size()#把x看作1×1×3了,然后1乘4,1乘2,3乘1
torch.Size([4, 2, 3])
* Tensor.expand( sizes) → Tensor
シングルトン次元をより大きなサイズに拡張した自己テンソルの新しいビューを返します。
ディメンションのサイズとして -1 を渡すことは、そのディメンションのサイズを変更しないことを意味します。
Tensor はさらに多くの次元に拡張することもでき、新しい次元が先頭に追加されます。新しいディメンションの場合、サイズを -1 に設定することはできません。
>>> x = torch.tensor([[1], [2], [3]])
>>> x.size()
torch.Size([3, 1])
>>> x.expand(3, 4)
tensor([[ 1, 1, 1, 1],
[ 2, 2, 2, 2],
[ 3, 3, 3, 3]])
>>> x.expand(-1, 4) # -1 means not changing the size of that dimension
tensor([[ 1, 1, 1, 1],
[ 2, 2, 2, 2],
[ 3, 3, 3, 3]])
11、torch.sum(input, dim, keepdim=False, *, dtype=None)
指定された次元 dim の入力テンソルの各行の合計を返します。dim が次元のリストの場合、減らすそれらすべてにわたって。
パラメータ:
·input (Tensor) – 入力テンソル。
·dim (int または int のタプル、オプション) – 削減する次元。None の場合、すべての次元が縮小されます。
·keepdim (bool) – 出力テンソルが dim を保持しているかどうか。
キーワード引数:
·dtype (torch.dtype、オプション) – 返されるテンソルの目的のデータ型。指定した場合、操作が実行される前に、入力テンソルが dtype にキャストされます。これは、データ型のオーバーフローを防ぐのに役立ちます。デフォルト: なし。
>>>a=torch.arange(3*2*2).view(2,2,3)
>>>print(a)
tensor([[[ 0, 1, 2],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 9, 10, 11]]])
>>>b=torch.sum(a,(1,2))
>#把(0,0,0)、(0,0,1)、(0,0,2)、(0,1,0)、(0,1,1)、(0,1,2)的相加,以此类推
>>>print(b)
tensor([15, 51])
>>>c=torch.sum(a,0)#即把坐标为(0,0,0)和(1,0,0)的相加,以此类推
>>>print(c)
tensor([[ 6, 8, 10],
[12, 14, 16]])
12、トーチ・カムロッド
>>>a=torch.Tensor([[0.1,0.2],[0.3,0.4]])
>>>b=torch.cumprod(a,dim=0)#第0维所以就是坐标为(0,0)和(1,0)的进行相乘
tensor([[0.1000, 0.2000],
[0.0300, 0.0800]])
>>>b=torch.cumprod(a,dim=1)
tensor([[0.1000, 0.0200],
[0.3000, 0.1200]])
13. torch. flatten(n) は、n 番目以降の次元を平坦化します。
agg = tensor.sum().item()
print(agg, type(agg))
tensor.add_(5)
#In-place operations:Operations that store the result into the operand are called in-place.
They are denoted by a _ suffix.