PyTorch学习笔记(五) ---------最大池化和非线性激活

一、最大池化

类似于卷积操作,这里最大池化的过程与卷积有部分相似之处,不多赘述

最大池化是为了保留数据特征,减少数据量

class Module(nn.Module):
    def __init__(self):
        super(Module, self).__init__()  # 父类继承
        self.maxpool1 = MaxPool2d(kernel_size=3, ceil_mode=True)  # kernel_size=3表示池化核是3*3, ceil_mode=True表示是否保留前一步结果
    def forward(self, input):
        output = self.maxpool1(input)
        return output

这边是定义的最大池化操作的神经网络,各关键词意思已经写在注释中

二、非线性激活

主要是ReLU和Sigmoid

定义一个神经网络

class Module(nn.Module):
    def __init__(self):
        super(Module, self).__init__()
        self.relu1 = ReLU()
        self.sigmoid1 = Sigmoid()
    def forward(self, input):
        output = self.sigmoid1(input)
        return output

非线性激活是为了提高泛化能力

三、源码

# -*- coding = utf-8 -*-
import torch
from torch import nn
from torch.nn import Conv2d, ReLU, Sigmoid
from torch.utils.data import Dataset
import cv2
from PIL import Image  # 图像处理的库
import os

from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
from torch.utils.data import DataLoader
import torch
from torch import nn
from torch.nn import MaxPool2d
# 最大池化,保留数据特征,减少数据量
'''
input = torch.tensor([[1, 2, 0, 3, 1],
                      [0, 1, 2, 3, 1],
                      [1, 2, 1, 0, 0],
                      [5, 2, 3, 1, 1],
                      [2, 1, 0, 1, 1]], dtype=torch.float32)  # 类型转换
input = torch.reshape(input, (-1, 1, 5, 5))  # -1表示自动匹配batch_size,1表示通道数为1,图像尺寸为5*5
'''
class MyData(Dataset):
    def __init__(self, root_dir, label_dir, transform=None):  # 初始化类,为class提供全局变量
        self.transform = transform
        self.root_dir = root_dir  # 根文件位置
        self.label_dir = label_dir  # 子文件名
        self.path = os.path.join(self.root_dir, self.label_dir)  # 合并,即具体位置
        self.img_path = os.listdir(self.path)  # 转换成列表的形式

    def __getitem__(self, idx):  # 获取列表中每一个图片
        img_name = self.img_path[idx]  # idx表示下标,即对应位置
        img_item_path = os.path.join(self.root_dir, self.label_dir, img_name)  # 每一个图片的位置
        img = Image.open(img_item_path)  # 调用方法,拿到该图像
        img = img.convert("RGB")
        img = self.transform(img)
        label = self.label_dir  # 标签
        return img, label  # 返回img 图片 label 标签

    def __len__(self):  # 返回长度
        return len(self.img_path)
tensor_trans = transforms.Compose([transforms.ToTensor(), transforms.Resize([512, 512])])
root_dir = 'D://情绪图片'  # 根目录
happy_label_dir = '开心'  # 子目录
happy_dataset = MyData(root_dir, happy_label_dir, transform=tensor_trans)  # 开心数据集创建完成
test_loader = DataLoader(dataset=happy_dataset, batch_size=4, shuffle=True, num_workers=0, drop_last=False)
'''
class Module(nn.Module):
    def __init__(self):
        super(Module, self).__init__()  # 父类继承
        self.maxpool1 = MaxPool2d(kernel_size=3, ceil_mode=True)  # kernel_size=3表示池化核是3*3, ceil_mode=True表示是否保留前一步结果
    def forward(self, input):
        output = self.maxpool1(input)
        return output
'''
# 非线性激活,提高泛化能力
class Module(nn.Module):
    def __init__(self):
        super(Module, self).__init__()
        self.relu1 = ReLU()
        self.sigmoid1 = Sigmoid()
    def forward(self, input):
        output = self.sigmoid1(input)
        return output
sj = Module()
step = 0
writer = SummaryWriter('sj')
for data in test_loader:
    imgs, label = data
    output = sj(imgs)

    step = step + 1
    writer.add_images('input', imgs, step)
    #  output = torch.reshape(output, (-1, 3, 510, 510))  # 修改输出通道为3, 前面-1表示batch_size不变,后面是图像尺寸
    writer.add_images('output', output, step)
writer.close()

步骤其实大体上都是一样的

都是先自定义数据集载入,再按需求定义神经网络,最后在tensorboard中展示

其中最大池化的结果是类似于马赛克一样的图片(马赛克的基本原理其实是平均池化)

非线性激活的结果是让图片变暗,可以根据源码tensorboard一下

四、总结

从最初的对数据集,卷积,池化,非线性激活等一系列专有名词一无所知的情况下,到现在略知一二,个人认为对模型的直观认识是非常重要的。通过代码段来print,每一步去了解它的用意,进去了再加以思考,这是非常重要的

你可能感兴趣的:(PyTorch深度学习,pytorch,深度学习,机器学习)