# 《动手学深度学习Pytorch版》之Pytorch常用操作

## 二、模型保存读取操作

### 1、访问模块模型参数

``````model.parameters()
``````

``````state_dict
``````

``````import torch
from torch import nn

net = MLP()   #这里我省略了MLP()的定义，详见《动手学习深度学习Pytorch》对应章节
net.state_dict()
``````

``````class MLP(nn.Module):...
OrderedDict([('hidden.weight',
tensor([[-0.1291, -0.4541, -0.0159],
[-0.5555, -0.3319,  0.4285]])),
('hidden.bias', tensor([-0.3046, -0.0209])),
('output.weight', tensor([[-0.4204,  0.4508]])),
('output.bias', tensor([-0.5094]))])
``````

``````optimizer = torch.optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
optimizer.state_dict()
``````

``````optimizer = torch.optim.SGD(net.parameters(), lr=0.001, momentum=0.9)...
{'state': {},
'param_groups': [{'lr': 0.001,
'momentum': 0.9,
'dampening': 0,
'weight_decay': 0,
'nesterov': False,
'params': [0, 1, 2, 3]}]}
``````

### 2、保存加载模型

#### 1）仅保存和加载模型参数（state_dict）(推荐)

`````` torch.save(model.state_dict(), PATH) # 推荐的⽂件后缀名是pt或pth
``````

``````model = TheModelClass(*args, **kwargs)
``````

#### 2）保存和加载整个模型

``````torch.save(model, PATH)
``````

``````model = torch.load(PATH)
``````

## 三、网络操作

### 1、named_children：获取一级子模块及其名字

``````# named_children获取一级子模块及其名字(named_modules会返回所有子模块,包括子模块的子模块)
for name, blk in net.named_children():
X = blk(X)
print(name, 'output shape: ', X.shape)
``````

``````vgg_block_1 output shape:  torch.Size([1, 64, 112, 112])
vgg_block_2 output shape:  torch.Size([1, 128, 56, 56])
vgg_block_3 output shape:  torch.Size([1, 256, 28, 28])
vgg_block_4 output shape:  torch.Size([1, 512, 14, 14])
vgg_block_5 output shape:  torch.Size([1, 512, 7, 7])
``````

### 2、torch.cat((p1, p2, p3, p4), dim=1) # 在通道维上连结输出

torch.cat是将两个张量（tensor）拼接在一起，cat是concatnate的意思，即拼接，联系在一起。

``````C = torch.cat( (A,B),0 )  #按维数0拼接（竖着拼）

C = torch.cat( (A,B),1 )  #按维数1拼接（横着拼）
``````

### 3、Global average Pooling

GAP的工作原理：

``````net.add_module("global_avg_pool", d2l.GlobalAvgPool2d()) # GlobalAvgPool2d的输出: (Batch, 512, 1, 1)
``````

### 4、Flatten layer

Convolution卷积层之后是无法直接连接Dense全连接层的，需要把Convolution层的数据压平（Flatten），然后就可以直接加Dense层了。

``````X = torch.rand((1, 512, 1, 1))
Flatnet = d2l.FlattenLayer()
Flatnet(X).size()
``````

``````torch.Size([1, 512])
``````