Torch的運(yùn)算主要分成三個(gè)模塊:(1)Tensor的成員函數(shù);(2)torch全局封裝函數(shù);(3)torch.nn.functional中封裝的函數(shù)(與神經(jīng)網(wǎng)絡(luò)有關(guān)的運(yùn)算)。其中很大一部分運(yùn)算都是在Tensor中實(shí)現(xiàn)的,本主題主要梳理Tensor中的一些運(yùn)算。
??1. 基本四則運(yùn)算;
??2. 三角函數(shù)運(yùn)算;
??3. 指數(shù)與對(duì)數(shù)運(yùn)算;
??4. 統(tǒng)計(jì)運(yùn)算;
??5. 隨機(jī)運(yùn)算;
??6. 線性代數(shù)運(yùn)算;
數(shù)學(xué)基本運(yùn)算與運(yùn)算符
-
數(shù)學(xué)運(yùn)算的常規(guī)分類是:
- 基本運(yùn)算:
- 算術(shù)運(yùn)算
- 比較運(yùn)算
- 邏輯運(yùn)算
- 位運(yùn)算
- 符合運(yùn)算
- 其他運(yùn)算
- 指數(shù)與對(duì)數(shù)運(yùn)算
- 三角函數(shù)運(yùn)算
- 雙曲函數(shù)運(yùn)算
- 角度與弧度運(yùn)算
- 基本運(yùn)算:
-
在一般應(yīng)用中,我們更加關(guān)注的是向量運(yùn)算的定義:
- 按向量的分量運(yùn)算;
- 非按向量的分量運(yùn)算;
運(yùn)算符與基本運(yùn)算
四則運(yùn)算
加減運(yùn)算
__add__(self, value, /)__sub__(self, value, /)__neg__(self, /)
import torch
t1 = torch.Tensor(
[
[1, 2, 3],
[3, 4, 5]
]
)
t2 = torch.Tensor(
[
[9, 8, 7],
[6, 5, 4]
]
)
print(t1 + t2)
print(t1 - t2)
print(- t2)
# print(+t2) # 這個(gè)運(yùn)算符是沒有第
乘除運(yùn)算
-
__matmul__(self, value, /)- 矩陣乘法:內(nèi)積:點(diǎn)擊
@
- 矩陣乘法:內(nèi)積:點(diǎn)擊
-
__mul__(self, value, /)- 按位乘法:
*
- 按位乘法:
-
__truediv__(self, value, /)- 浮點(diǎn)除
-
__floordiv__(self, other)- 整除
-
__mod__(self, value, /)- 求余
-
__div__(self, value, /)- 早期的除法python2.0支持的重載運(yùn)算符
- 注意:
- 上面的運(yùn)算除內(nèi)積外,在向量中還有一種運(yùn)算是數(shù)乘。
import torch
t1 = torch.Tensor(
[
[1, 2, 3],
[3, 4, 5]
]
)
t2 = torch.Tensor(
[
[9, 8, 7],
[6, 5, 4]
]
)
print(t1 * t2)
print(t1 / t2)
print(t1 % t2)
print(t1 // t2) # 整除
print(t1 @ t2.t()) # 內(nèi)積
# 數(shù)乘的例子
import torch
t1 = torch.Tensor(
[
[1, 2, 3],
[3, 4, 5]
]
)
print(t1 * 2)
print(t1 / 2)
print(t1 % 2)
print(t1 // 3) # 整除
# 內(nèi)積內(nèi)有數(shù)乘
- 算術(shù)運(yùn)算存在左乘與右乘
- 上面運(yùn)算左右都行,因?yàn)椋?
__radd__(self, value, /)__rsub__(self, value, /)__rmul__(self, value, /)__rtruediv__(self, value, /)__rfloordiv__(self, value, /)__rmod__(self, value, /)-
__rdivmod__(self, value, /): 這個(gè)運(yùn)算符是:divmod返回商與余數(shù)
- 上面運(yùn)算左右都行,因?yàn)椋?
冪運(yùn)算
__rpow__(self, other)__pow__(self, other)
import torch
t1 = torch.Tensor(
[
[1, 2, 3],
[3, 4, 5]
]
)
t2 = torch.Tensor(
[
[9, 8, 7],
[6, 5, 4]
]
)
print(t2 ** t1) # 按位叉乘
print(t1 ** 2) # 數(shù)乘
絕對(duì)值運(yùn)算
__abs__(self, /)
import torch
t1 = torch.Tensor(
[
[-1, 2, -3],
[3, -4, 5]
]
)
print(t1.abs())
# print(| t1 |) 絕對(duì)值沒有| | 這個(gè)符號(hào)
四則運(yùn)算的四個(gè)版本
- 版本一:
- 運(yùn)算符: +
- 版本二:
- 成員函數(shù): add
- 版本三:
- 替換修改函數(shù) :add_
- 版本四:
- 全局函數(shù):torch.add
- 注意:
- 某些運(yùn)算符的成員函數(shù)或者全局函數(shù)沒有實(shí)現(xiàn),比如truediv沒有,代替的是div。
- 具體支持哪個(gè)版本在查看運(yùn)算符的時(shí)候,文檔會(huì)有說明。
- 下面與運(yùn)算符有關(guān)的依次類推。
import torch
t1 = torch.Tensor(
[
[1, 2, 3],
[3, 4, 5]
]
)
t2 = torch.Tensor(
[
[9, 8, 7],
[6, 5, 4]
]
)
print(t1 + t2)
print(t1.add(t2))
print(t1.add_(t2))
print(torch.add(t1, t2))
比較運(yùn)算
__lt____le____gt____ge____eq____ne__
- 提示:
運(yùn)算符版
成員函數(shù)的兩個(gè)版本:lt與lt_
全局函數(shù)版本:torch.lt
-
記得向量運(yùn)算:
- 向量與向量
- 向量與標(biāo)量
import torch
t1 = torch.Tensor(
[
[1, 2, 3],
[3, 4, 5]
]
)
t2 = torch.Tensor(
[
[9, 8, 7],
[6, 5, 4]
]
)
print(t1 > t2)
print(t1.gt(t2))
print(torch.gt(t1, t2))
print(t1.gt_(t2)) # 保留了原來浮點(diǎn)數(shù)的風(fēng)格
# 向量 與 標(biāo)量
import torch
t1 = torch.Tensor(
[
[1, 2, 3],
[3, 4, 5]
]
)
t2 = torch.Tensor(
[
[9, 8, 7],
[6, 5, 4]
]
)
print(t1 > 2)
print(t1.gt(2))
print(torch.gt(t1, 2)) # 第一個(gè)必須是Tensor
print(t1.gt_(2)) # 保留了原來浮點(diǎn)數(shù)的風(fēng)格
邏輯運(yùn)算
- Tensor沒有重載and,or,xor, not等四個(gè)邏輯運(yùn)算,邏輯運(yùn)算還是采用的是Python的標(biāo)量運(yùn)算
位運(yùn)算
__and__(self, value, /)__or__(self, value, /)__xor__(self, value, /)__invert__(self, /)__lshift__(self, value, /)__rshift__(self, value, /)
# 向量 與 標(biāo)量
import torch
t1 = torch.LongTensor(
[
[1, 2, 3],
[3, 4, 5]
]
)
print(t1 & 1) # and
print(t1 | 1) # or
print(t1 ^ 1) # xor
print(t1 >> 1) # rshift
print(t1 << 1) # lshift
print(~t1) # invert
復(fù)合運(yùn)算
- 所謂符合運(yùn)算就是 += 這類運(yùn)算,類似于成員函數(shù)帶_下劃線后綴。
-
加減
__iadd__(...)__isub__(...)
-
乘除
__itruediv__ = __idiv__(...)__imul__(...)-
__idiv__(...)# 兼容python2.0
-
求冪
__ipow__(self, other)
-
位算術(shù)
__iand__(...)__ior__(...)__ixor__(...)
-
位移
__ilshift__(...)__irshift__(...)
- 注意:
- 求余是沒有賦值復(fù)合的。
# 注意:向量 與 向量 -- 向量 與標(biāo)量
import torch
t1 = torch.Tensor(
[
[1, 2, 3],
[3, 4, 5]
]
)
t2 = torch.Tensor(
[
[9, 8, 7],
[6, 5, 4]
]
)
t1 += t2
print(t1)
t1 -= t2
print(t1)
t1 *= t2
print(t1)
t1 //= t2
print(t1)
t1 /= t2
print(t1)
# t1 **= t2 # 文檔提供,但沒有實(shí)現(xiàn)
# t1 **=2
t1 /= 2
print(t1)
其他運(yùn)算
- 四舍五入:
- round
- max
- min
- all
- any
- mode:返回商與余數(shù)
- sqrt
- rsqrt : 平方根倒數(shù)
- sign
指數(shù)與對(duì)數(shù)函數(shù)
- 在Python內(nèi)置提供了指數(shù)函數(shù),這里的指數(shù)函數(shù)是指自然指數(shù)。
exp函數(shù)
-
exp(input, out=None) -> Tensor: -
expm1(input, out=None) -> Tensor: -
exponential_(lambd=1, *, generator=None) -> Tensor:
%matplotlib inline
import matplotlib.pyplot as plt
import torch
x = torch.linspace(-1, 1, 100)
y_1 = x.exp()
y_2 = x.expm1()
x_ = x.clone()
y_3 = x_.exponential_(lambd=1) # λ=1 該函數(shù)與exp函數(shù)一樣,但是這是一個(gè)隨機(jī)分布函數(shù),返回的滿足隨機(jī)取樣
plt.figure("指數(shù)函數(shù)", figsize=(10, 10))
ax1 = plt.subplot(221)
ax1.plot(x, y_1, color=(1,0,0,1))
ax2 = plt.subplot(222)
ax2.plot(x, y_2, color=(1,1,0,1))
ax3 = plt.subplot(223)
ax3.plot(x, y_3, color=(1,0,1,1))
plt.show()
log函數(shù)
-
log(input, out=None) -> Tensor: -
log10(input, out=None) -> Tensor: -
log2(input, out=None) -> Tensor: -
log1p(input, out=None) -> Tensor: -
log_normal_(mean=1, std=2, *, generator=None)::隨機(jī)采樣
%matplotlib inline
import matplotlib.pyplot as plt
import torch
x = torch.linspace(-10, 10, 100)
y_1 = x.log()
y_2 = x.log2()
y_3 = x.log10()
y_4 = x.log1p()
x_ = x.clone()
y_5 = x_.log_normal_()
plt.figure("指數(shù)函數(shù)", figsize=(15, 10))
ax1 = plt.subplot(231)
ax1.plot(x, y_1, color=(1, 0, 0, 1))
ax2 = plt.subplot(232)
ax2.plot(x, y_2, color=(0, 1, 0, 1))
ax3 = plt.subplot(233)
ax3.plot(x, y_3, color=(0, 0, 1, 1))
ax4 = plt.subplot(234)
ax4.plot(x, y_4, color=(0, 1, 1, 1))
ax5 = plt.subplot(235)
ax5.plot(x, y_5, color=(1, 0, 1, 1))
plt.show()
三角函數(shù)運(yùn)算
-
sin() -> Tensor與sin_() -> Tensor -
cos() -> Tensor與cos_() -> Tensor -
tan() -> Tensor與tan_() -> Tensor
-
asin() -> Tensor與asin_() -> Tensor -
acos() -> Tensor與acos_() -> Tensor -
atan() -> Tensor與atan_() -> Tensor -
atan2() -> Tensor與atan2_() -> Tensor
%matplotlib inline
import matplotlib.pyplot as plt
import torch
import math
x = torch.linspace(-2*math.pi, 2*math.pi, 100)
y_1 = x.sin()
y_2 = x.cos()
y_3 = x.tan()
plt.figure("指數(shù)函數(shù)", figsize=(15, 5))
ax1 = plt.subplot(131)
ax1.plot(x, y_1, color=(1, 0, 0, 1))
ax2 = plt.subplot(132)
ax2.plot(x, y_2, color=(0, 1, 0, 1))
ax3 = plt.subplot(133)
ax3.plot(x, y_3, color=(0, 0, 1, 1))
plt.show()
雙曲函數(shù)運(yùn)算
- 雙曲函數(shù)表達(dá)式
- 雙曲函數(shù)表達(dá)式
雙曲正弦
sinh_() -> Tensorsinh() -> Tensor
%matplotlib inline
import matplotlib.pyplot as plt
import torch
import math
x = torch.linspace(-10, 10, 100)
y = x.sinh()
plt.plot(x, y, color=(1, 0, 0, 1))
plt.show()
雙曲余弦
cosh_() -> Tensorcosh() -> Tensor
%matplotlib inline
import matplotlib.pyplot as plt
import torch
import math
x = torch.linspace(-10, 10, 100)
y = x.cosh()
plt.plot(x, y, color=(1, 0, 0, 1))
plt.show()
雙曲正切
tanh_() -> Tensortanh() -> Tensor
%matplotlib inline
import matplotlib.pyplot as plt
import torch
import math
x = torch.linspace(-10, 10, 100)
y = x.tanh()
plt.plot(x, y, color=(1, 0, 0, 1))
plt.show()
統(tǒng)計(jì)運(yùn)算
求和函數(shù)與求階乘
cumsum(dim, dtype=None) -> Tensorcumprod(dim, dtype=None) -> Tensorsum(dim=None, keepdim=False, dtype=None) -> Tensorsum_to_size(*size) -> Tensorprod(dim=None, keepdim=False, dtype=None) -> Tensor
import torch
t = torch.Tensor(
[
[1, 2, 3, 4],
[3, 4, 5, 6]
]
)
print(t.cumsum(dim=0)) # 按照行累加
print(t.sum(dim=(), keepdim=True))
print(t.sum(dim=(1), keepdim=True))
print(t.sum(dim=(0), keepdim=True))
print(t.sum(dim=(1, 0), keepdim=True))
print('---------')
print(t.sum_to_size(2,1)) # 行不動(dòng),列按照求和合并為1
print(t.sum_to_size(1,4)) # 列不動(dòng),行按照求和合并為1
print(t.sum_to_size(1,1)) # 行列累加
均值函數(shù)
mean(dim=None, keepdim=False) -> Tensor or (Tensor, Tensor)
import torch
t = torch.Tensor(
[
[1, 2, 3, 4],
[3, 4, 5, 6]
]
)
print(t.mean())
print(t.mean(1))
print(t.mean(dim=(1), keepdim=True))
print(t.mean(dim=(0), keepdim=False))
方差與標(biāo)準(zhǔn)差
-
std(dim=None, unbiased=True, keepdim=False) -> Tensor- unbiased:無偏與有偏方差
- 標(biāo)準(zhǔn)差與方差的區(qū)別是多了一個(gè)平方根運(yùn)算
var(dim=None, unbiased=True, keepdim=False) -> Tensor
import torch
t = torch.Tensor(
[
[1, 2, 3, 4],
[3, 4, 5, 6]
]
)
print(t.std())
print(t.var())
print(t.std(unbiased=False))
print(t.var(unbiased=False))
誤差函數(shù)
- 誤差相關(guān)函數(shù):
- Y = erf(X) Error function
- Y = erfc(X) Complementary error function(補(bǔ)誤差函數(shù))
- Y = erfcx(X) Scaled complementary error function
- X = erfinv(Y) Inverse error function(誤差函數(shù)的反函數(shù))
- X = erfcinv(Y) Inverse complementary error function(補(bǔ)誤差函數(shù)的反函數(shù))
- 函數(shù)公式:
-
- 當(dāng)x很大的時(shí)候:
- 當(dāng)x很大的時(shí)候:
erf() -> Tensorerfc() -> Tensorerfinv() -> Tensor
%matplotlib inline
import matplotlib.pyplot as plt
import torch
import math
x = torch.linspace(-10, 10, 100)
y = x.erf()
plt.plot(x, y, color=(1, 0, 0, 1))
plt.plot(x, x.erfc(), color=(0, 0, 1, 1))
plt.show()
直方計(jì)數(shù)
-
histc(bins=100, min=0, max=0) -> Tensor- bins:直方統(tǒng)計(jì)的箱子數(shù)
%matplotlib inline
import matplotlib.pyplot as plt
import torch
import math
t = torch.randint(low=0, high=10, size=(100,), dtype=torch.float)
print(t)
h = t.histc(bins=5) # 直方統(tǒng)計(jì),分成多個(gè)段,每個(gè)段的數(shù)量
print(h)
plt.hist(t, bins=5, rwidth=0.5, color='red')
plt.show()
中值
median(dim=None, keepdim=False) -> (Tensor, LongTensor)
import torch
t = torch.Tensor(
[
[1, 2, 3, 4],
[3, 4, 5, 6]
]
)
print(t.median())
最大值,最小值
max(dim=None, keepdim=False) -> Tensor or (Tensor, Tensor)min(dim=None, keepdim=False) -> Tensor or (Tensor, Tensor)argmax(dim=None, keepdim=False) -> LongTensorargmin(dim=None, keepdim=False) -> LongTensor
import torch
t = torch.Tensor(
[
[1, 2, 3, 4],
[3, 4, 5, 6]
]
)
print(t.max())
print(t.min())
print(t.argmax())
print(t.argmax(dim=0)) # 按照行取最大值
線性代數(shù)運(yùn)算
轉(zhuǎn)置運(yùn)算
-
2D維轉(zhuǎn)置
t() -> Tensort_() -> Tensor
-
多維維數(shù)交換
transpose(dim0, dim1) -> Tensortranspose_(dim0, dim1) -> Tensor
import torch
t = torch.Tensor(
[
[1, 2, 3, 4],
[3, 4, 5, 6]
]
)
print(t.t())
print(t.transpose(1, 0))
逆矩陣運(yùn)算
-
inverse() -> Tensor- 必須是方陣。
import torch
t = torch.Tensor(
[
[1, 2, 3],
[3, 4, 5],
[5, 6, 7]
]
)
print(t.inverse())
行列式計(jì)算
det() -> Tensor
import torch
t = torch.Tensor(
[
[1, 2],
[3, 4]
]
)
print(t.det())
特征分解計(jì)算
eig(eigenvectors=False) -> (Tensor, Tensor)
import torch
t = torch.Tensor(
[
[1, 2],
[3, 4]
]
)
print(t.eig(eigenvectors=True))
奇異值分解計(jì)算
svd(some=True, compute_uv=True) -> (Tensor, Tensor, Tensor)
import torch
t = torch.Tensor(
[
[1, 2, 3, 4],
[3, 4, 5, 6]
]
)
print(t.svd())
print(t.svd(some=False))
print(t.qr(some=False))
QR分解
qr(some=True) -> (Tensor, Tensor)
import torch
t = torch.Tensor(
[
[1, 2, 3, 4],
[3, 4, 5, 6]
]
)
print(t.qr(some=False))
內(nèi)積與叉集
-
dot(tensor2) -> Tensor- 點(diǎn)積(只對(duì)向量)
-
cross(other, dim=-1) -> Tensor- 叉乘:就是兩個(gè)向量的正交向量(必須是3維的)。
-
matmul(tensor2) -> Tensor- 矩陣內(nèi)積
-
mul(value) -> Tensor- 按照元素乘
import torch
t1 = torch.Tensor(
[
[1, 2, 3],
[3, 4, 5]
]
)
t2 = torch.Tensor(
[
[1, 2, 3],
[3, 4, 5]
]
)
print(t1.cross(t2, dim=1))
print(t1[0].dot(t2[0]))
print(t1.matmul(t2.T))
print(t1.mul(t2))
方程求解
-
solve(A) -> Tensor, Tensor- 表示代數(shù)方程的解:
- B表示張量本身
- A表示代數(shù)方程的系數(shù);
- 表示代數(shù)方程的解:
import torch
B = torch.Tensor(
[
[1],
[1],
[1]
]
)
A = torch.Tensor(
[
[1, 0, 0],
[0, 2, 0],
[0, 0, 3]
]
)
print(B.solve(A))
# AX=B
神經(jīng)網(wǎng)絡(luò)中的激活函數(shù)運(yùn)算
- 在Torch中,還有專門的激活函數(shù)實(shí)現(xiàn)模塊,這里只是介紹Tensor類及其相關(guān)的簡(jiǎn)單部分。
-
prelu()- Parametric Rectified Linear Unit:帶參數(shù)的RELU
- 小于0的部分添加了一個(gè)參數(shù)(斜率)
relu(...)sigmoid() -> Tensorsign() -> Tensor-
softmax(...)- 概率化:自然指數(shù)標(biāo)準(zhǔn)化
tanh() -> Tensor
%matplotlib inline
import matplotlib.pyplot as plt
import torch
import math
x = torch.linspace(-10, 10, 100)
y = x.prelu(weight=torch.tensor(0.1))
plt.plot(x, y, color=(1, 0, 0, 1))
plt.show()
%matplotlib inline
import matplotlib.pyplot as plt
import torch
import math
x = torch.linspace(-10, 10, 100)
y = x.softmax(dim=0)
plt.plot(x, y, color=(1, 0, 0, 1))
plt.show()
