[十四]深度学习Pytorch-池化层、线性层、激活函数层

0. 往期内容

[一]深度学习Pytorch-张量定义与张量创建

[二]深度学习Pytorch-张量的操作:拼接、切分、索引和变换

[三]深度学习Pytorch-张量数学运算

[四]深度学习Pytorch-线性回归

[五]深度学习Pytorch-计算图与动态图机制

[六]深度学习Pytorch-autograd与逻辑回归

[七]深度学习Pytorch-DataLoader与Dataset(含人民币二分类实战)

[八]深度学习Pytorch-图像预处理transforms

[九]深度学习Pytorch-transforms图像增强(剪裁、翻转、旋转)

[十]深度学习Pytorch-transforms图像操作及自定义方法

[十一]深度学习Pytorch-模型创建与nn.Module

[十二]深度学习Pytorch-模型容器与AlexNet构建

[十三]深度学习Pytorch-卷积层(1D/2D/3D卷积、卷积nn.Conv2d、转置卷积nn.ConvTranspose)

[十四]深度学习Pytorch-池化层、线性层、激活函数层

深度学习Pytorch-池化层、线性层、激活函数层

  • 0. 往期内容
  • 1. 池化层 Pooling Layer
    • 1.1 池化层定义
    • 1.2 nn.MaxPool2d(kernel_size, padding=0, dilation=1)
    • 1.3 nn.AvgPool2d(kernel_size, padding=0)
    • 1.4 nn.MaxUnpool2d(kernel_size, padding=0)
  • 2. 线性层(全连接层)
    • 2.1 线性层定义
    • 2.2 nn.Linear(in_features, out_features, bias=True)
  • 3. 激活函数
    • 3.1 激活函数定义
    • 3.2 nn.Sigmoid()
    • 3.3 nn.Tanh()
    • 3.4 nn.ReLU()
    • 3.5 nn.LeakyReLU(negative_slope=0.01, inplace=False)
    • 3.5 nn.PReLU(num_parameters=1, init=0.25, device=None, dtype=None)
    • 3.6 nn.RReLU(lower=0.125, upper=0.3333333333333333, inplace=False)
  • 4. 完整代码

negative infinity 负无穷大;
implicit zero padding 隐式零填充;

1. 池化层 Pooling Layer

1.1 池化层定义

[十四]深度学习Pytorch-池化层、线性层、激活函数层_第1张图片

1.2 nn.MaxPool2d(kernel_size, padding=0, dilation=1)

nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)

同卷积类似,看池化的窗口在几个维度上滑动便是几维池化。
(1)功能:对二维信号进行最大值池化;
(2)参数
kernel_size: 池化核的尺寸;
stride: 步长,stride步长是滑动时滑动几个像素;
padding: 填充个数,保证输入和输出图像在尺寸上是匹配的;
dilation: 空洞卷积的大小;
ceil_mode:尺寸取整,ceil_mode设置为True则为尺寸向上取整,默认为False即尺寸向下取整;
return_indices:记录最大值像素所在的位置的索引,通常用于最大值反池化上采样时使用;
[十四]深度学习Pytorch-池化层、线性层、激活函数层_第2张图片[十四]深度学习Pytorch-池化层、线性层、激活函数层_第3张图片

(3)代码示例

set_seed(1)  # 设置随机种子

# ================================= load img ==================================
path_img = os.path.join(os.path.dirname(os.path.abspath(__file__)), "lena.png")
img = Image.open(path_img).convert('RGB')  # 0~255

# convert to tensor
#c:通道,h:高,w:宽
img_transform = transforms.Compose([transforms.ToTensor()])
img_tensor = img_transform(img)
img_tensor.unsqueeze_(dim=0)    # C*H*W to B*C*H*W

# ================================= create convolution layer ==================================

# ================ maxpool
flag = 1
if flag:
    #stride步长通常与池化窗口大小2*2一致,保证池化时不会发生重叠
    maxpool_layer = nn.MaxPool2d((2, 2), stride=(2, 2))  
    img_pool = maxpool_layer(img_tensor)

