<jupyter_start><jupyter_text>模型构造---  继承Module类来构造模型<jupyter_code>import torch
from torch import nn

class MLP(nn.Module):
    # 声明带有模型参数的层，这里声明了两个全连接层
    def __init__(self, **kwargs):
        super(MLP,self).__init__(**kwargs)
        self.hidden = nn.Linear(784, 256)
        self.act = nn.ReLU()
        self.output = nn.Linear(256, 10)

    # 定义模型的前向运算，即如何根据输入x计算返回所需要的模型输出
    def forward(self, x):
        a = self.act(self.hidden(x))
        return self.output(a)
X = torch.rand(2, 784)
net = MLP()
print(net)
net(X)
from collections import OrderedDict
class MySequential(nn.Module):
    def __init__(self, *args):
        super(MySequential, self).__init__()
        if len(args) == 1 and isinstance(args[0], OrderedDict):
            for key, module in args[0].item():
                self.add_module(key, module)
        else:
            for idx, module in enumerate(args):
                print('idx: ', idx)
                print('module: ', module)
                self.add_module(str(idx), module)

    def forward(self, input):
        for module in self._modules.values():
            input = module(input)
        return input
net = MySequential(
    nn.Linear(784, 256),
    nn.ReLU(),
    nn.Linear(256, 10)
)
print(net)
net(X)<jupyter_output>idx:  0
module:  Linear(in_features=784, out_features=256, bias=True)
idx:  1
module:  ReLU()
idx:  2
module:  Linear(in_features=256, out_features=10, bias=True)
MySequential(
  (0): Linear(in_features=784, out_features=256, bias=True)
  (1): ReLU()
  (2): Linear(in_features=256, out_features=10, bias=True)
)<jupyter_text>ModuleList<jupyter_code>net = nn.ModuleList([nn.Linear(784, 256), nn.ReLU()])
net.append(nn.Linear(256, 10))
print(net[-1])
print(net)
# net(torch.zeros(1, 784)) # 会报NotImplementedError
# oduleList仅仅是一个储存各种模块的列表，这些模块之间没有联系也没有顺序（所以不用保证相邻层的输入输出维度匹配），而且没有实现forward功能需要自己实现，所以上面执行net(torch.zeros(1, 784))会报NotImplementedError；
# 而Sequential内的模块需要按照顺序排列，要保证相邻层的输入输出大小相匹配，内部forward功能已经实现。

class MyModule(nn.Module):
    def __init__(self):
        super(MyModule, self).__init__()
        self.linears = nn.ModuleList([nn.Linear(10, 10) for i in range(10)])

    def forward(self, x):
        for i, l in enumerate(self.linears):
            print('self.linears[i // 2](x): ', self.linears[i // 2](x))
            x = self.linears[i // 2](x) + l(x)
        return x
# ModuleList不同于一般的Python的list，加入到ModuleList里面的所有模块的参数会被自动添加到整个网络中
class Module_ModuleList(nn.ModuleList):
    def __init__(self):
        super(Module_ModuleList, self).__init__()
        self.linears = nn.ModuleList([nn.Linear(10,10)])

class Module_List(nn.Module):
    def __init__(self):
        super(Module_List, self).__init__()
        self.linears = [nn.Linear(10,10)]

net1 = Module_ModuleList()
net2 = Module_List()

print('net1: ')
for p in net1.parameters():
    print(p.size())

print('net2: ')
for p in net2.parameters():
    print(p.size())<jupyter_output>net1: 
torch.Size([10, 10])
torch.Size([10])
net2:<jupyter_text>ModuleDict类<jupyter_code>net = nn.ModuleDict({
    'linear': nn.Linear(784, 256),
    'act': nn.ReLU()
})
net['output'] = nn.Linear(256, 10)
print(net['linear'])
print(net.output)
print(net)<jupyter_output>Linear(in_features=784, out_features=256, bias=True)
Linear(in_features=256, out_features=10, bias=True)
ModuleDict(
  (linear): Linear(in_features=784, out_features=256, bias=True)
  (act): ReLU()
  (output): Linear(in_features=256, out_features=10, bias=True)
)<jupyter_text>构造复杂的模型<jupyter_code>class FancyMLP(nn.Module):
    def __init__(self, **kwargs):
        super(FancyMLP, self).__init__()

        self.rand_weight = torch.rand((20, 20), requires_grad=True)
        self.linear = nn.Linear(20, 20)

    def forward(self, x):
        x = self.linear(x)
        # 使用创建的参数，以及nn.functional中的relu函数、mm函数
        x = nn.functional.relu(torch.mm(x, self.rand_weight.data) + 1)

        # 复用全连接层。等价于两个全连接层共享参数
        x = self.linear(x)
        # 控制流，这里我们需要调用item函数来返回标量进行比较
        while x.norm().item() > 1:
            x /= 2
        if x.norm().item() < 0.8:
            x *= 10
        return x.sum()
X = torch.rand(2, 20)
net = FancyMLP()
print(net)
net(X)<jupyter_output>FancyMLP(
  (linear): Linear(in_features=20, out_features=20, bias=True)
)
{'fraction_non_alphanumeric': 0.150694607958559, 'fraction_numerical': 0.03838003296444549, 'mean_word_length': 3.5775862068965516, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '26715', 'license': 'MIT', 'n_tokens_mistral': 1860, 'n_tokens_neox': 1807, 'n_words': 280, 'path': 'Deep-Learning-Notes/4 Calculation/1-Module-Construct.ipynb', 'repo_name': 'zhiyu1998/JavaStudyXmind', 'size': '4247'}