C# Python zip迭代器和Adagrad更新
我试图理解Andrej Karpathy作为指南给出的优秀代码: 我是python新手,还在学习 我正在尽我所能从链接中理解以下代码:C# Python zip迭代器和Adagrad更新,c#,python,C#,Python,我试图理解Andrej Karpathy作为指南给出的优秀代码: 我是python新手,还在学习 我正在尽我所能从链接中理解以下代码: # perform parameter update with Adagrad for param, dparam, mem in zip([Wxh, Whh, Why, bh, by], [dWxh, dWhh, dWhy, dbh, dby],
# perform parameter update with Adagrad
for param, dparam, mem in zip([Wxh, Whh, Why, bh, by],
[dWxh, dWhh, dWhy, dbh, dby],
[mWxh, mWhh, mWhy, mbh, mby]):
mem += dparam * dparam
param += -learning_rate * dparam / np.sqrt(mem + 1e-8) # adagrad update
我已经阅读了有关的文章,并做了一些简短的测试,试图了解这是如何工作的
到目前为止,我所知道的是,5次迭代,第一次迭代时param==Wxh,但在第二次迭代时没有
理想情况下,我正在尝试将此代码转换为C#,要做到这一点,我需要理解它
在引用时,当我们将每个数组的每个项相乘时,它会出现:
param = Wxh * dWxh * mWxh
但是变量param
dparam
和mem
在zip函数之外被修改
在这个for循环场景中,这些变量是如何工作的?Python仅将变量视为标签或名称标记。由于您已将它们压缩到一个
列表中
,所以它们在哪里并不重要,只要您按名称/标签正确地对它们进行寻址即可。请注意,这可能不适用于不可变类型,如int
或str
等。有关更多解释,请参阅此答案-。Python仅将变量视为标签或名称标记。由于您已将它们压缩到一个列表中
,所以它们在哪里并不重要,只要您按名称/标签正确地对它们进行寻址即可。请注意,这可能不适用于不可变类型,如int
或str
等。请参阅此答案以获取更多解释-。使用zip编写一个简单的for循环将帮助您学到很多东西
例如:
for a, b, c in zip([1,2,3],
[4,5,6],
[7,8,9]):
print a
print b
print c
print "/"
t = (2, 4)
x, y = t
此功能将打印:1 4 7/2 5 8/3 6 7
因此zip函数只是将这三个列表放在一起,然后使用三个变量param、dparam、mem来引用不同的列表
在每次迭代中,这三个变量引用了它们相应列表中的特定项,就像[1,2,3]中i的:
这样,您只需要为循环编写一个而不是三个,以更新每个参数的梯度:Wxh、Whh、Why、bh、by
在第一次迭代中,仅使用dWxh和mWxh按照adagrad规则更新Wxh。其次,使用dWhh和mWhh更新Whh,以此类推。使用zip编写一个简单的for循环将帮助您学到很多东西 例如:
for a, b, c in zip([1,2,3],
[4,5,6],
[7,8,9]):
print a
print b
print c
print "/"
t = (2, 4)
x, y = t
此功能将打印:1 4 7/2 5 8/3 6 7
因此zip函数只是将这三个列表放在一起,然后使用三个变量param、dparam、mem来引用不同的列表
在每次迭代中,这三个变量引用了它们相应列表中的特定项,就像[1,2,3]中i的:
这样,您只需要为循环编写一个而不是三个,以更新每个参数的梯度:Wxh、Whh、Why、bh、by
在第一次迭代中,仅使用dWxh和mWxh按照adagrad规则更新Wxh。其次,使用dWhh和mWhh更新Whh,依此类推。zip的作用是什么 引用官方文件: Zip返回元组列表,其中第i个元组包含第i个元组 来自每个参数序列或iterables的元素。返回 列表的长度被截断为最短参数的长度 顺序 这意味着
>>> zip(["A", "B"], ["C", "D"], ["E", "F"])
[('A', 'C', 'E'), ('B', 'D', 'F')]
现在,当你循环时,你实际上有一个元组列表。内容像
# These are strings here but in your case these are objects
[('Wxh', 'dWxh', 'mWxh'), ('Whh', 'dWhh', 'mWhh'), ('Why', 'dWhy', 'mWhy'),
('bh', 'dbh', 'mbh'),('by', 'dby', 'mby')]
到目前为止,我知道的是,5次迭代,第一次迭代时param==Wxh
但不是在那里
您是对的,现在让我们分析您的循环
for param, dparam, mem in m:
print(param, dparam, mem)
# Which prints
('Wxh', 'dWxh', 'mWxh')
('Whh', 'dWhh', 'mWhh')
('Why', 'dWhy', 'mWhy')
('bh', 'dbh', 'mbh')
('by', 'dby', 'mby')
这意味着,在每次迭代中,params
获取第0个索引元组值,dparam
获取第一个值,mem
获取第二个值
现在,当我在for循环的范围之外键入param
时,我得到
>>> param
'by'
这意味着params仍然通过对象保存对的引用
从正式文件:
for循环对目标中的变量进行赋值
列表循环启动时,不会删除目标列表中的[…]名称
已完成,但如果序列为空,则它们将不会被删除
完全由循环指定给
zip
做什么
引用官方文件:
Zip返回元组列表,其中第i个元组包含第i个元组
来自每个参数序列或iterables的元素。返回
列表的长度被截断为最短参数的长度
顺序
这意味着
>>> zip(["A", "B"], ["C", "D"], ["E", "F"])
[('A', 'C', 'E'), ('B', 'D', 'F')]
现在,当你循环时,你实际上有一个元组列表。内容像
# These are strings here but in your case these are objects
[('Wxh', 'dWxh', 'mWxh'), ('Whh', 'dWhh', 'mWhh'), ('Why', 'dWhy', 'mWhy'),
('bh', 'dbh', 'mbh'),('by', 'dby', 'mby')]
到目前为止,我知道的是,5次迭代,第一次迭代时param==Wxh
但不是在那里
您是对的,现在让我们分析您的循环
for param, dparam, mem in m:
print(param, dparam, mem)
# Which prints
('Wxh', 'dWxh', 'mWxh')
('Whh', 'dWhh', 'mWhh')
('Why', 'dWhy', 'mWhy')
('bh', 'dbh', 'mbh')
('by', 'dby', 'mby')
这意味着,在每次迭代中,params
获取第0个索引元组值,dparam
获取第一个值,mem
获取第二个值
现在,当我在for循环的范围之外键入param
时,我得到
>>> param
'by'
这意味着params仍然通过
对象保存对的引用
从正式文件:
for循环对目标中的变量进行赋值
列表循环启动时,不会删除目标列表中的[…]名称
已完成,但如果序列为空,则它们将不会被删除
完全由循环指定给
任何序列(或iterable)都可以使用简单的赋值操作解压成变量。唯一的要求是变量的数量和结构与序列相匹配。例如:
for a, b, c in zip([1,2,3],
[4,5,6],
[7,8,9]):
print a
print b
print c
print "/"
t = (2, 4)
x, y = t
在本例中,标准文档中的zip()是“zip(),生成一个迭代器,该迭代器聚合来自每个iterables的元素。返回一个元组迭代器,其中第i个元组包含来自每个参数序列或iterables的第i个元素。因此,对于您的情况
for param, dparam, mem in zip([Wxh, Whh, Why, bh, by],
[dWxh, dWhh, dWhy, dbh, dby],
[mWxh, mWhh, mWhy, mbh, mby]):
mem += dparam * dparam
param += -learning_rate * dparam / np.sqrt(mem + 1e-8)
lets say:
iterable1 = [Wxh, Whh, Why, bh, by]
iterable2 = [dWxh, dWhh, dWhy, dbh, dby]
iterable3 = [mWxh, mWhh, mWhy, mbh, mby]
here zip() returns [(Wxh, dWxh, mWxh), (Whh, dWhh, mWhh), (Why, dWhy, mWhy), (bh, dbh, mbh), (by, dby, mby)]
on 1st iteration:
param, dparam, mem = (Wxh, dWxh, mWxh)
so,
param = Wxh
dparam = dWxh
mem = mWxh
mem = mem + (dparam * dparam) = mWxh + (dWxh * dWxh)
param = param + (-learning_rate * dparam / np.sqrt(mem + 1e-8)) = Wxh + (-learning_rate * dWxh / np.sqrt(mWxh + (dWxh * dWxh) + 1e-8)
on 2nd iteration:
param, dparam, mem = (Whh, dWhh, mWhh)
so,
param = Whh
dparam = dWhh
mem = mWhh
an so on.
任何序列(或iterable)都可以通过简单的赋值操作解压成变量