一、错误解决合集
1.
====> combined_seq.named_children()
2.
isinstance 2th parameter : must be a type or tuple of types ====> 改为tuple,不要用列表。改为 LLLayer = (nn.Conv2d,nn.Linear)3.
File “test.py”, line 90, in calculate_fin_fout
print(“hi”, seq[k].weight.shape[0], layers_fin_fout[“fout”][module])
KeyError: ScaledNeuron(
(neuron): IFNode(
v_threshold=1.0, v_reset=None, detach_reset=False
(surrogate_function): Sigmoid(alpha=1.0, spiking=True)
)
)
KeyError:
试图在字典中查找不存在的键。
试图通过属性访问或键索引获取对象的属性或字典中的键,但对象或字典中不存在这样的键或属性。
可能在使用类似字典的数据结构时,由于使用了无效的键或索引导致查找失败。
这里是键不存在的问题!首先要搞清楚什么是键?layers_fin_fout[“fout”][module]为键。注意:键需要初始化。键在使用之前一定要初始化,一层一层的初始化:`layers_fin_fout["fout"] = {} layers_fin_fout["fout"][module] = 0
二、
1、什么是拆包(解包)和封包:
拆包就是将列表(list)、元组(tuple)、字典(dict)三种类型的元素,全部提炼出来的过程;或者是使用变量去接收函数返回值的过程
封包是将多个值赋值给一个变量时,python会自动将这些值封装成元组,这个特性称之为封包;或者函数返回多个值时,也会进行封包
2、拆包的注意事项:
拆包时,接收返回数据的变量一定要与列表(list)、元组(tuple)、字典(dict)中的元素个数相同,否则会导致程序异常
三、数据结构:迭代器和集合的配合
这里的集合指:list,dict,tuple,set
基础
Python 中的集合类和迭代器是两个不同的概念,它们并没有继承关系。Python 中的集合类并不是继承自迭代器接口,而是通过实现特定的协议和方法来支持迭代器行为。在 Python 中,实现了迭代器接口的对象必须具有__iter__()
和__next__()
方法。反过来说,在 Python 中,迭代器是一种用于遍历可迭代对象的工具,它提供了 __iter__()
和 __next__()
方法。当一个对象实现了这两个方法时,它就是一个迭代器,可以通过iter()
函数获得。 也就是说对象可以支持迭代器行为。
__iter__()
方法返回迭代器对象自身,而 __next__()
方法用于获取迭代器的下一个元素。集合类可以实现这两个方法来支持迭代器行为,使得它们可以被iter()
函数返回对应的迭代器,并支持使用 next()
方法来遍历元素。
a.Iterator迭代器
迭代器(Iterator)并不像列表(List)那样可以直接输出(打印)所有元素。迭代器是一种按需生成元素的对象,每次只生成一个元素。要从迭代器中获取元素,必须使用for循环或next()函数逐个获取。
my_iterator = iter([1, 2, 3])
for element in my_iterator:
print(element)
# 1, 2,3
my_iterator = iter([1, 2, 3])
print(next(my_iterator)) # 输出:1
print(next(my_iterator)) # 输出:2
print(next(my_iterator)) # 输出:3
b.集合list,dict,tuple,set
集合可以直接print输出。且所有集合实现了 __iter__()
和 __next__()
方法,那么他就是一个可迭代对象。从而,你可以直接隐式的遍历集合,因为他可迭代,实际是调用的内部实现的__iter__()
:
my_list = [1, 2, 3, 4, 5]
for element in my_list:
print(element)
当你需要索引时,用emumerate函数生成索引,enumerate函数返回的也是一个迭代器(index, content),所以你可以遍历。
所以,综上所述,for 循环的语法是
f
o
r
for
for
e
l
e
m
e
n
t
element
element
i
n
in
in
i
t
e
r
a
b
l
e
iterable
iterable,iterable可以是:
- 序列类型:例如列表(list)、元组(tuple)、字符串(str)等。
- 集合类型:例如集合(set)和字典(dict)。
- 文件对象:例如使用 open() 函数打开的文件对象。
- 迭代器:例如使用 iter() 函数获得的迭代器。
c.区分:
__iter__()
:
__iter__()
是一个特殊的方法名,用于在 Python 类中定义一个对象的迭代器。当我们在一个类中定义了__iter__()
方法时,这个类的实例就成为了可迭代的对象,即支持迭代操作。
__iter__()
方法应该返回一个迭代器对象,通常是 self 本身,或者是实现了__next__()
方法的对象。这个迭代器对象可以用于在 for 循环中遍历对象的元素。iter()
:
iter()
是一个内置函数,在 Python 中用于获取一个可迭代对象的迭代器。它的参数可以是任何可迭代对象,比如列表、元组、集合、字典等。
iter()
函数返回指定对象的迭代器。如果对象本身已经实现了__iter__()
方法,iter()
函数会直接调用该方法来获取迭代器;否则,它会尝试使用其他方式创建一个迭代器,例如对于序列类型,返回一个索引逐个遍历元素的迭代器。
具体过程如下:
首先,iter() 函数会检查传入的对象是否实现了 iter() 方法。如果该对象有实现 iter() 方法,那么 iter() 函数会调用该方法,将返回的迭代器对象作为结果返回。
如果对象没有实现 iter() 方法,iter() 函数会尝试查找对象是否实现了 getitem() 方法。如果对象有实现 getitem() 方法,那么 iter() 函数会创建一个简单的索引迭代器,通过索引逐个访问对象的元素。
如果对象既没有实现 iter() 方法,也没有实现 getitem() 方法,那么 iter() 函数会抛出 TypeError,表示该对象不可迭代。
四、详解*与**,*args,**kargs
*args,**kargs:
前置知识提要:
-
list 是有序可变的数据类型,元素在列表中的顺序由其添加的顺序决定。用
.append
添加。列表一般不会作为参数直接传入。
dict 是无序可变的数据类型,元素以键-值对的形式存储。有序的dict称为collections.OrderedDict
。直接添加dic["w"] = 2
tuple是有序不可变的数据类型。 -
函数的参数可以分为两种类型:位置参数和关键字参数。位置参数按照定义时的顺序进行传递,并且每个参数的值与传入时的位置一一对应。关键字参数在函数调用时指定了参数的名称,并且可以在任意顺序下传递。
通过上述的数据结构特性,可以得出,作为函数参数时:
*
用于收集和传递位置参数,返回类型为tuple(追求有序不可变)**
用于收集和传递关键字参数,返回类型为dict(追求无序)
def f(*args, **kargs):
pass
f(1,2,3, Name='xx', age='yy')
# args = (1,2,3)
# kargs = {'Name': xx, 'age': yy}
* & ** 的其他用法
在函数调用或列表拼接等情况下,* 号可以用于解包列表。
my_list = [1, 2, 3]
print(*my_list)
# 1 2 3
*my_list
将会把列表 my_list
中的元素解包,作为单独的参数传递给print()
函数。这样,print(*my_list)
就等价于 print(1, 2, 3)
按照上面的思想我们可以完成下面的代码:
children()
返回的是iterator
,用list()
转为转为列表相加。
nn.Sequential
接受的参数必须是nn.Module
的子类,也就是说你不能把一个列表传给这个类,[nn.ReLU,nn.linear…]
torch.nn.Sequential(*args: Module)
,且sequential是有顺序要求的,利用解包操作一个个传入。
解包之后原式 = nn.Sequential(nn.ReLU,nn.linear.....)
combined_seq = nn.Sequential()
snn_model = model
for name, module in snn_model.named_modules():
if isinstance(module, nn.Sequential):
combined_seq = nn.Sequential(*(list(combined_seq.children()) + list(module.children())))
序列解包运算,也就是把一段不定长数据转换成list,注意这里不是tuple了,而是List
a, b, *c = 1,2,3,4
#c:[3,4]
四、
注意缩进。尤其在Python里的缩进。。。