# mypy: 允许未类型化装饰器
# mypy: 允许未类型化定义
导入
操作符
来自
集合
导入 abc
作为 container_abcs, OrderedDict
来自 collections.abc
导入
迭代器,
迭代器,
映射
来自 itertools
导入 chain, islice
来自
打字
导入
任意,
可选,
过载,
类型变量,
联合
来自 typing_extensions
导入
已弃用,
自身
导入
火炬
来自 torch._jit_internal
导入
_脚本复制包装器
来自
torch.nn 参数
导入
参数
来自
.模块
导入
模块
__all__ = [
容器,
顺序的,
模块列表,
模块字典,
参数列表,
参数字典,
]
T = 类型变量(
T,
绑定=
模块)
# 从 torch.nn.modules.module 复制,用于为 ModuleList 自定义__repr__
def _addindent(s_, numSpaces):
s = s_.分割("
输入文本翻译为简体中文为:\n")
#不要对单行内容进行操作
如果
长度(s) == 1:
返回 s_
第一 = s.
弹出(0)
s = [
空格数量 *
输入文本为空,请提供需要翻译的文本) +
行
为
行
在 s]
s = "输入文本翻译为简体中文为:\n".
连接(s)
s = 第一 + "
输入文本翻译为简体中文为:\n" + s
返回 s
@deprecated(
"nn.Container 已弃用。 "
"所有功能现在都已实现在 nn.Module 中。请改用子类化。",
分类=
未来警告,
)
类
容器(
模块):
def 初始化(
我, **kwargs:
任意) ->
无:
超级().
初始化()
为
键, value
在 kwargs.
项目():
我.
添加模块(
键,
值)
[文档]
类
顺序的(
模块):
r一个顺序容器。
模块将按传入顺序添加到其中
构造函数。或者,一个模块的有序字典
传入。`Sequential` 的 `forward()` 方法接受任何
输入并将其转发到它包含的第一个模块。然后
“链式”将输出按顺序传递给每个后续模块的输入,
最后返回最后一个模块的输出。
与手动调用序列相比,`Sequential` 提供的价值
模块的一个特点是它允许将整个容器作为一个
单个模块,以便执行转换
``Sequential``适用于它存储的每个模块(这些是
每个都是一个注册的子模块(``Sequential``)。
什么是 ``Sequential`` 和 ``ModuleList`` 的区别?``ModuleList`` 就像它的名字一样——一个用于存储 ``Module`` 的列表!另一方面,
class:`torch.nn.ModuleList`?A ``ModuleList`` is exactly what it
sounds like--a list for storing ``Module`` s! On the other hand,
the layers in a ``Sequential`` are connected in a cascading way.
示例::
使用 Sequential 创建一个小型模型。当`model`运行时,
输入首先传递给`Conv2d(1,20,5)`。输出传递给
`Conv2d(1,20,5)` 将被用作第一个输入
# `ReLU`;第一个 `ReLU` 的输出将成为输入
对于 `Conv2d(20,64,5)`。最后,输出将用于第二个 `ReLU`
`Conv2d(20,64,5)` 将作为第二个 `ReLU` 的输入
model = nn.Sequential(
nn.Conv2d(1,20,5),
nn.ReLU()
nn.Conv2d(20,64,5)
nn.ReLU()
)
# 使用 Sequential 和 OrderedDict。这在功能上是
# same as the above code
模型 = nn.Sequential(OrderedDict([
('conv1', nn.Conv2d(1,20,5)),
('relu1', nn.ReLU()),
('conv2', nn.Conv2d(20,64,5)),
('relu2', nn.ReLU())
]))
"源代码"
模块:
字典[
字符串,
模块]
# 类型:忽略[赋值]
@overload
def 初始化(
我, *
参数:
模块) ->
无:
...
@overload
def 初始化(
我, arg:
"OrderedDict[str, 模块]") ->
无:
...
def 初始化(
我, *
参数):
超级().
初始化()
如果
长度(
参数) == 1
和 isinstance(
参数[0
]
有序字典):
为
键,
模块
在
参数[0].
项目():
我.
添加模块(
键,
模块)
否则:
为
索引,
模块
在
列举(
参数):
我.
添加模块(
字符串(
索引),
模块)
def _get_item_by_idx(我,
迭代器,
索引) -> T:
# 类型忽略[misc, 类型变量]
获取迭代器的第 idx 个元素。
大小 =
长度(
我)
索引 =
操作符.
索引(
索引)
如果 not -
大小
≤
索引 <
尺寸:
提升
索引错误(f
"索引"{
索引}
超出范围")
索引 %=
大小
返回
下一(islice(
迭代器,
索引,
无))
@_copy_to_script_wrapper
def __getitem__(我,
索引:
联盟[
切片, int]) ->
联盟[
顺序的, T
]
如果 isinstance(
索引,
切片):
返回
我.
类(
有序字典(
列表(
我.
模块.
项目
()
索引]))
否则:
返回
我.
通过索引获取项(
我.
模块.
值(),
索引)
def __setitem__(我,
索引: int,
模块:
模块) ->
无:
键:
字符串 =
我.
通过索引获取项(
我.
模块.
键(),
索引)
返回 setattr(
我,
键,
模块)
def __delitem__(我,
索引:
联盟[
切片, int]) ->
无:
如果 isinstance(
索引,
切片):
为 key
在
列表(
我.
模块.
键
()
索引
]
delattr(我,
键)
否则:
key = 我.
通过索引获取项(
我.
模块.
键(),
索引)
delattr(我,
键)
# To preserve numbering
字符索引 = [
字符串(i)
为 i
在
范围(
长度(
我.
模块))]
我.
模块 =
有序字典(
列表(
压缩(
字符索引,
我.
模块.
值())))
@_copy_to_script_wrapper
def __len__(我) -> int:
返回
长度(
我.
模块)
def __add__(我,
其他) ->
顺序的:
如果 isinstance(
其他,
顺序的):
返回 =
顺序的()
为
层
在
我:
返回.
追加(
层)
为
层
在
其他:
返回.
追加(
层)
返回
返回
否则:
提升 ValueError(
"仅支持对象添加操作符"
f"但仅限于 Sequential 类,但"{
字符串(
类型(
其他))}
给定。"
)
def 弹出(
我,
键:
联盟[int,
切片]) ->
模块:
v = 我[
键]
删除
我[
键]
返回 v
def __iadd__(我,
其他) ->
自身:
如果 isinstance(
其他,
顺序的):
偏移 =
长度(
我)
为 i,
模块
在
列举(
其他):
我.
添加模块(
字符串(i +
偏移量),
模块)
返回 self
否则:
提升 ValueError(
"仅支持对象操作符"
f"的顺序类,但"{
字符串(
类型(
其他))}
是给定的。
)
def __mul__(我,
其他: int) ->
"顺序":
如果 not isinstance(
其他, int):
提升
类型错误(
f"不支持的操作类型:"{
类型(
我)}
和{
类型(
其他)}"
)
elif 其他
≤ 0:
提升 ValueError(
f"非正乘数因子"{
其他}
对于{
类型(
我)}"
)
否则:
组合 =
顺序的()
偏移 = 0
为 _
在
范围(
其他):
为
模块
在
我:
组合.
添加模块(
字符串(
偏移量),
模块)
偏移 += 1
返回
合并
def 矢量乘(
我,
其他: int) ->
顺序的:
返回
我.__mul__(
其他)
def __imul__(我,
其他: int) ->
自身:
如果 not isinstance(
其他, int):
提升
类型错误(
f"不支持的操作类型(s) for *:"{
类型(
我)}
和{
类型(
其他)}"
)
elif 其他
≤ 0:
提升 ValueError(
f"非正乘数因子"{
其他}
对于{
类型(
我)}"
)
否则:
原始长度 =
长度(
我)
偏移 =
长度(
我)
为 _
在
范围(
其他 - 1):
为 i
在
范围(
原始长度):
我.
添加模块(
字符串(i +
偏移量),
我.
模块[
字符串(i
)]])
偏移 +=
原始长度
返回 self
@_copy_to_script_wrapper
def __dir__(我):
键 =
超级().__dir__()
键 = [key
为 key
在
键
如果 not
键.isdigit()]
返回
键
@_copy_to_script_wrapper
def __iter__(我) ->
迭代器[
模块
]
返回
迭代(
我.
模块.
值())
# NB: 我们实际上无法对这个函数进行类型检查,因为输入的类型
# 可能会动态变化(如测试所示)
# TestScript.test_sequential_intermediary_types)。无法使用 Any 进行注释
# 因为 TorchScript 需要更精确的类型
def 前向(
我,
输入):
为
模块
在
我:
输入 =
模块(
输入)
返回
输入
[文档] def append(self, module: Module) -> "Sequential":
将给定的模块追加到末尾。
参数:
module (nn.Module): 要追加的模块
"""
self.add_module(str(len(self)), 模块)
return self
def 插入(
我,
索引: int,
模块:
模块) ->
序列:
如果 not isinstance(
模块,
模块):
提升
断言错误(f
模块应为以下类型:{
模块}")
n = 长度(
我.
模块)
如果 not (-n
≤
索引
≤ n):
提升
索引错误(f
索引超出范围:{
索引}")
如果
索引 < 0:
索引 += n
为 i
在
范围(n,
索引, -1):
我.
模块[
字符串(i
] =
我.
模块[
字符串(i - 1
]
我.
模块[
字符串(
索引
] =
模块
返回 self
def 扩展(
我,
顺序的) ->
顺序的:
为
层
在
顺序的:
我.
追加(
层)
返回
我
[文档]
类
模块列表(
模块):
r将子模块存储在列表中。
`:class:`~torch.nn.ModuleList` 可以像常规 Python 列表一样索引,但
包含的模块已正确注册,并且将可通过所有
`:class:`~torch.nn.Module` 方法可见。
参数:
模块(可迭代,可选):要添加的模块的可迭代对象
示例::
class MyModule(nn.Module):
def __init__(self) -> None:
super().__init__()
self.linears = nn.ModuleList([nn.Linear(10, 10) for i in range(10)])
def forward(self, x):
# ModuleList 可以作为可迭代对象使用,或者使用整数进行索引
for i, l in enumerate(self.linears):
x = self.linears[i // 2](x) + l(x)
return x
"源代码"
模块:
字典[
字符串,
模块]
# 类型:忽略[赋值]
def 初始化(
我,
模块:
可选[
迭代器[
模块]] =
无) ->
无:
超级().
初始化()
如果
模块
是 not
无:
self += 模块
def _get_abs_string_index(我,
索引):
获取模块列表的绝对索引。
索引 =
操作符.
索引(
索引)
如果 not (-
长度(
我)
≤
索引 <
长度(
我)):
提升
索引错误(f
"索引"{
索引}
超出范围")
如果
索引 < 0:
索引 +=
长度(
我)
返回
字符串(
索引)
@overload
def __getitem__(我,
索引:
切片) ->
模块列表:
...
@overload
def __getitem__(我,
索引: int) ->
模块:
...
@_copy_to_script_wrapper
def __getitem__(我,
索引:
联盟[int,
切片]) ->
联盟[
模块,
模块列表
]
如果 isinstance(
索引,
切片):
返回
我.
类(
列表(
我.
模块.
值
()
索引])
否则:
返回
我.
模块[
我.
_获取绝对字符串索引(
索引
]
def __setitem__(我,
索引: int,
模块:
模块) ->
无:
索引 =
我._get_abs_string_index(
索引)
返回 setattr(
我,
字符串(
索引),
模块)
def __delitem__(我,
索引:
联盟[int,
切片]) ->
无:
如果 isinstance(
索引,
切片):
为 k
在
范围(
长度(
我.
模块))[
索引
]
delattr(我,
字符串(k))
否则:
delattr(我,
我._get_abs_string_index(
索引))
# 为了保留编号,self._modules 正在被重建,以删除后的模块
str_indices = [字符串(i)
为 i
在
范围(
长度(
我.
模块))]
我.
模块 =
有序字典(
列表(
压缩(
str_indices
字符串索引, 我.
模块.
值())))
@_copy_to_script_wrapper
def __len__(我) -> int:
返回
长度(
我.
模块)
@_copy_to_script_wrapper
def __iter__(我) ->
迭代器[
模块
]
返回
迭代(
我.
模块.
值())
def __iadd__(我,
模块:
迭代器[
模块]) ->
自身:
返回
我.
扩展(
模块)
def __add__(我,
其他:
迭代器[
模块]) ->
模块列表:
合并 =
模块列表()
为 i,
模块
在
列举(chain(
我,
其他)):
合并.
添加模块(
字符串(i),
模块)
返回
合并
def __repr__(我):
返回一个用于 ModuleList 的自定义 repr,该 repr 可以压缩重复的模块表示。
repr 列表 = [
表示(
项目)
为
项目
在
我]
如果
长度(
repr 列表) == 0:
返回
我.
_获取名称() + "()"
起始结束索引 = [[0, 0]]
重复块 = [
表示列表[0]]
为 i, r
在
列举(
表示列表[1
, 1):
如果 r ==
重复块[-1
]
起始结束索引[-1
]
[1] += 1
继续
起始结束索引.
追加([i, i])
重复块.
追加(r)
行 = []
主字符串 =
我.
_获取名称() +
“(”
为 (
开始 ID,
结束 ID), b
在
压缩(
开始结束索引,
重复块):
本地表示 = f
“(”{
开始 ID}): {b}"
# 默认表示
如果
开始 ID !=
结束 ID:
n = 结束 ID -
开始 ID + 1
本地表示 = f
“(”{
开始 ID}-{
结束 ID}): {n} x {b}"
本地表示 = _addindent(
本地表示, 2)
行.
追加(
本地表示)
主字符串 += "
输入文本翻译为简体中文为:\n " + "
输入文本翻译为简体中文为:\n ".
连接(
行) + "
输入文本翻译为简体中文为:\n"
主字符串 +=
)"
返回
主字符串
@_copy_to_script_wrapper
def __dir__(我):
键 =
超级().__dir__()
键 = [key
为 key
在
键
如果 not
键.isdigit()]
返回
键
[文档] def insert(self, index: int, module: Module) -> None:
r"""在列表中插入指定模块到指定索引之前。
Args:
index (int): 要插入的索引。
(nn.Module): 插入模块
"""
for i in range(len(self._modules), index, -1):
self._modules[str(i)] = self._modules[str(i - 1)]
self._modules[str(index)] = module
[文档] def append(self, 模块: 模块) -> "模块列表":
r"""将给定的模块添加到列表末尾。
Args:
模块 (nn.Module): 要添加的模块
"``"
self.add_module(str(len(self)), module)
return self
def 弹出(
我,
键:
联盟[int,
切片]) ->
模块:
v = 我[
键]
删除
我[
键]
返回 v
[文档] def extend(self, modules: Iterable[Module]) -> Self:
r"""将 Python 可迭代对象中的模块追加到列表末尾。
Args:
modules (可迭代对象): 要追加的模块的可迭代对象
"""
如果不是 isinstance(modules, container_abcs.Iterable):
抛出 TypeError(
"ModuleList.extend 应该用参数调用 "
"可迭代的,但得到了 " + type(modules).__name__
)
偏移量 = len(self)
for i, module in enumerate(modules):
self.add_module(str(offset + i), module)
返回 self
# 移除所有前进以回退到 Module 的_forward_unimplemented
[文档]
类 ModuleDict(
模块):
r在字典中保存子模块。
`torch.nn.ModuleDict` 可以像常规 Python 字典一样索引,
但它包含的模块会被正确注册,并且对所有模块可见
`torch.nn.Module` 方法。
`torch.nn.ModuleDict` 是一个 **有序** 的字典,它尊重
* 插入顺序,并且
* 在 `torch.nn.ModuleDict.update` 中,合并的顺序
`OrderedDict`、`dict`(从 Python 3.6 开始)或另一个
`:class:`~torch.nn.ModuleDict`(参数为)
`:meth:`~torch.nn.ModuleDict.update`)。
注意:使用其他无序映射的 `:meth:`~torch.nn.ModuleDict.update`。
类型(例如,Python 3.6 版本之前的 Python 的普通`dict`)不保留合并映射的顺序。
模块(可迭代,可选):一个(字符串:模块)映射(字典)或键值对的可迭代序列,键值对类型为(字符串,模块)。
参数:
模块(iterable,可选):一个(字符串:模块)映射(字典)或一个键值对的可迭代序列,键值对类型为(字符串,模块)。
模块(iterable,可选):一个(字符串:模块)映射(字典)或一个键值对的可迭代序列,键值对类型为(字符串,模块)。
示例::
class MyModule(nn.Module):
def __init__(self) -> None:
super().__init__()
self.choices = nn.ModuleDict({)
'conv': nn.Conv2d(10, 10, 3),
'pool': nn.MaxPool2d(3)
})
self.activations = nn.ModuleDict([
['lrelu', nn.LeakyReLU()]
['prelu', nn.PReLU()]
])
def forward(self, x, choice, act):
x = self.choices[choice](x)
x = self.activations[act](x)
return x
"源代码"
模块:
字典[
字符串,
模块]
# 类型:忽略[赋值]
def 初始化(
我,
模块:
可选[
映射[
字符串,
模块]] =
无) ->
无:
超级().
初始化()
如果
模块
是 not
无:
我.
更新(
模块)
@_copy_to_script_wrapper
def __getitem__(我,
键:
字符串) ->
模块:
返回
我.
模块[
键]
def __setitem__(我,
键:
字符串,
模块:
模块) ->
无:
我.
添加模块(
键,
模块)
def __delitem__(我,
键:
字符串) ->
无:
删除
我.
模块[
键]
@_copy_to_script_wrapper
def __len__(我) -> int:
返回
长度(
我.
模块)
@_copy_to_script_wrapper
def __iter__(我) ->
迭代器[
字符串
]
返回
迭代(
我.
模块)
@_copy_to_script_wrapper
def 包含(
我,
键:
字符串) ->
布尔:
返回 key
在
我.
模块
[文档] def clear(self) -> None:
"""从模块字典中移除所有项。"""
self._modules.clear()
[文档] def pop(self, key: str) -> Module:
从模块字典中删除键并返回其模块。
参数:
key (str): 从模块字典中弹出的键
"""
v = self[key]
del self[key]
return v
[文档] @_copy_to_script_wrapper
def keys(self) -> Iterable[str]
返回模块字典键的可迭代对象。
return self._modules.keys()
[文档] @copy_to_script_wrapper
def items(self) -> Iterable[tuple[str, Module]]:
r"""返回一个包含 ModuleDict 键值对的迭代器。"""
return self._modules.items()
[文档] @_copy_to_script_wrapper
def values(self) -> Iterable[Module]
返回一个包含 ModuleDict 值的可迭代对象。
return self._modules.values()
[文档] def update(self, modules: Mapping[str, Module]) -> None:
更新 :class:`~torch.nn.ModuleDict`,使用映射中的键值对,覆盖现有键。
.. 注意::
如果 :attr:`modules` 是一个 ``OrderedDict``、一个 :class:`~torch.nn.ModuleDict` 或
一个键值对的迭代器,则其中新元素的顺序将被保留。
Args:
模块(可迭代对象):一个从字符串到 :class:`~torch.nn.Module` 的映射(字典),
或者一个类型为(字符串,:class:`~torch.nn.Module`)的键值对的可迭代对象
"""
如果不是 container_abcs.Iterable 类型的实例:
raise TypeError(
"ModuleDict.update 应该使用键值对的可迭代对象调用,但得到了 " + type(modules).__name__
"ModuleDict.update 应该使用键值对的可迭代对象调用,但得到了 " + type(modules).__name__
)
如果 isinstance(modules, (OrderedDict, ModuleDict, container_abcs.Mapping))
for key, module in modules.items():
self[key] = module
else:
# 模块这里可以是一个包含两个元素的列表
for j, m in enumerate(modules):
if not isinstance(m, container_abcs.Iterable):
raise TypeError(
"模块字典更新序列元素 "
"#" + str(j) + " 应该是可迭代对象;实际类型为" + type(m).__name__
)
如果列表 m 的长度不等于 2:
raise ValueError(
"模块字典更新序列元素 "
"#" + str(j) + " 的长度为 " + str(len(m)) + ";需要 2 个"
)
# 模块可以是映射(在输入中如何类型),或者是一个列表:[(name1, module1), (name2, module2)]
# 这样使用重载输入太繁琐,所以在这里添加忽略
self[m[0]] = m[1] # 类型:忽略[赋值]
完全删除前缀以回退到模块的 _forward_unimplemented
[文档]
类
参数列表(
模块):
r将参数存储在列表中。
类 `~torch.nn.ParameterList` 可以像常规 Python 列表一样使用,
但作为 `~torch.nn.Parameter` 的张量会被正确注册,
它将由所有 :class:`~torch.nn.Module` 方法可见。
注意构造函数、将列表元素赋值、:meth:`~torch.nn.ParameterList.append` 方法以及 :meth:`~torch.nn.ParameterList.extend` 方法会将任何 :class:`~torch.Tensor` 转换为 :class:`~torch.nn.Parameter`。
meth:`~torch.nn.ParameterList.append` 方法以及 :meth:`~torch.nn.ParameterList.extend` 方法。
该方法将任何 :class:`~torch.Tensor` 转换为 :class:`~torch.nn.Parameter`。
参数:
参数(可迭代对象,可选):要添加到列表中的元素的可迭代对象。
示例::
class MyModule(nn.Module):
def __init__(self) -> None:
super().__init__()
self.params = nn.ParameterList([nn.Parameter(torch.randn(10, 10)) for i in range(10)])
def forward(self, x):
# ParameterList 可以作为可迭代对象使用,也可以使用整数进行索引
for i, p in enumerate(self.params):
x = self.params[i // 2].mm(x) + p.mm(x)
return x
"源代码"
def 初始化(
我,
值:
可选[
迭代器[
任意]] =
无) ->
无:
超级().
初始化()
我.
_大小 = 0
如果 values
是 not
无:
self += values
def _get_abs_string_index(我,
索引):
获取模块列表的绝对索引。
索引 =
操作符.
索引(
索引)
如果 not (-
长度(
我)
≤
索引 <
长度(
我)):
提升
索引错误(f
"索引"{
索引}
超出范围")
如果
索引 < 0:
索引 +=
长度(
我)
返回
字符串(
索引)
@overload
def __getitem__(我,
索引: int) ->
任意:
...
@overload
def __getitem__(我: T,
索引:
切片) -> T:
...
def __getitem__(我,
索引):
如果 isinstance(
索引,
切片):
开始,
停止,
步骤 =
索引.
索引(
长度(
我))
out = 我.
类()
为 i
在
范围(
开始,
停止,
步长):
输出.
追加(
我[i])
返回 out
否则:
索引 =
我.
获取绝对字符串索引(
索引)
返回 getattr(
我,
字符串(
索引))
def __setitem__(我,
索引: int,
参数:
任意) ->
无:
注意,所有添加到列表部分的函数
最终都会在这里结束。所以这是唯一需要
将内容包裹在 Parameter 中的地方。
通过 setattr()添加的对象不在列表部分,因此不会
调用此函数。
索引 =
我.
_获取绝对字符串索引(
索引)
如果 isinstance(
参数,
火炬.
张量)
和 not isinstance(
参数,
参数):
参数 =
参数(
参数)
返回 setattr(
我,
字符串(
索引),
参数)
def __len__(我) -> int:
返回
我.
_大小
def __iter__(我) ->
迭代器[
任意
]
返回
迭代(
我[i]
为 i
在
范围(
长度(
我)))
def __iadd__(我,
参数:
迭代器[
任意]) ->
自身:
返回
我.
扩展(
参数)
def __dir__(我):
键 =
超级().__dir__()
键 = [key
为 key
在
键
如果 not
键.isdigit()]
返回
键
[文档] def append(self, value: Any) -> "参数列表":
"""将给定的值追加到列表末尾。
Args:
value (Any): 要追加的值
"``"
new_idx = self 的长度
self._size += 1
self[new_idx] = value
返回自身
[文档] def extend(self, values: Iterable[Any]) -> Self:
"""将 Python 可迭代对象中的值追加到列表末尾。
参数:
values(可迭代对象):要附加的值(可迭代对象)
"""
# 张量是可迭代的,但我们在这里不想解包它
如果 values 不是 container_abcs.Iterable 类型或者
值,torch.Tensor
):
raise TypeError(
"ParameterList.extend 应该用参数调用 "
可迭代的,但得到了 " + type(values).__name__
)
for value in values:
self.append(value)
返回自身
def 额外表示(
我) ->
字符串:
子行 = []
为 k, p
在
列举(
我):
如果 isinstance(p,
火炬.
张量):
大小字符串 = "x".
连接(
字符串(
尺寸)
为
大小
在 p.
尺寸())
如果 p.
设备.
类型
在 [
cuda,
火炬._C._get_privateuse1_backend_name()]:
设备字符串 = f
"("{p.
设备})"
否则:
设备字符串 =
请提供需要翻译的文本
段落字符串 = "{}
包含:{}
大小为{}{}
]].
格式(
参数
如果 isinstance(p,
参数)
否则
"张量",
p.数据类型,
大小字符串,
设备字符串,
)
子行.
追加(" (" +
字符串(k) + "): " +
段落字符串)
否则:
子行.
追加(
( ) +
字符串(k) +
"):对象类型: +
类型(p).__name__
)
临时字符串 = "
输入文本翻译为简体中文为:\n".
连接(
子行)
返回
临时字符串
def __调用__(
我, *
参数, **kwargs):
提升
运行时错误(
"参数列表不应被调用。")
[文档]
类 ParameterDict(
模块):
r将参数存储在字典中。
ParameterDict 可以像常规 Python 字典一样索引,但它包含的参数会被正确注册,并且将可以通过所有 Module 方法可见。
其他对象将被当作常规 Python 字典处理。
其他对象将按照常规 Python 字典的处理方式处理。
`:class:`~torch.nn.ParameterDict` 是一个 **有序** 字典。
torch.nn.ParameterDict.update 与其他无序映射一起使用
类型(例如,Python 的普通`dict`)不保留顺序
合并映射。另一方面,`OrderedDict` 或另一个 `:class:`~torch.nn.ParameterDict`
将保留它们的顺序。
注意构造函数、分配字典元素以及
meth:`~torch.nn.ParameterDict.update` 方法会将任何 :class:`~torch.Tensor` 转换为
class:`~torch.nn.Parameter`。
参数:
values(可迭代对象,可选):一个映射(字典)
(字符串:Any)或一个键值对的可迭代对象
类型为(字符串,Any)
示例::
class MyModule(nn.Module):
def __init__(self) -> None:
super().__init__()
self.params = nn.ParameterDict({
'left': nn.Parameter(torch.randn(5, 10)),
'right': nn.Parameter(torch.randn(5, 10))
})
def forward(self, x, choice):
x = self.params[choice].mm(x)
return x
"源代码"
def 初始化(
我,
参数:
任何 =
无) ->
无:
超级().
初始化()
我._keys:
字典[
字符串,
无] = {}
如果
参数
是 not
无:
我.
更新(
参数)
def _key_to_attr(我,
键:
字符串) ->
字符串:
如果 not isinstance(
键,
字符串):
提升
类型错误(
"给定的索引不能用作键,因为它不是字符串(类型是"
f"不是字符串(类型是'"{
类型(
键).__name__}
'). 在 "github" 上提交一个 issue,如果您需要非字符串键。'
"github if you need non-string keys."
)
否则:
# 使用键的原始形式,以便 `.named_parameters()` 返回正确的内容
返回 key
def __getitem__(我,
键:
字符串) ->
任意:
属性 =
我._key_to_attr(
键)
返回 getattr(
我,
属性)
def __setitem__(我,
键:
字符串,
值:
任意) ->
无:
# 注意,所有添加到字典部分的函数,包括
# ParameterDict 的,最终都会在这里。因此,这是唯一需要
# 将内容包装到 Parameter 中的地方。
# 通过 setattr()添加的对象不在字典部分,因此不会
# 调用此函数。
我.
_键[
键] =
无
属性 =
我._key_to_attr(
键)
如果 isinstance(
值,
火炬.
张量)
和 not isinstance(
值,
参数):
value = 参数(
值)
setattr(我,
属性,
值)
def __delitem__(我,
键:
字符串) ->
无:
删除
我._keys[
键]
属性 =
我._key_to_attr(
键)
delattr(我,
属性)
def __len__(我) -> int:
返回
长度(
我._keys)
def __iter__(我) ->
迭代器[
字符串
]
返回
迭代(
我._keys)
def __倒序__(
我) ->
迭代器[
字符串
]
返回
反转(
列表(
我._keys))
[文档] def 复制(self) -> "参数字典":
返回此 :class:`~torch.nn.ParameterDict` 实例的副本。
我们必须使用 OrderedDict,因为 ParameterDict 构造函数
在普通字典和 OrderedDict 上的行为不同
返回 ParameterDict(OrderedDict((k, self[k]) for k in self._keys))
def 包含(
我,
键:
字符串) ->
布尔:
返回 key
在
我._keys
[文档] def setdefault(self, key: str, default: Optional[Any] = None) -> Any:
"""设置 Parameterdict 中键的默认值。
如果键在 ParameterDict 中,则返回其值。
如果没有,则插入带有参数 `default` 的 `key` 并返回 `default`。
`default` 默认为 `None`。
参数:
key (str): 设置默认值的键
默认(任何):设置给键的参数
"""
如果键不在 self 中:
self[key] = default
return self[key]
[docs] def clear(self) -> None:
"""Remove all items from the ParameterDict."""
for k in self._keys.copy():
删除 self[k]
[文档] def pop(self, key: str) -> Any:
r"""从 ParameterDict 中删除 key 并返回其参数。
Args:
key (str): 从 ParameterDict 中弹出的键
"""
v = self[key]
del self[key]
返回 v
[文档] def popitem(self) -> tuple[str, Any]:
"""从 ParameterDict 中移除并返回最后一个插入的 `(key, parameter)` 对"""
k, _ = self._keys.popitem()
# 我们需要 _keys 中的键来访问/删除
self._keys[k] = None
val = self[k]
del self[k]
return k, val
[文档] def get(self, key: str, default: Optional[Any] = None) -> Any:
r"""返回与键关联的参数(如果存在)。如果没有提供默认值,则返回 None。
参数:
key (str): 从 ParameterDict 获取的键
默认(参数,可选):如果键不存在则返回的值
"""
如果键在 self 中,则返回 self[key],否则返回 default
[文档] def fromkeys(
self, 键: 可迭代字符串,默认: 可选的 Any = None
) -> "ParameterDict":
r"""返回一个新的 ParameterDict,包含提供的键。
参数:
keys(可迭代对象,字符串):用于从新 ParameterDict 中创建的键
default(Parameter,可选):为所有键设置的值
"""
返回 ParameterDict((k, default) for k in keys)
[文档] def keys(self) -> Iterable[str]:
返回 ParameterDict 键的可迭代对象。
return self._keys.keys()
[文档] def items(self) -> Iterable[tuple[str, Any]]:
返回一个包含 ParameterDict 键/值对的迭代器。
return ((k, self[k]) for k in self._keys)
[文档] def values(self) -> Iterable[Any]:
返回 ParameterDict 值的可迭代对象。
返回一个生成器表达式,遍历 self._keys 中的键,并获取 self 中对应的值。
[文档] def update(self, parameters: 联合[Mapping[str, Any], "ParameterDict"]) -> None:
r"""更新 :class:`~torch.nn.ParameterDict`,使用 ``parameters`` 中的键值对,覆盖现有键。
.. note::
如果 :attr:`parameters` 是一个 ``OrderedDict``、:class:`~torch.nn.ParameterDict` 或
一个可迭代的键值对序列,其中新元素的顺序被保留。
Args:
参数(可迭代对象):一个从字符串到
class:`~torch.nn.Parameter`,或一个可迭代的
类型为 (字符串, :class:`~torch.nn.Parameter`) 的键值对
"""
如果 parameters 不是 container_abcs.Iterable 的实例:
抛出 TypeError 异常(
"ParametersDict.update 应该使用键值对的可迭代对象调用,但得到的是 " + type(parameters).__name__
"if isinstance(parameters, (OrderedDict, ParameterDict))"
)
if isinstance(parameters, (OrderedDict, ParameterDict))
for key, parameter in parameters.items():
self[key] = parameter
elif isinstance(parameters, container_abcs.Mapping):
for key, parameter in sorted(parameters.items()):
self[key] = 参数
else:
for j, p in enumerate(参数):
if not isinstance(p, container_abcs.可迭代):
raise TypeError(
"参数字典更新序列元素 "
"#" + str(j) + " 应该是可迭代对象;是 " + type(p).__name__
)
如果 len(p) 不等于 2:
raise ValueError(
"参数字典更新序列元素 "
"#" + str(j) + " 的长度为 " + str(len(p)) + ";需要 2 个"
)
参数作为长度为 2 的列表过于繁琐,请参阅 ModuleDict.update 注释
self[p[0]] = p[1] # 忽略赋值类型
def 额外表示(
我) ->
字符串:
子行 = []
为 k, p
在
我.
项目():
如果 isinstance(p,
火炬.
张量):
大小字符串 = "x".
连接(
字符串(
尺寸)
为
大小
在 p.
尺寸())
如果 p.
设备.
类型
在 [
cuda,
火炬._C._get_privateuse1_backend_name()]:
设备字符串 = f
"("{p.
设备})"
否则:
设备字符串 =
请提供需要翻译的文本
段落字符串 = "{}
包含:{}
大小为{}{}
]].
格式(
参数
如果 isinstance(p,
参数)
否则
"张量",
火炬.
类型名(p),
size_str,
设备字符串,
)
儿歌.
追加(" (" +
字符串(k) + "): " +
段落)
否则:
儿行.
追加(
" (" + 字符串(k) +
"): 对象类型: " +
类型(p).__name__
)
tmpstr = "输入文本翻译为简体中文为:\n".
加入(
子行)
返回
临时字符串
def __调用__(
我,
输入):
提升
运行时错误(
"ParameterDict 不应被调用。")
def __or__(自己,
其他:
参数字典) ->
参数字典:
复制 =
我.
复制()
复制.
更新(
其他)
返回
复制
def __ror__(我,
其他:
"参数字典") ->
"参数字典":
复制 =
其他.
复制()
复制.
更新(
自己)
返回
复制
def __ior__(自己,
其他:
"参数字典") ->
自身:
自己.
更新(
其他)
返回
自己