将向量与形状 (2,) 和 (3, 1) 相乘
Multiply vectors with shape (2,) and (3, 1)
我有这个代码:
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),为什么我可以将它们相乘?
有人告诉我它与elementwise和broadcasting有关,但我不明白那些术语。因为要进行逐元素乘法,两个矩阵必须具有相同的大小,而这里没有。
*
只是元素乘法。 广播 是它起作用的原因。简而言之,当您将大小为 (3, 1) 的列(我们称之为 x)与一行大小为 (2, )(我们称之为 y ), numpy 创建一个新的 3X2 数组,其中第一列是 y[0]*x
,第二列是 y[1]*x
.
关于何时以及如何发生的确切规则有些复杂。详情见documentation
好的,我引用文档中的 broadcasting rules:
Two dimensions are compatible when
1) they are equal, or
2) one of them is 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]])
我有这个代码:
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),为什么我可以将它们相乘?
有人告诉我它与elementwise和broadcasting有关,但我不明白那些术语。因为要进行逐元素乘法,两个矩阵必须具有相同的大小,而这里没有。
*
只是元素乘法。 广播 是它起作用的原因。简而言之,当您将大小为 (3, 1) 的列(我们称之为 x)与一行大小为 (2, )(我们称之为 y ), numpy 创建一个新的 3X2 数组,其中第一列是 y[0]*x
,第二列是 y[1]*x
.
关于何时以及如何发生的确切规则有些复杂。详情见documentation
好的,我引用文档中的 broadcasting rules:
Two dimensions are compatible when
1) they are equal, or
2) one of them is 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]])