资源简介

卷积网络架构-LeNet-5

资源截图

代码片段和文件信息

import torch
import random
import math
import numpy as np
import torch.nn as nn
import torch.nn.functional as F
from torchvision import datasets transforms
import matplotlib.pyplot as plt


class MyLinear(nn.Module):
    def __init__(self in_features out_features bias=True):
        super(MyLinear self).__init__()  # 和自定义模型一样,第一句话就是调用父类的构造函数
        self.in_features = in_features
        self.out_features = out_features
        # 参数定义
        self.weight = nn.Parameter(torch.Tensor(in_features out_features))  # 使用Parameter来定义
        if bias:
            self.bias = nn.Parameter(torch.Tensor(out_features))  # 使用Parameter来定义
        else:
            self.register_parameter(‘bias‘ None)
        # 参数初始化
        self.reset_parameters()

    def reset_parameters(self):
        stdv = 1. / math.sqrt(self.weight.size(1))
        self.weight.data.uniform_(-stdv stdv)
        if self.bias is not None:
            self.bias.data.uniform_(-stdv stdv)

    def forward(self x):
        y = x.mm(self.weight) + self.bias
        return y


class MyConv(nn.Module):
    def __init__(self in_channels out_channels kernel_size stride padding bias):
        super(MyConv self).__init__()

        self.in_channels self.out_channels = in_channels out_channels  # 输入通道数输出通道数
        self.kernel_size self.stride self.padding = kernel_size stride padding  # 卷积核的大小{k_W=k_H},卷积的步长; padding的大小
        self.bias_true = bias  # 偏置项 {Ture False}

        # 卷积核的数量(输出通道数),输入通道数,卷积核的大小:HW
        self.weight = nn.Parameter(torch.Tensor(out_channels in_channels kernel_size kernel_size))

        if self.bias_true == True:
            # 偏置项: 偏置项数量 = 卷积核的数量,所以需要out_channels个偏置参数
            self.bias = nn.Parameter(torch.Tensor(out_channels 1))

        else:
            self.register_parameter(‘bias‘ None)
        # 参数初始化
        self.reset_parameters()

    def forward(self x):
        # Padding 补0操作   在x 左右上下 分别填充self.padding个0
        ZeroPad = nn.ZeroPad2d(padding=(self.padding self.padding self.padding self.padding))
        x = ZeroPad(x)  # Padding 操作

        conv_x = self.conv_compute(x)  # 卷积操作

        return conv_x

    def conv_compute(self x):

        # x:  padding 后的 data
        (batch in_c H W) = x.shape  # 图片的batchsiez,通道数,高,宽

        (out_c in_c kernel_size_H kernel_size_W) = self.weight.shape  # 卷积核的数量,通道数 卷积核的大小:HW

        new_H = int(1 + (H - kernel_size_H) / self.stride)  # 卷积后得到的图片高
        new_W = int(1 + (W - kernel_size_W) / self.stride)  # 卷积后得到的图片宽

        x_unfold = F.unfold(x (kernel_size_H kernel_size_W)
                            stride=self.stride)  # x_unfold:(batch in_c*k_H*k_W L)    L: (new_H*new_W)
        w = self.weight

        #  1. (batch L in_c*k_H*k_W) matmul (in_c*k_H*k_Wout_c)-->  (batch L out_c)
        #  2. out_unf: (batch L out_c)--> (batch out_c L)
        out_unf = x_unfold.transpose(1 2).m

评论

共有 条评论