我一直在学习人工神经网络,但我读过的书中有Python的例子。问题是我从未用Python编写过,这些代码行太难理解了:
sizes = [3,2,4]
self.weights = [np.random.randn(y, x)
for x, y in zip(sizes[:-1], sizes[1:])]
我读了一些关于它的事情,发现randn()
函数返回一个数组,其中y
个元素和x
维度填充了0到1之间的随机数。{{1}将两个数组连接成一个。 zip()
返回最后一个元素,sizes[:-1]
返回没有第一个元素的数组。
但是,尽管如此,我仍然无法向自己解释这会产生什么。
答案 0 :(得分:5)
sizes[:-1]
将返回子列表[3,2]
(即除最后一个元素之外的所有元素)。
sizes[1:]
将返回子列表[2,4]
(即除第一个之外的所有元素)。
zip([a,b], [c,d])
给出[(a,c), (b,d)]
。
因此,压缩上面的两个列表会为您提供[(3,2), (2,4)]
权重的构造是list comprehension。因此,此代码等同于
weights = []
for x,y in [(3,2), (2,4)]:
weights.append(np.random.randn(y, x))
所以最终结果与
相同[ np.random.randn(2,3),
np.random.randn(4,2) ]
答案 1 :(得分:2)
这里发生了很多事情。
让我们分解那个表达式:如你所说zip
将创建一个元组列表,其中包含sizes
的每个元素及其后继元素(除了最后一个元素)
理解列表[ ... for x, y in zip(..)]
的工作原理如下:元组在变量x
和y
中展开,并将这些元组传递到np.random.randn
以创建随机矩阵列表
这些矩阵的特点是第一个维度(行)长度由sizes
的每个元素指定,第二个维度(列)长度为以下元素。
有趣的是,矩阵的兼容维度在该序列中相互成倍增加,但我猜这不是目的。 weights
列表中每个矩阵的目的是指定完全连接的神经元层之间的权重。祝好运!似乎是一个有趣的项目!
因为您是初学者:您可以在代码中的任何位置添加import pdb; pdb.set_trace()
语句以获取断点。然后你可以复制并粘贴任何表达式的不同部分,看看会出现什么。
例如:
ipdb> print sizes
[3, 2, 4]
ipdb> print sizes[:-1]
[3, 2]
ipdb> print sizes[1:]
[2, 4]
ipdb> print zip(sizes[:-1], sizes[1:])
[(3, 2), (2, 4)]
ipdb> print [np.random.randn(y, x) for x, y in zip(sizes[:-1], sizes[1:])]
[array([[ 0.25933943, 0.59855688, 0.49055744],
[ 0.94602292, -0.8012292 , 0.56352986]]), array([[ 0.81328847, -0.53234407],
[-0.272656 , -1.24978881],
[-1.2306653 , 0.56038948],
[ 1.15837792, 1.19408038]])]
答案 2 :(得分:2)
让我们把它分成几块:
self.weights = [some junk]
将成为列表理解。这意味着,做some junk
的东西,你最终会得到一个元素列表。通常这些看起来像这样:
self.weights = [some_func(x) for x in a_list]
这相当于:
self.weights = []
for x in a_list:
self.weights.append(some_func(x))
zip(a, b)
将a
和b
的元素分段合并为元组对:
(a1, b1), (a2, b2), (a3, b3), ...
for x, y in zip(a, b):
这遍历了上面谈到的元组对
sizes[:-1]
这是为了获取列表sizes
的所有元素,但最后项(-1
)除外。
sizes[1:]
这是为了获取列表sizes
的所有元素,但第一个项除外。
所以,最后将这些拼凑在一起你得到:
self.weights = [np.random.randn(y, x) for x, y in zip(sizes[:-1], sizes[1:])]
这是一个列表理解,迭代第一个大小的元组对,从第2个项目到最后一个,第二个从第1个项目到倒数第二个,根据这两个参数创建一个随机数,然后附加到存储为的列表中self.weights
答案 3 :(得分:0)
此代码生成一个列表并将其分配给self.weights属性(这可能在一个类中?这可以解释自我)。第二行是列表理解。它生成一个列表,将函数randn应用于变量对(x,y)