(1)本文涉及函数的列表(具体用法和注释在代码之中)
- import torch.nn as nn # 导入所需的第三方库的模块
- nn.Module # 被继承的基类
- nn.Conv2d # 定义卷积
- self.add_module # 添加卷积(类似于nn.Conv2d)
- model.children() # 返回子模块的迭代器
- model.modules() # 返回当前模型所有模块的迭代器
- model.named_children() # 返回子模块名字和模块本身的迭代器
- model.named_modules() # 返回模块名和模块本身的迭代器
- model.parameters() # 返回模型所有参数的迭代器
>>>nn.Module官方注释截图
注:
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
其中,nn.Conv2d 的输入参数解释如下:
- in_channels(int) – 输入信号的通道
- out_channels(int) – 卷积产生的通道
- kerner_size(int or tuple) - 卷积核的尺寸
- stride(int or tuple, optional) - 卷积步长
- padding(int or tuple, optional) - 输入的每一条边补充 0 的层数
- dilation(int or tuple, optional) – 卷积核元素之间的间距
- groups(int, optional) – 从输入通道到输出通道的阻塞连接数
- bias(bool, optional) - 如果 bias=True,添加偏置
groups: 控制输入和输出之间的连接, group=1,输出是所有的输入的卷积;group=2,此时相当于有并排的两个卷积层,每个卷积层计算输入通道的一半,并且产生的输出是输出通道的一半,随后将这 两个输出连接起来。
(2)代码示例(含注释)
import torch.nn as nn
# Containers(容器):
# class torch.nn.Module: 所有网络的基类。你的模型也应该继承这个类。
# Modules 也可以包含其它 Modules,允许使用树结构嵌入他们。你可以将子模块赋值给模型属性。
class Model1(nn.Module):
def __init__(self):
super(Model1, self).__init__()
# 定义卷积
self.conv1 = nn.Conv2d(in_channels=1, out_channels=20, kernel_size=(1, 2))
self.conv2 = nn.Conv2d(in_channels=20, out_channels=20, kernel_size=(1, 2))
# 通过上面方式赋值的 submodule 会被注册。当调用 .cuda() 的时候,submodule 的参数也会转换为 cuda Tensor。
model1 = Model1()
print("*"*20, "model1", "*"*20, "\n", model1)
class Model2(nn.Module):
def __init__(self):
super(Model2, self).__init__()
self.add_module("conv3", nn.Conv2d(10, 20, (2, 4)))
self.add_module("conv4", nn.Conv2d(5, 10, (2, 2)))
# 等价于 add_module,但是这个是父类,如果重新定义,则会覆盖子类的卷积信息
# self.conv3 = nn.Conv2d(10, 40, (4, 4))
model2 = Model2()
print("*"*20, "model2", "*"*20, "\n", model2)
# .children(): 返回当前模型 子模块 的迭代器。
print("*"*20, "children", "*"*20)
for sub_module in model2.children():
print("\n", sub_module)
# .modules(): 返回一个包含 当前模型 所有模块的迭代器,即返回 模型信息 和 所有子模块。
# 注意:重复的模块只被返回一次(children()也是)。
print("*"*20, "all", "*"*20)
for module in model2.modules():
print("\n", module)
# 返回 包含 模型当前子模块 的迭代器,产生模块名字和模块本身。
print("*"*20, "named_children", "*"*20)
for name, module1 in model2.named_children():
print("\n", name, module1)
# 返回包含网络中所有模块的迭代器, 产生(yielding)模块名和模块本身。
x, y = [], []
for index, nm in model2.named_modules():
x.append(index)
y.append(nm)
print("*"*20, "named_modules", "*"*20, "\n", x, "\n", y)
# 返回一个 包含模型所有参数 的迭代器。
# 随机生成指定尺寸的张量。
print("*"*20, "parameters", "*"*20)
for param in model2.parameters():
print(type(param.data), "\n", param.size())
>>>output
******************** model1 ********************
Model1(
(conv1): Conv2d(1, 20, kernel_size=(1, 2), stride=(1, 1))
(conv2): Conv2d(20, 20, kernel_size=(1, 2), stride=(1, 1))
)
******************** model2 ********************
Model2(
(conv3): Conv2d(10, 20, kernel_size=(2, 4), stride=(1, 1))
(conv4): Conv2d(5, 10, kernel_size=(2, 2), stride=(1, 1))
)
******************** children ********************Conv2d(10, 20, kernel_size=(2, 4), stride=(1, 1))
Conv2d(5, 10, kernel_size=(2, 2), stride=(1, 1))
******************** all ********************Model2(
(conv3): Conv2d(10, 20, kernel_size=(2, 4), stride=(1, 1))
(conv4): Conv2d(5, 10, kernel_size=(2, 2), stride=(1, 1))
)Conv2d(10, 20, kernel_size=(2, 4), stride=(1, 1))
Conv2d(5, 10, kernel_size=(2, 2), stride=(1, 1))
******************** named_children ********************conv3 Conv2d(10, 20, kernel_size=(2, 4), stride=(1, 1))
conv4 Conv2d(5, 10, kernel_size=(2, 2), stride=(1, 1))
******************** named_modules ********************
['', 'conv3', 'conv4']
[Model2(
(conv3): Conv2d(10, 20, kernel_size=(2, 4), stride=(1, 1))
(conv4): Conv2d(5, 10, kernel_size=(2, 2), stride=(1, 1))
), Conv2d(10, 20, kernel_size=(2, 4), stride=(1, 1)), Conv2d(5, 10, kernel_size=(2, 2), stride=(1, 1))]
******************** parameters ********************
<class 'torch.Tensor'>
torch.Size([20, 10, 2, 4])
<class 'torch.Tensor'>
torch.Size([20])
<class 'torch.Tensor'>
torch.Size([10, 5, 2, 2])
<class 'torch.Tensor'>
torch.Size([10])
>>>如有疑问,欢迎评论区一起探讨