CNN层探索

2019-08-02  本文已影响0人  钢笔先生

Time: 2019-08-02
视频链接:https://youtu.be/stWU37L91Yc?list=PLZbbT5o_s2xrfNyHZsM6ufI0iZENK9xgG

卷积层的参数

全连接层的参数

CNN权重

class Network():
  def __init__(self):
#     super(Network, self).__init__()
    # 将层定义为属性
    self.conv1 = nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5)
    self.conv2 = nn.Conv2d(in_channels=6, out_channels=12, kernel_size=5)
    
    self.fc1 = nn.Linear(in_features=12*4*4, out_features=120)
    self.fc2 = nn.Linear(in_features=120, out_features=60)
    self.out = nn.Linear(in_features=60, out_features=10)
    
  # 实现forward函数,即组装网络的过程
  def forward(self, t):
    # pass
    return t

不继承nn.Module的类,实例化后:

# 实例化网络
network = Network()
network
# <__main__.Network at 0x7febde19b668>

就是一个平平无奇的对象。

继承后:

class Network(nn.Module):
  def __init__(self):
    super(Network, self).__init__()
    # 将层定义为属性
    self.conv1 = nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5)
    self.conv2 = nn.Conv2d(in_channels=6, out_channels=12, kernel_size=5)
    
    self.fc1 = nn.Linear(in_features=12*4*4, out_features=120)
    self.fc2 = nn.Linear(in_features=120, out_features=60)
    self.out = nn.Linear(in_features=60, out_features=10)
    
  # 实现forward函数,即组装网络的过程
  def forward(self, t):
    # pass
    return t

实例化后:

network
'''
Network(
  (conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))
  (conv2): Conv2d(6, 12, kernel_size=(5, 5), stride=(1, 1))
  (fc1): Linear(in_features=192, out_features=120, bias=True)
  (fc2): Linear(in_features=120, out_features=60, bias=True)
  (out): Linear(in_features=60, out_features=10, bias=True)
)
'''

刚好今天复习到__repr__函数的实现,显然在nn.Module中实现了__repr__函数,这个可打印出关于对象的信息。

关于卷积层的权重问题思考

network.conv1.weight.shape
# torch.Size([6, 1, 5, 5])

就以这层作为例子好了,可以反映出卷积操作的全部问题。

鼓励的思考卷积操作,我们可以想到几个关键词:

但我个人觉得在思考CNN问题时,最重要的起点是:想到卷积核是3D张量,每一层的卷积核有多个,所以整体权重是个4D张量。每个卷积核对应着提取一种特征的权重。

卷积层的权重就是卷积核的权重。

另外不要混淆了卷积核输出的特征图的大小。

卷积操作是立体的,是和输入张量形状所匹配的。

这里,在定义卷积操作时,输入通道个数在前,输出通道个数在后,也即该层的卷积核的个数大小。

该层的权重的形状中,第一个轴的大小是本层的输出通道个数,这样方便我们取得单个卷积核的大小。

[6, 1, 5, 5]可以看作是6个卷积核,每个卷积核的形状是[1, 5, 5]。因为输入层就一层,所以这是个平面卷积核。

全连接层就是密集的矩阵乘法,是二维平面。

权重是个平面矩阵。

查看网络的参数

nn.Module中,网络中有个默认函数实现,parameters(),可以按照如下的方式调用:

# 获取所有参数
for param in network.parameters():
  print(param.shape)

'''
torch.Size([6, 1, 5, 5])
torch.Size([6])
torch.Size([12, 6, 5, 5])
torch.Size([12])
torch.Size([120, 192])
torch.Size([120])
torch.Size([60, 120])
torch.Size([60])
torch.Size([10, 60])
torch.Size([10])
'''

另外还可以获取命名参数:

for name, param in network.named_parameters():
  print(name, '\t\t', param.shape)

'''
conv1.weight         torch.Size([6, 1, 5, 5])
conv1.bias       torch.Size([6])
conv2.weight         torch.Size([12, 6, 5, 5])
conv2.bias       torch.Size([12])
fc1.weight       torch.Size([120, 192])
fc1.bias         torch.Size([120])
fc2.weight       torch.Size([60, 120])
fc2.bias         torch.Size([60])
out.weight       torch.Size([10, 60])
out.bias         torch.Size([10])
'''

这些都是可学习参数。

END.

上一篇 下一篇

猜你喜欢

热点阅读