深度学习——参数管理(笔记)

1.单隐藏层的多层感知机

import torch
from torch import nn

# 单隐藏层的多层感知机
net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 1))
X = torch.rand(size=(2, 4))
print(net(X))

输出:

 

2.查看全部参数访问:获取权重和偏置。指定层的参数 net[2]就是 nn.Linear(8, 1)

 print(net[2].state_dict())

输出:

OrderedDict([('weight', tensor([[ 0.2506, -0.1574, -0.2171,  0.1743, -0.0860, -0.1802, -0.0337,  0.3189]])), ('bias', tensor([0.1444]))])

3.指定参数的访问--偏置

①查看指定偏置的类型

print(type(net[2].bias))

输出:Parameter'>

Parameter'代表参数可以优化

②查看指定偏置的数据

print(net[2].bias)

输出:

Parameter containing:
tensor([-0.0795], requires_grad=True)

③查看指定偏置的数值

print(net[2].bias.data)

输出:tensor([-0.0795])

④查看偏置的梯度(没有反向传播计算所以None)

print(net[2].bias.grad)

输出:None 

4.访问指定net[0]层的参数

net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 1))
print(*[(name, param.shape) for name, param in net[0].named_parameters()])

输出:

('weight', torch.Size([8, 4])) ('bias', torch.Size([8]))

[个人猜测不一定对:weight是8*4的原因,输入是4个维度,每个维度就有4个权重。输出是8个维度了,要带着前面输入的维度的4个权重,所以就是8*4]

5.访问整个网络层的参数

print(*[(name, param.shape) for name, param in net.named_parameters()])

输出:【激活函数没有权重和偏置】

('0.weight', torch.Size([8, 4])) ('0.bias', torch.Size([8])) ('2.weight', torch.Size([1, 8])) ('2.bias', torch.Size([1]))

 

注意:*[]是解包。把列表拆成一个一个元素。

6.指定特征名称的值的数据

print(net.state_dict()['2.bias'].data)

输出:tensor([-0.2114])

7.从嵌套块里面收集参数

def block1():
    return nn.Sequential(nn.Linear(4, 8), nn.ReLU(),
                         nn.Linear(8, 4), nn.ReLU())

def block2():  # 用循环 加入4次block1
    net = nn.Sequential()
    for i in range(4):
        # 在这里嵌套
        net.add_module(f'block {i}', block1())  # Sequential()这样可以把字符串的名字传进去
    return net


rgnet = nn.Sequential(block2(), nn.Linear(4, 1))
rgnet(X)
print(rgnet)

查看一下网络结构

Sequential(
  (0): Sequential(
    (block 0): Sequential(
      (0): Linear(in_features=4, out_features=8, bias=True)
      (1): ReLU()
      (2): Linear(in_features=8, out_features=4, bias=True)
      (3): ReLU()
    )
    (block 1): Sequential(
      (0): Linear(in_features=4, out_features=8, bias=True)
      (1): ReLU()
      (2): Linear(in_features=8, out_features=4, bias=True)
      (3): ReLU()
    )
    (block 2): Sequential(
      (0): Linear(in_features=4, out_features=8, bias=True)
      (1): ReLU()
      (2): Linear(in_features=8, out_features=4, bias=True)
      (3): ReLU()
    )
    (block 3): Sequential(
      (0): Linear(in_features=4, out_features=8, bias=True)
      (1): ReLU()
      (2): Linear(in_features=8, out_features=4, bias=True)
      (3): ReLU()
    )
  )
  (1): Linear(in_features=4, out_features=1, bias=True)
)

8.内置初始化参数

①内置初始化权重正态分布

def init_normal(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, mean=0, std=0.01)
        nn.init.zeros_(m.bias)


net.apply(init_normal)  # 遍历整个net网络里的各个层 挨个调用init_normal函数进行修改
print(net[0].weight.data[0])
print(net[0].bias.data[0])
net.apply(init_normal) 的说明:遍历net的所有层,如果是Linear层,就进行权重和偏置的初始化修改。

输出:

tensor([-0.0020, -0.0105, -0.0021,  0.0196])
tensor(0.)

②内置函数把权重变为一个数(为了演示,算法角度不能做)

def init_constant(m):
    if type(m) == nn.Linear:
        nn.init.constant_(m.weight, 1)  # 权重全为1,变成一样的
        nn.init.zeros_(m.bias)


net.apply(init_constant)  # 遍历整个net网络里的各个层 挨个调用init_normal函数进行修改
print(net[0].weight.data[0])
print(net[0].bias.data[0])

输出:

 9.自定义初始化权重和偏置

net[0].weight.data[:] += 1  # 每个权重都加1
net[0].weight.data[0, 0] = 42  # 第一个权重变为42
print(net[0].weight.data[0])

 10.参数绑定

shared = nn.Linear(8, 8)  # 里面有权重了
net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(),
                    shared, nn.ReLU(),
                    shared, nn.ReLU(),
                    nn.Linear(8, 1))
net(X)
# 检查参数是否相同
print(net[2].weight.data[0] == net[4].weight.data[0])
net[2].weight.data[0, 0] = 100
# 确保它们实际上是同一个对象,而不只是有相同的值
print(net[2].weight.data[0] == net[4].weight.data[0])

 

shared在网络里是同一个内存 ,同一个对象。所以权重是一样的

你可能感兴趣的:(深度学习,人工智能,python)