Python 养老金阶段

Python strange syntaxis

我一直在学习 ANN,但我正在阅读的书在 Python 中有示例。问题是我从来没有写过Python,这几行代码对我来说太难理解了:

sizes = [3,2,4]
self.weights = [np.random.randn(y, x) 
                    for x, y in zip(sizes[:-1], sizes[1:])]

我读了一些关于它的东西,发现 randn() 函数 return 是一个包含 y 元素和 x 维度的数组,其中填充了介于 0 之间的随机数和 1. zip() 将两个数组连接成一个。 sizes[:-1] return 是最后一个元素,sizes[1:] return 是没有第一个元素的数组。

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

sizes[:-1] 将 return 子列表 [3,2](即除最后一个之外的所有元素)。

sizes[1:] 将 return 子列表 [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) ]

此代码生成一个列表并将其分配给 self.weights 属性(这可能在 class 内部?这将解释 self)。第二行是列表理解。它生成一个列表,将函数 randn 应用于变量对 (x, y)

这里发生了很多事情。

让我们分解该表达式:如您所说,zip 将创建一个元组列表,其中包含 sizes 的每个元素及其后继元素(最后一个元素除外)

理解列表 [ ... for x, y in zip(..)] 的工作方式如下:元组在变量 xy 中展开,然后传递给 np.random.randn 以创建一个列表随机矩阵。

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

有趣的是,矩阵具有兼容的维度,可以按该顺序相互相乘,但我想这不是目的。 weights 列表中每个矩阵的目的是指定完全连接的神经元层之间的权重。祝你好运!看起来是个有趣的项目!

Post 脚本

由于您是初学者:您可以在代码的任意位置添加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]])]

让我们把它分成几块:


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 的所有元素,除了 last 项 (-1)。

sizes[1:]

这表示获取列表 sizes 的所有元素,除了 第一个 项。


所以,最后将这些拼凑在一起你会得到:

self.weights = [np.random.randn(y, x) for x, y in zip(sizes[:-1], sizes[1:])] 

这是一个列表推导式,从第一项到最后一项和第二项从第一项到倒数第二项迭代第一个大小的元组对,根据这两个参数创建一个随机数,然后附加到一个列表存储为 self.weights