Как работает обновление цикла Python for в списке? - PullRequest
0 голосов
/ 14 февраля 2019

В руководстве Майкла Нильсена по нейронным сетям он имеет следующий код:

def update_mini_batch(self, mini_batch, eta):
    """The ``mini_batch`` is a list of tuples ``(x, y)``, and ``eta``
    is the learning rate."""
    nabla_b = [np.zeros(b.shape) for b in self.biases]
    nabla_w = [np.zeros(w.shape) for w in self.weights]
    for x, y in mini_batch:
        delta_nabla_b, delta_nabla_w = self.backprop(x, y)
        nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
        nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]
    self.weights = [w-(eta/len(mini_batch))*nw
                    for w, nw in zip(self.weights, nabla_w)]
    self.biases = [b-(eta/len(mini_batch))*nb
                   for b, nb in zip(self.biases, nabla_b)]

Я понимаю, что такое кортежи и списки, и я понимаю, что делает функция zip, но я не понимаю, как переменныеnb, dnb, nw и dnw обновляются в этих 2 строках кода:

        nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
        nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]

Кто-нибудь может помочь объяснить магию, происходящую в этих 2 строках?

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

Эти 2 строки являются типичными примерами Python списочных представлений .

По сути, для вашего первого списка:

nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]

это означает:

  1. Возьмите 1-ую пару из zip(nabla_b, delta_nabla_b);назовите их nb и dnb
  2. добавьте их (nb+dnb)
  3. сделайте результат первым элементом нового списка nabla_b
  4. Перейдите к первому шагудля 2-й пары и т. д. добавление результатов к nabla_b, пока все пары из zip(nabla_b, delta_nabla_b) не будут исчерпаны

В качестве простого примера приведено следующее понимание списка:

squares = [x**2 for x in range(10)]
print(squares)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

эквивалентно следующему циклу for:

squares = []

for x in range(10):
    squares.append(x**2)

print(squares)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

См. здесь для большего количества примеров и краткого введения.

0 голосов
/ 14 февраля 2019

Функция zip склеивает два списка вместе элемент за элементом, так что если вы дадите его:

a = [1, 2, 3, 4]
b = ["a", "b", "c", "d"]

zip(a, b) вернет:

[(1, "a"), (2, "b"), ...]

(каждыйэлемент, являющийся tuple)

Вы можете распаковать элементы list s, которые tuple s (или list s), используя запятую между каждой переменной в элементе tuple:

for elem_a, elem_b in zip(a, b):
    print(elem_a, elem_b)

Это вывело бы:

1 a
2 b
3 c
4 d

Итак, в вашем случае это добавление двух списков nabla_b и delta_nabla_b поэлементно, так что вы получите один список с каждым элементом, являющимсясумма соответствующих элементов в заархивированных списках.

Может показаться немного странным, потому что цикл for находится в одной строке, но это называется «списком».Простое понимание списка читается как английский.

...