# ================================= visualization ==================================
print("池化前尺寸:{}\n池化后尺寸:{}".format(img_tensor.shape, img_pool.shape))
img_pool = transform_invert(img_pool[0, 0:3, ...], img_transform)
img_raw = transform_invert(img_tensor.squeeze(), img_transform)
plt.subplot(122).imshow(img_pool)
plt.subplot(121).imshow(img_raw)
plt.show()

[十四]深度学习Pytorch-池化层、线性层、激活函数层_第4张图片
池化后照片没有啥区别,池化常用于冗余信息的剔除并减少计算量。

在这里插入图片描述

1.3 nn.AvgPool2d(kernel_size, padding=0)

nn.AvgPool2d(kernel_size, stride=None, padding=0, ceil_mode=False, count_include_pad=True, divisor_override=None)

(1)功能:对二维信号(图像)进行平均值池化;
(2)参数
kernel_size: 池化核的尺寸;
stride: 步长,stride步长是滑动时滑动几个像素;
padding: 填充个数,保证输入和输出图像在尺寸上是匹配的;
ceil_mode:尺寸取整,ceil_mode设置为True则为尺寸向上取整,默认为False即尺寸向下取整;
count_include_pad:填充值是否用于计算;
divisor_override:除法因子,此时计算平均值时分母为divisor_override

[十四]深度学习Pytorch-池化层、线性层、激活函数层_第5张图片
(3)代码示例
avgpool

set_seed(1)  # 设置随机种子

# ================================= load img ==================================
path_img = os.path.join(os.path.dirname(os.path.abspath(__file__)), "lena.png")
img = Image.open(path_img).convert('RGB')  # 0~255

# convert to tensor
#c:通道,h:高,w:宽
img_transform = transforms.Compose([transforms.ToTensor()])
img_tensor = img_transform(img)
img_tensor.unsqueeze_(dim=0)    # C*H*W to B*C*H*W

# ================================= create convolution layer ==================================

# ================ avgpool
flag = 1
if flag:
    avgpoollayer = nn.AvgPool2d((2, 2), stride=(2, 2))   
    img_pool = avgpoollayer(img_tensor)

# ================================= visualization ==================================
print("池化前尺寸:{}\n池化后尺寸:{}".format(img_tensor.shape, img_pool.shape))
img_pool = transform_invert(img_pool[0, 0:3, ...], img_transform)
img_raw = transform_invert(img_tensor.squeeze(), img_transform)
plt.subplot(122).imshow(img_pool)
plt.subplot(121).imshow(img_raw)
plt.show()

[十四]深度学习Pytorch-池化层、线性层、激活函数层_第6张图片
平均值池化的图像相较于最大值池化的图像较暗淡,因为像素值较小,最大值池化图像取得是最大值,平均值池化图像取得是平均值。

在这里插入图片描述

avgpool_divisor_override

set_seed(1)  # 设置随机种子

# ================================= load img ==================================
path_img = os.path.join(os.path.dirname(os.path.abspath(__file__)), "lena.png")
img = Image.open(path_img).convert('RGB')  # 0~255

# convert to tensor
#c:通道,h:高,w:宽
img_transform = transforms.Compose([transforms.ToTensor()])
img_tensor = img_transform(img)
img_tensor.unsqueeze_(dim=0)    # C*H*W to B*C*H*W

# ================================= create convolution layer ==================================
# ================ avgpool divisor_override
flag = 1
if flag:
    img_tensor = torch.ones((1, 1, 4, 4))#创建1*1*4*4,代表B*C*H*W, B是batchsize
    avgpool_layer = nn.AvgPool2d((2, 2), stride=(2, 2))
    img_pool = avgpool_layer(img_tensor) #输出1*1*2*2,因为(1+1+1+1)/4=1

    avgpool_layer = nn.AvgPool2d((2, 2), stride=(2, 2), divisor_override=3)
    img_pool = avgpool_layer(img_tensor) #输出1*1*1.3333*1.3333,因为(1+1+1+1)/3=1.3333

    print("raw_img:\n{}\npooling_img:\n{}".format(img_tensor, img_pool))

