matmul与dot的区别(广义最小残差法和共轭梯度法的区别和联系)

matmul与dot的区别(广义最小残差法和共轭梯度法的区别和联系)

扫码添加渲大师小管家,免费领取渲染插件、素材、模型、教程合集大礼包!

大家好,今天来介绍matmul与dot的区别的问题,以下是渲大师小编对此问题的归纳和整理,感兴趣的来一起看看吧!

广义最小残差法和共轭梯度法的区别

答:共轭梯度法是以函数的梯度构造共轭方向的一种算法,具有共轭方向的性质。共轭梯度法具有超线性收敛速度。梯度法与共轭梯度法的区别是:
1)最速下降法孝袭手(梯度禅岁法) :搜索方向为目标函数负梯度方向,计算效率优于坐标轮换法。开始几步搜索下降快,但愈接近极值点下降愈慢。对初始点的选择要求不高,适合与其它方法结合使用。
2)共轭梯度法:第一步搜索沿负梯度方向,然后沿负梯度的巧嫌共轭方向搜索。计算效率介于梯度法和牛顿法之间。对初始点没有特殊的要求,不需要计算二阶偏导数矩阵及其逆矩阵,计算量与梯度法相当。适用于各种规模的问题

探索性数据分析的残差是什么

正态性检验

用于检验数据是否符合正态性分布

# 生成正态分布的观测数据
norm_data = ss.norm.rvs(loc = 0,scale = 1,size = int(10e6)) # loc为均值,scale为标准差,size为生成数据个数,可以为元组
ss.normaltest(norm_data)
1
2
3
1
2
3
1.2 卡方检验

常用作检验两个样本数据含颤核之间是否有较强联系

ss.chi2_contingency([[15,95],[85,5]])
1
1
1.3 独立分布t检验

常用作比较均值是否有相异性,不要求两个样本之间数据量一致

ss.ttest_ind(ss.norm.rvs(size = 500),ss.norm.rvs(size = 1000))
1
1
1.4 方差检验

常用作检验多组样本数据之间的均值是否有差异

ss.f_oneway(ss.norm.rvs(size = 5000),ss.norm.rvs(size = 10000),ss.norm.rvs(size = 5000))
1
1
1.5 Q-Q图

横轴为:标准分布的分位数值(默认为正态分布)
纵轴为:已知分布的分位数的值
数据洞返集中在对角谈掘线上则说明越符合正态分布
from statsmodels.graphics.api import qqplot
import matplotlib.pyplot as plt
qqplot(ss.norm.rvs(size = 50))
plt.close()
# plt.show()
1
2
3
4
5
1
2
3
4
5
1.6 相关系数

pearson相关系数和具体数值有关
spearman相关系数和名次差有关,运用于相对比较的情况
s1 = pd.Series(np.random.randn(10))
s2 = pd.Series(np.random.randn(10))
s1.corr(s2,method = "spearman")
df = pd.DataFrame(np.array([s1,s2]).T)
df.corr()
1
2
3
4
5
1
2
3
4
5
2 单因素分析

2.1 线性回归

求解方法:最小二乘法
关键指标:
决定系数: [0,1],越接近于1,回归效果越好
残差不相关(DW检验):[0,4],DW = 2 回归效果好,即残差不相关,0负相关,4正相关
# 一元线性回归
from sklearn.linear_model import LinearRegression as LR
from sklearn.cross_validation import train_test_split
x = np.arange(50).astype(np.float).reshape(-1,1)
y = 3*x + 2+5*np.random.random((50,1))
x_train,x_test,y_train,y_test = train_test_split(x,y,train_size = 0.8)
lr = LR()
lr.fit(x_train,y_train) # 线性拟合
y_pre = lr.predict(x) # 拟合模型进行预测
plt.scatter(x_train,y_train,color = "b")
plt.scatter(x_test,y_test,color = "y")
plt.plot(x,y_pre,color = "r")
plt.close()
lr.coef_ # 斜率
lr.intercept_ #截距
lr.score(x_test,y_test) # 决定系数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2.2 PCA 奇异值分解

