大家好,今天来介绍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中可以添加一个维度,然后在进行批乘操作。
本文地址:https://gpu.xuandashi.com/72115.html,转载请说明来源于:渲大师
声明:本站部分内容来自网络,如无特殊说明或标注,均为本站原创发布。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。分享目的仅供大家学习与参考,不代表本站立场!