[十四]深度学习Pytorch-池化层、线性层、激活函数层_第7张图片
[十四]深度学习Pytorch-池化层、线性层、激活函数层_第8张图片

1.4 nn.MaxUnpool2d(kernel_size, padding=0)

nn.MaxUnpool2d(kernel_size, stride=None, padding=0)

(1)功能:对二维信号(图像)进行最大值池化上采样;
(2)参数
kernel_size: 池化核的尺寸;
stride: 步长,stride步长是滑动时滑动几个像素;
padding: 填充个数,保证输入和输出图像在尺寸上是匹配的;
[十四]深度学习Pytorch-池化层、线性层、激活函数层_第9张图片
(3)代码示例
test.py

set_seed(1)  # 设置随机种子

# ================================= load img ==================================
path_img = os.path.join(os.path.dirname(os.path.abspath(__file__)), "lena.png")
img = Image.open(path_img).convert('RGB')  # 0~255

# convert to tensor
#c:通道,h:高,w:宽
img_transform = transforms.Compose([transforms.ToTensor()])
img_tensor = img_transform(img)
img_tensor.unsqueeze_(dim=0)    # C*H*W to B*C*H*W

# ================================= create convolution layer ==================================

# ================ max unpool
flag = 1
if flag:
    # pooling
    img_tensor = torch.randint(high=5, size=(1, 1, 4, 4), dtype=torch.float) #生成尺寸为1*1*4*4的整数[0, 5)均匀分布
    maxpool_layer = nn.MaxPool2d((2, 2), stride=(2, 2), return_indices=True)
    img_pool, indices = maxpool_layer(img_tensor) #记录最大像素值的索引

    # unpooling
    #创建反池化层的输入,输入的尺寸与图片池化后的尺寸一致。
    img_reconstruct = torch.randn_like(img_pool, dtype=torch.float) #标准正态分布
    #构建反池化层(窗口、步长参数与池化层参数一一对应相等)
    maxunpool_layer = nn.MaxUnpool2d((2, 2), stride=(2, 2))
    #生成反池化后的图像
    img_unpool = maxunpool_layer(img_reconstruct, indices)

    print("raw_img:\n{}\nimg_pool:\n{}".format(img_tensor, img_pool))
    print("img_reconstruct:\n{}\nimg_unpool:\n{}".format(img_reconstruct, img_unpool))

[十四]深度学习Pytorch-池化层、线性层、激活函数层_第10张图片
official_test

>>> pool = nn.MaxPool2d(2, stride=2, return_indices=True)
>>> unpool = nn.MaxUnpool2d(2, stride=2)
>>> input = torch.tensor([[[[ 1.,  2.,  3.,  4.],
                            [ 5.,  6.,  7.,  8.],
                            [ 9., 10., 11., 12.],
                            [13., 14., 15., 16.]]]])
>>> output, indices = pool(input)
>>> unpool(output, indices)
tensor([[[[  0.,   0.,   0.,   0.],
          [  0.,   6.,   0.,   8.],
          [  0.,   0.,   0.,   0.],
          [  0.,  14.,   0.,  16.]]]])
>>> # Now using output_size to resolve an ambiguous size for the inverse
>>> input = torch.torch.tensor([[[[ 1.,  2.,  3., 4., 5.],
                                  [ 6.,  7.,  8., 9., 10.],
                                  [11., 12., 13., 14., 15.],
                                  [16., 17., 18., 19., 20.]]]])
>>> output, indices = pool(input)
>>> # This call will not work without specifying output_size
>>> unpool(output, indices, output_size=input.size())
tensor([[[[ 0.,  0.,  0.,  0.,  0.],
          [ 0.,  7.,  0.,  9.,  0.],
          [ 0.,  0.,  0.,  0.,  0.],
          [ 0., 17.,  0., 19.,  0.]]]])

2. 线性层(全连接层)

2.1 线性层定义

[十四]深度学习Pytorch-池化层、线性层、激活函数层_第11张图片
每个 上一层所有

2.2 nn.Linear(in_features, out_features, bias=True)

nn.Linear(in_features, out_features, bias=True, device=None, dtype=None)