sklearn自带的PCA方法使用的是奇异值分解

from sklearn.decomposition import PCA
decom = PCA(n_components = 1)
data = np.random.random((50,2))
decom.fit(data)
decom.explained_variance_ratio_ # 降维后得到的信息量
decom.fit_transform(data) # 得到降维后的数据
1
2
3
4
5
6
1
2
3
4
5
6
2.3 主成分分析(PCA自定义实现)

def myPCA(data,n_components = 2):
from scipy import linalg # linear algbra 线性代数
data_cov = np.cov(data,rowvar = False)
data_mean = np.mean(data,axis = 0)
data_temp = data - data_mean
eig_value,eig_vector = linalg.eig(np.mat(data_cov)) # eigen为特征的、固有的意思,linalg.eig为计算特征值和特征向量的函数
eig_value_index = np.argsort(eig_value)[:-(n_components+1):-1]
eig_vector = eig_vector[:,eig_value_index]
data_decom = np.dot(data_temp,eig_vector) # np.dot和np.matmul都为矩阵乘法
return data_decom,eig_value
data = np.array([[2.5,0.5,2.2,1.9,3.1,2.3,2,1,1.5,1.1],[2.4,0.7,2.9,2.2,3,2.7,1.6,1.1,1.6,0.9]]).T
myPCA(data,n_components = 1)
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
3 复合分析

3.1 分组分析

分组分析只是一种辅助手段
钻取:分为向上钻取和向下钻取,向上钻取即为汇总分析
分割:一阶差分
拐点:二阶差分
不纯度:GiNi系数
3.1.1 离散数据分组

import seaborn as sns
sns.barplot(data = df,x = "a",y = "b",hue = "c")
1
2
1
2
3.1.2 连续数据分组

sns.barplot(list(range(len(df['a']))),df['a'].sort_values())
1
1
3.1.3 不纯度(GiNi系数)

针对目标标注的GiNi系数
选取GiNi系数接近于0的目标标注
# 定义概率平方和函数:
def getProbSS(s):
import pandas as pd
import numpy as np
if not isinstance(s,pd.core.series.Series):
s = pd.Series(s)
return sum((pd.groupby(s,by = s).count().values/float(len(s)))2)

