【问题标题】:Multiply vectors with shape (2,) and (3, 1)将具有形状 (2,) 和 (3, 1) 的向量相乘
【发布时间】:2017-08-21 18:21:16
【问题描述】:

我有这个代码:

import numpy as np


def sigmoid(x):
    """
    Calculate sigmoid
    """
    return 1 / (1 + np.exp(-x))


x = np.array([0.5, 0.1, -0.2])
target = 0.6
learnrate = 0.5

weights_input_hidden = np.array([[0.5, -0.6],
                                 [0.1, -0.2],
                                 [0.1, 0.7]])

weights_hidden_output = np.array([0.1, -0.3])

## Forward pass
hidden_layer_input = np.dot(x, weights_input_hidden)
hidden_layer_output = sigmoid(hidden_layer_input)

output_layer_in = np.dot(hidden_layer_output, weights_hidden_output)
output = sigmoid(output_layer_in)

## Backwards pass
## TODO: Calculate error
error = target - output

# TODO: Calculate error gradient for output layer
del_err_output = error * output * (1 - output)
print("del_err_output", del_err_output)

# TODO: Calculate error gradient for hidden layer
del_err_hidden = np.dot(del_err_output, weights_hidden_output) * hidden_layer_output * (1 - hidden_layer_output)
print("del_err_hidden", del_err_hidden)
print("del_err_hidden.shape", del_err_hidden.shape)
print("x", x)
print("x.shape", x.shape)
print("x[:,None]")
print(x[:,None])
print("x[:,None].shape", x[:,None].shape)
print("del_err_hidden * x[:, None]")
print(del_err_hidden * x[:, None])

生成此输出:

del_err_output 0.0287306695435
del_err_hidden [ 0.00070802 -0.00204471]
del_err_hidden.shape (2,)
x [ 0.5  0.1 -0.2]
x.shape (3,)
x[:,None]
[[ 0.5]
 [ 0.1]
 [-0.2]]
x[:,None].shape (3, 1)
del_err_hidden * x[:, None]
[[  3.54011093e-04  -1.02235701e-03]
 [  7.08022187e-05  -2.04471402e-04]
 [ -1.41604437e-04   4.08942805e-04]]

我的问题是这个操作:del_err_hidden * x[:, None]

*是哪种操作?

其次,如果 del_err_hidden.shape 是 (2,) 而 x[:,None].shape 是 (3, 1),为什么我可以将它们相乘?

有人告诉我它与元素和广播有关,但我不明白这些术语。因为要进行元素乘法,两个矩阵必须具有相同的大小,而这里它们没有。

【问题讨论】:

  • Numpy 自动做del_err_hidden[None,:],所以乘法是(1,2) * (3,1) => (3,2)
  • @hpaulj 不是反​​过来吗? (3, 1) * (1, 2) => (3, 2) 在数学上是正确的
  • 广播元素智能乘法是可交换的。

标签: python numpy neural-network deep-learning backpropagation


【解决方案1】:

* 只是元素乘法。 广播是它起作用的原因。简而言之,当您将大小为 (3, 1) 的列(我们称其为 x)与大小为 (2, ) 的行(我们称其为 y)相乘时, numpy 创建一个新的 3X2 数组,其中第一列是y[0]*x,第二列是y[1]*x

关于何时以及如何发生的确切规则有些复杂。详情见documentation

【讨论】:

    【解决方案2】:

    好的,我引用文档中的broadcasting rules

    两个维度兼容
    1) 它们是相等的,或者
    2) 其中一个是 1

    您有两个形状数组 (2, )(3, 1)

    arr1 (1D) shape :      2
    arr2 (2D) shape :  3 x 1
    
    #                      ^
    #                      |    (c.f. rule-2)
    
    In [24]: err              # shape (2,)
    Out[24]: array([2, 4])
    
    In [26]: x                # shape (3, 1)
    Out[26]: 
    array([[3],
           [4],
           [5]])
    

    由于数组维度之一是 1,因此通过了规则。这些数组是可广播的并且可以成倍增加。下一部分是拉伸err 所在的数组(嗯仅在概念上)。

    In [27]: err          # shape (3, 2)
    Out[27]: 
    array([[2, 4],
           [2, 4],
           [2, 4]])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-27
      • 2020-12-06
      • 2021-07-27
      • 2021-10-28
      • 2021-07-28
      • 1970-01-01
      相关资源
      最近更新 更多