(1)功能:对一维信号(向量)进行线性组合;
(2)参数
in_features: 输入节点数;
in_features: 输出节点数;
bias: 是否需要偏置,默认为True

在这里插入图片描述
(3)代码示例
[十四]深度学习Pytorch-池化层、线性层、激活函数层_第12张图片

test.py

# ================ linear
flag = 1
if flag:
    inputs = torch.tensor([[1., 2, 3]]) #1*3
    linear_layer = nn.Linear(3, 4) #输入节点3个,输出节点4个
    #w权值矩阵为4*3,每一行代表一个神经元与上一层神经元连接的权值。
    linear_layer.weight.data = torch.tensor([[1., 1., 1.],
                                             [2., 2., 2.],
                                             [3., 3., 3.],
                                             [4., 4., 4.]])

    linear_layer.bias.data.fill_(0.5)
    output = linear_layer(inputs)
    print(inputs, inputs.shape)
    print(linear_layer.weight.data, linear_layer.weight.data.shape)
    #output=inputs*w^T+bias
    print(output, output.shape) #输出的尺寸为1*4

official_test

>>> m = nn.Linear(20, 30)
>>> input = torch.randn(128, 20)
>>> output = m(input)
>>> print(output.size())
torch.Size([128, 30])

3. 激活函数

3.1 激活函数定义

[十四]深度学习Pytorch-池化层、线性层、激活函数层_第13张图片

3.2 nn.Sigmoid()

[十四]深度学习Pytorch-池化层、线性层、激活函数层_第14张图片
(1)多个网络层叠加后,导数范围会变得更小,甚至消失。
(2)输出不是0均值分布,破坏了数据分布。

代码示例

>>> m = nn.Sigmoid()
>>> input = torch.randn(2)
>>> output = m(input)

3.3 nn.Tanh()

[十四]深度学习Pytorch-池化层、线性层、激活函数层_第15张图片
多个网络层叠加后,导数范围会变得更小,甚至消失。

代码示例

>>> m = nn.Tanh()
>>> input = torch.randn(2)
>>> output = m(input)

3.4 nn.ReLU()

[十四]深度学习Pytorch-池化层、线性层、激活函数层_第16张图片
(1)ReLU=修正线性单元;
(2)死神经元:导数为0,没有输出。
(3)多个网络层叠加后,导数一直是1,不会使梯度下降,有可能梯度越来越大,引发梯度爆炸。

代码示例

  >>> m = nn.ReLU()
  >>> input = torch.randn(2)
  >>> output = m(input)

3.5 nn.LeakyReLU(negative_slope=0.01, inplace=False)

[十四]深度学习Pytorch-池化层、线性层、激活函数层_第17张图片

LeakyReLU:负半轴0.01的斜率.

代码示例

>>> m = nn.LeakyReLU(0.1)
>>> input = torch.randn(2)
>>> output = m(input)

3.5 nn.PReLU(num_parameters=1, init=0.25, device=None, dtype=None)

[十四]深度学习Pytorch-池化层、线性层、激活函数层_第18张图片
[十四]深度学习Pytorch-池化层、线性层、激活函数层_第19张图片

PReLU:斜率是可学习的.

代码示例

>>> m = nn.PReLU()
>>> input = torch.randn(2)
>>> output = m(input)

3.6 nn.RReLU(lower=0.125, upper=0.3333333333333333, inplace=False)

[十四]深度学习Pytorch-池化层、线性层、激活函数层_第20张图片
RReLU:斜率是随机的,均匀分布.

在这里插入图片描述
代码示例

>>> m = nn.RReLU(0.1, 0.3)
>>> input = torch.randn(2)
>>> output = m(input)

4. 完整代码

# -*- coding: utf-8 -*-
"""
# @file name  : nn_layers_others.py
# @brief      : 其它网络层
"""
import os
import torch
import random
import numpy as np
import torchvision
import torch.nn as nn
from torchvision import transforms
from matplotlib import pyplot as plt
from PIL import Image
from tools.common_tools import transform_invert, set_seed

set_seed(1)  # 设置随机种子

