Python奇怪的语法

时间:2015-10-12 18:55:14

标签: python arrays for-loop numpy neural-network

我一直在学习人工神经网络,但我读过的书中有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]返回没有第一个元素的数组。

但是,尽管如此,我仍然无法向自己解释这会产生什么。

4 个答案:

答案 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(..)]的工作原理如下:元组在变量xy中展开,并将这些元组传递到np.random.randn以创建随机矩阵列表

这些矩阵的特点是第一个维度(行)长度由sizes的每个元素指定,第二个维度(列)长度为以下元素。

有趣的是,矩阵的兼容维度在该序列中相互成倍增加,但我猜这不是目的。 weights列表中每个矩阵的目的是指定完全连接的神经元层之间的权重。祝好运!似乎是一个有趣的项目!

Post Scriptum

因为您是初学者:您可以在代码中的任何位置添加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)

ab的元素分段合并为元组对:

(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)