仅仅重塑与重塑并转置的区别?

我在研究CS231的作业时发现了一个令人困惑的问题。在计算梯度时,我先重塑x然后再获取其转置,这样就能得到正确的结果。

x_r=x.reshape(x.shape[0],-1)dw= x_r.T.dot(dout)

enter image description here

然而,当我直接按照X.T的形状重塑时,得到的结果就不正确了。

dw = x.reshape(-1,x.shape[0]).dot(dout)

enter image description here

有人能解释以下问题吗?

使用np.reshape()获取元素的顺序是如何变化的?将形状为(N,d1,d2..dn)的数组重塑成N,D数组与将其重塑成(D,N)并获取其转置的数组有什么不同?


回答:

虽然你的两种方法都会得到相同形状的数组,但由于numpy读取/写入元素的方式,元素的顺序会有不同。默认情况下,reshape使用类似C语言的索引顺序,这意味着元素是以最后一个轴的索引变化最快的方式读取/写入的,而第一个轴的索引变化最慢(摘自文档)。

下面是一个实际例子来说明这一点。假设我们有以下数组x

x = np.asarray([[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10], [11, 12]]])print(x.shape) # (2, 3, 2)print(x)# output[[[ 1  2]  [ 3  4]  [ 5  6]] [[ 7  8]  [ 9 10]  [11 12]]]

现在让我们以以下两种方式重塑这个数组:

opt1 = x.reshape(x.shape[0], -1)opt2 = x.reshape(-1, x.shape[0])print(opt1.shape) # outptu: (2, 6)print(opt2.shape) # output: (6, 2)print(opt1)# output:[[ 1  2  3  4  5  6] [ 7  8  9 10 11 12]]print(opt2)# output:[[ 1  2] [ 3  4] [ 5  6] [ 7  8] [ 9 10] [11 12]]

reshape首先推断新数组的形状,然后以C语言索引顺序读取元素并返回一个视图。

opt1为例:由于原始数组x有12个元素,它推断新数组opt1必须具有(2, 6)的形状(因为2*6=12)。现在,reshape返回一个视图,其中:

opt1[0][0] == x[0][0][0] opt1[0][1] == x[0][0][1]opt1[0][2] == x[0][1][0]opt1[0][3] == x[0][1][1]opt1[0][4] == x[0][2][0]opt1[0][5] == x[0][2][1]opt1[1][0] == x[1][0][0]...opt1[1][5] == x[1][2][1]

如上所述,最后一个轴的索引变化最快,第一个轴的索引变化最慢。同样,opt2的输出将以相同的方式计算。

现在你可以验证,第一种方法的转置将导致相同形状但元素顺序不同的结果:

opt1 = opt1.Tprint(opt1.shape) # output: (6, 2)print(opt1)# output: [[ 1  7] [ 2  8] [ 3  9] [ 4 10] [ 5 11] [ 6 12]]

显然,由于元素顺序的不同,这两种方法不会得到相同的数组,尽管它们会有相同的形状。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

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