# ================================= load img ==================================
path_img = os.path.join(os.path.dirname(os.path.abspath(__file__)), "lena.png")
img = Image.open(path_img).convert('RGB')  # 0~255

# convert to tensor
#c:通道,h:高,w:宽
img_transform = transforms.Compose([transforms.ToTensor()])
img_tensor = img_transform(img)
img_tensor.unsqueeze_(dim=0)    # C*H*W to B*C*H*W

# ================================= create convolution layer ==================================

# ================ maxpool
# flag = 1
flag = 0
if flag:
    #stride步长通常与池化窗口大小2*2一致,保证池化时不会发生重叠
    maxpool_layer = nn.MaxPool2d((2, 2), stride=(2, 2))  
    img_pool = maxpool_layer(img_tensor)

# ================ avgpool
# flag = 1
flag = 0
if flag:
    avgpoollayer = nn.AvgPool2d((2, 2), stride=(2, 2))   
    img_pool = avgpoollayer(img_tensor)

# ================ avgpool divisor_override
# flag = 1
flag = 0
if flag:
    img_tensor = torch.ones((1, 1, 4, 4))#创建1*1*4*4,代表B*C*H*W, B是batchsize
    avgpool_layer = nn.AvgPool2d((2, 2), stride=(2, 2))
    img_pool = avgpool_layer(img_tensor) #输出1*1*2*2,因为(1+1+1+1)/4=1

    avgpool_layer = nn.AvgPool2d((2, 2), stride=(2, 2), divisor_override=3)
    img_pool = avgpool_layer(img_tensor) #输出1*1*1.3333*1.3333,因为(1+1+1+1)/3=1.3333

    print("raw_img:\n{}\npooling_img:\n{}".format(img_tensor, img_pool))


# ================ max unpool
# flag = 1
flag = 0
if flag:
    # pooling
    img_tensor = torch.randint(high=5, size=(1, 1, 4, 4), dtype=torch.float) #生成尺寸为1*1*4*4的整数[0, 5)均匀分布
    maxpool_layer = nn.MaxPool2d((2, 2), stride=(2, 2), return_indices=True)
    img_pool, indices = maxpool_layer(img_tensor) #记录最大像素值的索引

    # unpooling
    #创建反池化层的输入,输入的尺寸与图片池化后的尺寸一致。
    img_reconstruct = torch.randn_like(img_pool, dtype=torch.float) #标准正态分布
    #构建反池化层(窗口、步长参数与池化层参数一一对应相等)
    maxunpool_layer = nn.MaxUnpool2d((2, 2), stride=(2, 2))
    #生成反池化后的图像
    img_unpool = maxunpool_layer(img_reconstruct, indices)

    print("raw_img:\n{}\nimg_pool:\n{}".format(img_tensor, img_pool))
    print("img_reconstruct:\n{}\nimg_unpool:\n{}".format(img_reconstruct, img_unpool))


# ================ linear
flag = 1
# flag = 0
if flag:
    inputs = torch.tensor([[1., 2, 3]]) #1*3
    linear_layer = nn.Linear(3, 4) #输入节点3个,输出节点4个
    #w权值矩阵为4*3,每一行代表一个神经元与上一层神经元连接的权值。
    linear_layer.weight.data = torch.tensor([[1., 1., 1.],
                                             [2., 2., 2.],
                                             [3., 3., 3.],
                                             [4., 4., 4.]])

    linear_layer.bias.data.fill_(0.5)
    output = linear_layer(inputs)
    print(inputs, inputs.shape)
    print(linear_layer.weight.data, linear_layer.weight.data.shape)
    #output=inputs*w^T+bias
    print(output, output.shape) #输出的尺寸为1*4


# ================================= visualization ==================================
print("池化前尺寸:{}\n池化后尺寸:{}".format(img_tensor.shape, img_pool.shape))
img_pool = transform_invert(img_pool[0, 0:3, ...], img_transform)
img_raw = transform_invert(img_tensor.squeeze(), img_transform)
plt.subplot(122).imshow(img_pool)
plt.subplot(121).imshow(img_raw)
plt.show()

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