卷积和CNN

                   简单卷积公式

               简单卷积公式 

                                      卷积公式

                                  卷积公式 

如何理解卷积神经网络(CNN)中的卷积和池化?

                                     卷积和池化概念的介绍

An Intuitive Explanation of Convolutional Neural Networks

                                   讲得更深的卷积池化介绍

用Pytorch搭建CNN

使用Pytorch搭建CNN_羊城迷鹿的博客-CSDN博客

                                    流程介绍外加代码实例(核心流程)

以下是上面核心流程的Comment

1.卷积核的搭建

卷积核(kernel)和过滤器(filter)的区别_Medlen-CSDN博客_卷积核和过滤器是一样的吗

                        卷积核(kernel)和过滤器(filter)的区别
import numpy as np

def convolution(img, kernel, padding=1, stride=1):
    """
    img: input image with one channel
    kernel: convolution kernel
    """

    h, w = img.shape
    kernel_size = kernel.shape[0]

    # 获取扩增之后的图像
    ph, pw = h + 2 * padding, w + 2 * padding
    padding_img = np.zeros((ph, pw))
    padding_img[padding:h + padding, padding:w + padding] = img

    # 获取经过卷积之后的完整图像
    result_h = (h + 2 * padding - kernel_size) // stride + 1
    result_w = (w + 2 * padding - kernel_size) // stride + 1

    result = np.zeros((result_h, result_w))

    # 进行卷积运算
    x, y = 0, 0
    for i in range(0, ph - kernel_size + 1, stride):
        for j in range(0, pw - kernel_size + 1, stride):
            roi = padding_img[i:i + kernel_size, j:j + kernel_size]
            result[x, y] = np.sum(roi * kernel)
            y += 1
        y = 0
        x += 1
    return result
def myconv2d(features, weights, padding=0, stride=1):
    """
    features: input, in_channel * h * w
    weights: kernel, out_channel * in_channel * kernel_size * kernel_size
    return output with out_channel
    """
    in_channel, h, w = features.shape
    out_channel, _, kernel_size, _ = weights.shape

    # height and width of output image
    output_h = (h + 2 * padding - kernel_size) // stride + 1
    output_w = (w + 2 * padding - kernel_size) // stride + 1
    output = np.zeros((out_channel, output_h, output_w))

    # call convolution out_channel * in_channel times
    for i in range(out_channel):
        weight = weights[i]
        for j in range(in_channel):
            feature_map = features[j]
            kernel = weight[j]
            output[i] += convolution(feature_map, kernel, padding, stride)
    return output

Python numpy函数:shape用法_Daisy_HJL的博客-CSDN博客

Shape的用法

import torch
import torch.nn.functional as F
input_tensor = torch.tensor(input_data).unsqueeze(0).float()

F.conv2d(input_tensor, weight=torch.tensor(weights_data).float(), bias=None, stride=3, padding=3)
def convolutionV2(img, kernel, padding=(0,0), stride=(1,1)):    
    h, w = img.shape
    kh, kw = kernel.shape
    
    # height and width of image with padding 
    ph, pw = h + 2 * padding[0], w + 2 * padding[1]
    padding_img = np.zeros((ph, pw))
    padding_img[padding[0]:int(h + padding[0]), padding[1]:int(w + padding[1])] = img
    
    # height and width of output image
    result_h = (h + 2 * padding[0] - kh) // stride[0] + 1
    result_w = (w + 2 * padding[1] - kw) // stride[1] + 1
    
    result = np.zeros((result_h, result_w))
    
    # convolution
    x, y = 0, 0
    for i in range(0, ph - kh + 1, stride[0]):
        for j in range(0, pw - kw + 1, stride[1]):
            roi = padding_img[i:i+kh, j:j+kw]
            result[x, y] = np.sum(roi * kernel)
            y += 1
        y = 0
        x += 1
    return result

Python int() 函数

import torch
import torch.nn as nn

x = torch.randn(1, 1, 32, 32)

conv_layer = nn.Conv2d(in_channels=1, out_channels=3, kernel_size=3, stride=1, padding=0)
y = conv_layer(x)
print(x.shape)
print(y.shape)

Week 9 Note

  1. in_channels=C, out_channels=Cout, kernel_size=k, stride=s, padding=p,那么输出的tensor size是多少?