# 定义GiNi系数求取函数
def getGiNi(s1,s2):
"""
其中s1为目标标注
"""
import pandas as pd
import numpy as np
dict_temp = {}
for i in range(len(s1)):
dict_temp[s1[i]] = dict_temp.get(s1[i],[]) + [s2[i]]
return 1 - sum([getProbSS(value)/float(len(value)) for value in dict_temp.values()])
s1 = ["x1","x1","x2","x2","x2","x2"]
s2 = ["y1","y1","y1","y2","y2","y2"]
getGiNi(s1,s2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
3.2 相关分析

相关性分析分为两种:
连续数据的相关性分析 - 相关性系数
离散数据的相关性分析 - 基于熵定义的相关性系数
# __________离散数据相关系数的计算
s1 = ["x1","x1","x2","x2","x2","x2"]
s2 = ["y1","y1","y1","y2","y2","y2"]

# 定义计算熵的函数
def getEntropy(s):
"""
熵是度量不确定性的指标
熵趋近于0,则不确定会很小。
"""
import pandas as pd
import numpy as np
if not isinstance(s,pd.core.series.Series):
s = pd.Series(s)
prob_dist = pd.groupby(s,by = s).count().values/float(len(s))
return -(prob_dist*np.log2(prob_dist)).sum()

# 自定义计算条件熵的函数
def getCondEntropy(s1,s2):
"""
在s1分布下分别对s2计算熵
"""
import pandas as pd
import numpy as np
if not isinstance(s1,pd.core.series.Series):
s1 = pd.Series(s1)
if not isinstance(s2,pd.core.series.Series):
s2 = pd.Series(s2)
dict_temp = {}
for i in np.arange(len(s1)):
dict_temp[s1[i]] = dict_temp.get(s1[i],[]) + [s2[i]]
return sum([getEntropy(value)*float(len(value))/float(len(s1)) for value in dict_temp.values()])

# 自定义互信息即熵增益函数
def getEntropyGain(s1,s2):
"""
计算由s1分布到s2的熵增益
"""
return getEntropy(s2) - getCondEntropy(s1,s2)

# 自定义熵增益率系数
def getEntropyGainRatio(s1,s2):
return getEntropyGain(s1,s2)/getEntropy(s2)

# 自定义熵相关度函数
def getDiscreteRelation(s1,s2):
"""
计算离散变量的相关系数
"""
return getEntropyGain(s1,s2)/(getEntropy(s1)*getEntropy(s2))0.5

getDiscreteRelation(s1,s2)

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
4 因子分析(成分分析)

from factor_analyzer import FactorAnalyzer
class CyrusFactorAnalysis():
def __init__(self,logger=None):
self.logger = logger
self.metric_tool = CyrusMetrics(logger=self.logger)
self.plot_tool = PlotTool(self.logger)

def select_factor_nums(self,data):
self.standard_tool = StandardTool(data)
std_data = self.standard_tool.transform_x(data)
self.factor_tool = FactorAnalyzer(n_factors=data.shape[1], rotation="promax")
var = self.factor_tool.get_factor_variance()
save_to_excel()

def run_factor_analysis(self,data,n_factor=2):
self.standard_tool = StandardTool(data)
std_data = self.standard_tool.transform_x(data)
self.factor_tool = FactorAnalyzer(n_factors=n_factor, rotation="promax")

process_data = self.factor_tool.fit_transform(std_data)
factor_data = self.factor_tool.loadings_
weights = self.factor_tool.weights_
var = self.factor_tool.get_factor_variance()

save_to_excel([(pd.DataFrame(factor_data),"载荷矩阵"),(pd.DataFrame(process_data),"归因后结果"),
(pd.DataFrame(weights),"归因系数"),(pd.DataFrame(var),"方差解释性")],
path="FactorAnalysisResult_{}".format(datetime.datetime.now().strftime("%Y-%m-%d")))

def transform(self,data):
std_data = self.standard_tool.transform_x(data)
factor_data = self.factor_tool.transform(std_data)
return factor_data

def save_model(self):
save_var(self.factor_tool,path="FactorAnalysisModel_{}".format(datetime.datetime.now().strftime("%Y-%m-%d")))
1

Numpy中的矩阵乘法

用燃猛 a * b 或者漏段悉 np.multiply(a,b)

用 np.dot(a,b) 、 np.matmul(a,b) 或 a.dot(b)

用 np.multiply(a,b)

用 a * b 、返乎 np.dot(a,b) 、 np.matmul(a,b) 或 a.dot(b)

《Attention Is All You Need》算法详解

该篇文章右谷歌大脑团队在17年提出,目的是解决对于NLP中使用RNN不能并行计算(详情参考 《【译】理解LSTM(通俗易懂版)》 ),从而导致算法效率低的问题。该篇文章中的模型就是近几年大家到处可以听到的Transformer模型。

由于该文章提出是解决NLP(Nature Language Processing)中的任务,例如文章实验是在翻译任务上做的。为了CV同学更好的理解,先简单介绍一下NLP任务的一个工作流程,来理解模型的输入和输出是什么。

首先拿羡没CV中的分类任务来说,训练前我们会有以下几个常见步骤:

所以对于分类任务来兄扒纳说,模型的输入为预处理过的图片,输出为图片的类别(一般为预测的向量,然后求argmax获得类别)。

在介绍NLP任务预处理流程前,先解释两个词,一个是tokenize,一个是embedding。

tokenize 是把文本切分成一个字符串序列,可以暂且简单的理解为对输入的文本进行分词操作。对英文来说分词操作输出一个一个的单词,对中文来说分词操作输出一个一个的字。(实际的分词操作多有种方式,会复杂一点,这里说的只是一种分词方式,姑且这么定,方便下面的理解。)

embedding 是可以简单理解为通过某种方式将词向量化,即输入一个词输出该词对应的一个向量。(embedding可以采用训练好的模型如GLOVE等进行处理,也可以直接利用深度学习模型直接学习一个embedding层,Transformer模型的embedding方式是第二种,即自己去学习的一个embedding层。)

在NLP中,拿翻译任务(英文翻译为中文)来说,训练模型前存在下面步骤:

所以对于翻译任务来说,翻译模型的输入为句子每个词的one-hot向量或者embedding后的向量(取决于embedding是否是翻译模型自己学习的,如果是则输入one-hot就可以了,如果不是那么输入就是通过别的模型获得的embedding向量)组成的序列,输出为当前预测词的类别(一般为词表大小维度的向量)

知道了Transformer模型的输入和输出后,下面来介绍一下Transformer模型的结构。

先来看看Transformer的整体结构,如下图所示:

可以看出它是一个典型的seq2seq结构(encoder-decoder结构),Encoder里面有N个重复的block结构,Decoder里面也有N个重复的block结构。

可以注意到这里的embedding操作是与翻译模型一起学习的。所以Transformer模型的输入为对句子分词后,每个词的one-hot向量组成的一个向量序列,输出为预测的每个词的预测向量。

为了更好的利用序列的位置信息,在对此厅embedding后的向量加上位置相关的编码。文章采用的是人工预设的方式计算出来的编码。计算方式如下

上式中,pos表示当前词在句子中的位置,例如输入的序列长L=5,那么pos取值分别为0-4,i表示维度的位置,偶数位置用 公式计算, 奇数位置用 公式计算。

文章也采用了加入模型训练来自动学习位置编码的方式,发现效果与人工预设方式差不多。

Encoder包含了N个重复的block结构,文章N=6。下面来拆解一个每个块的具体结构。

为了便于理解,介绍Multi-Head Attention结构前,先介绍一下基础的Scaled Dot-Product Attention结构,该结构是Transformer的核心结构。

Scaled Dot-Product Attention结构如下图所示

Scaled Dot-Product Attention模块用公式表示如下

上式中,可以假设Q\K的维度皆为 ,V的维度为 ,L为输入的句子长度, 为特征维度。

得到的维度为 ,该张量可以理解为计算Q与K中向量两两间的相似度或者说是模型应该着重关注(attention)的地方。这里还除了 ,文章解释是防止维度 太大得到的值就会太大,导致后续的导数会太小。(这里为什么一定要除 而不是 或者其它数值,文章没有给出解释。)

经过 获得attention权重后,与V相乘,既可以得到attention后的张量信息。最终的 输出维度为

这里还可以看到在Scaled Dot-Product Attention模块中还存在一个可选的Mask模块(Mask(opt.)),后续会介绍它的作用。

文章认为采用多头(Multi-Head)机制有利于模型的性能提高,所以文章引入了Multi-Head Attention结构。

Multi-Head Attention结构如下图所示

Multi-Head Attention结构用公式表示如下

上述参数矩阵为 , , , 。 为multi-head attention模块输入与输出张量的通道维度,h为head个数。文中h=8, ,

关于multi-head机制为什么可以提高模型性能

文章末尾给出了多头中其中两个头的attention可视化结果,如下所示

图中,线条越粗表示attention的权重越大,可以看出,两个头关注的地方不一样,绿色图说明该头更关注全局信息,红色图说明该头更关注局部信息。

从结构图不难看出网络加入了residual结构,所以add很好理解,就是输入张量与输出张量相加的操作。

Norm操作与CV常用的BN不太一样,这里采用NLP领域较常用的LN(Layer Norm)。(关于BN、LN、IN、GN的计算方式可以参考 《GN-Group Normalization》 )

还要多说一下的是,文章中共Add&Norm结构是先相加再进行Norm操作。

该结构很简单,由两个全连接(或者kernel size为1的卷积)和一个ReLU激活单元组成。

Feed Forward结构用公式表示如下

Decoder同样也包含了N个重复的block结构,文章N=6。下面来拆解一个每个块的具体结构。

从名字可以看出它比2.3.1部分介绍的Multi-Head Attention结构多一个masked,其实它的基本结构如下图所示

可以看出这就是Scaled Dot-Product Attention,只是这里mask是启用的状态。

这里先从维度角度考虑mask是怎么工作的,然后再解释为什么要加这个mask操作。

mask工作方式

为了方便解释,先不考虑多batch和多head情况。

可以假设Q\K的维度皆为 ,V的维度为 。

那么在进行mask操作前,经过MatMul和Scale后得到的张量维度为 。

现在有一个提前计算好的mask为 ,M是一个上三角为-inf,下三角为0的方阵。如下图所示(图中假设L=5)。

的结果如下图所示(图中假设L=5)

注意:下图中的非0区域的值不一定是一样的,这里为了方便显示画成了一样的颜色

现在Scaled Dot-Product Attention的公式如下所示

可以看出经过M后,softmax在-inf处输出结果为0,其它地方为非0,所以softmax的输出为 ,该结果为上三角为0的方阵。与 进行相乘得到结果为 。

从上述运算可以看出mask的目的是为了让V与attention权重计算attention操作时只考虑当前元素以前的所有元素,而忽略之后元素的影响。即V的维度为 ,那么第i个元素只考虑0-i元素来得出attention的结果。

mask操作的作用

在解释mask作用之前,我们先解释一个概念叫 teacher forcing

teacher forcing这个操作方式经常在训练序列任务时被用到,它的含义是在训练一个序列预测模型时,模型的输入是ground truth。

举例来说,对于"I Love China -> 我爱中国"这个翻译任务来说,测试阶段,Encoder会将输入英文编译为feature,Decoder解码时首先会收到一个BOS(Begin Of Sentence)标识,模型输出"我",然后将"我"作为decoder的输入,输出"爱",重复这个步骤直到输出EOS(End Of Sentence)标志。

但是为了能快速的训练一个效果好的网络,在训练时,不管decoder输出是什么,它的输入都是ground truth。例如,网络在收到BOS后,输出的是"你",那么下一步的网络输入依然还是使用gt中的"我"。这种训练方式称为teacher forcing。如下图所示

我们看下面两张图,第一张是没有mask操作时的示例图,第二张是有mask操作时的示例图。可以看到,按照teacher forcing的训练方式来训练Transformer,如果没有mask操作,模型在预测"我"这个词时,就会利用到"我爱中国"所有文字的信息,这不合理。所以需要加入mask,使得网络只能利用部分已知的信息来模拟推断阶段的流程。

decoder中的Multi-Head Attention内部结构与encoder是一模一样的,只是输入中的Q为2.4.1部分提到的Masked Multi-Head Attention的输出,输入中的K与V则都是encoder模块的输出。

下面用一张图来展示encoder和decoder之间的信息传递关系

decoder中Add&Norm和Feed Forward结构都与encoder一模一样了。

1. 从图中看出encoder和decoder中每个block的输入都是一个张量,但是输入给attention确实Q\K\V三个张量?

对于block来说,Q=K=V=输入张量

2. 推断阶段,解码可以并行吗?

不可以,上面说的并行是采用了teacher forcing+mask的操作,是的训练可以并行计算。但是推断时的解码过程同RNN,都是通过auto-regression方式获得结果的。(当然也有non auto-regression方面的研究,就是一次估计出最终结果)

参考:

torchmul() 、 torchmm() 及torchmatmul()的区别

1、torch.mul(a, b)是矩阵a和b对应位相乘,a和b的维度必须相等,比如a的维度是(1, 2),b的维度是(1, 2),返回的仍是(1, 2)的矩阵;
2、torch.mm(a, b)是矩阵a和b矩阵相乘,比如a的维度是(1, 2),b的维度是(2, 3),返回的就是(1, 3)的矩阵。
PS:更接地气来说区别就是点乘,和矩阵乘法的区别

torch.bmm()

torch.matmul()

torch.bmm()强制规定维度和大小相同

torch.matmul()没有强制规定维度和大小,可以用利用广播机制进行不同维度的相乘操作

当进行操作的两个tensor都是3D时,两者等同。

torch.bmm()

官网: https://pytorch.org/docs/stable/torch.html#torch.bmm

torch.bmm(input, mat2, out=None) → Tensor

torch.bmm()是tensor中的一个相乘操作,类似于矩阵中的A*B。

参数:

input,mat2:两个要进行相乘的tensor结构,两者必须是3D维度的,每个维度中的大小是相同的。

output:输出结果

并且相乘的两个矩阵,要满足一定的维度要求:input(p,m,n) * mat2(p,n,a) ->output(p,m,a)。这个要求,可以类比于矩阵相乘。前一个矩阵的列等于后面矩阵的行才可以相乘。

例子:

torch.matmul()也是一种类似于矩阵相乘操作的tensor联乘操作。但是它可以利用python 中的广播机制,处理一些维度不同的tensor结构进行相乘操作。这也是该函数与torch.bmm()区别所在。

参数:

input,other:两个要进行操作的tensor结构

output:结果

一些规则约定:

(1)若两个都是1D(向量)的,则返回两个向量的点积

(2)若两个都是2D(矩阵)的,则按照(矩阵相乘)规则返回庆茄2D

(3)若input维度1D,other维度2D,则先将1D的维度扩充到2D(1D的维数前面+1),然后得到结果后再将此维度去掉,得到的与input的维度相同。即使作扩充(广播)处理,input的维度也要和other维度做对应关系。

(4)若input是2D,other是1D,则返回两者的点积结果。(个人觉得这块也可以理解成给other添加了维度,然后再去掉此维度,只不过维度是(3, )而不是规则(3)中的( ,4)了,但是可能就是因为内部机制不同,所以官方说的是点积而不是维度的升高和下降)

(5)如果一个维度至少是1D,另外一个大于2D,则返回的是一个批庆漏矩阵乘法( a batched matrix multiply)。

(a)若input是1D,other是大于2D的,则类似于规则(3)。

(b)若other是1D,input是大于2D的,则类似于规则(4)。

(c)若input和other都是3D的,则誉差察与torch.bmm()函数功能一样。

(d)如果input中某一维度满足可以广播(扩充),那么也是可以进行相乘操作的。例如 input(j,1,n,m)* other (k,m,p) = output(j,k,n,p)。

这个例子中,可以理解为x中dim=1这个维度可以扩充(广播),y中可以添加一个维度,然后在进行批乘操作。

分享到 :
相关推荐

asp.net空间的作用有哪些(asp空间是什么)

asp.net空间的作用有:1。支持多语言。主要表现在编程语言种类多和单个语言功能强...

制作手游多少钱(制作手游多少钱一小时)

制作手机游戏多少钱?现在游戏行业依然是比较火爆的。而且随着智能手机的普及。有不少游戏...

xshell使用教程(xshell怎么用ssh连接Linux)

大家好,今天来介绍xshell使用教程(xshell怎么用vim)的问题,以下是渲大...

高防服务器租用价格受什么因素影响(高防服务器租用价格受什么因素影响呢)

高防服务器租用价格十分地受到人们的关注。很多人在租用服务器的时候。都选择高防服务器。...

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注