计算机视觉入门 4)滑动窗口

news2025/1/11 22:39:23

系列文章目录

  1. 计算机视觉入门 1)卷积分类器
  2. 计算机视觉入门 2)卷积和ReLU
  3. 计算机视觉入门 3)最大池化
  4. 计算机视觉入门 4)滑动窗口
  5. 计算机视觉入门 5)自定义卷积网络
  6. 计算机视觉入门 6) 数据集增强(Data Augmentation)

提示:仅为个人学习笔记分享,若有错漏请各位老师同学指出,Thanks♪(・ω・)ノ


目录

  • 系列文章目录
  • 一、滑动窗口 The Sliding Window
    • 步幅(stride)
    • 填充(Padding)
  • 二、【代码示例】
    • 步骤1:导入包、函数封装
    • 步骤2:定义核函数
    • 步骤3:结果对比


一、滑动窗口 The Sliding Window

在前几个文章中,介绍了图像特征提取的三个操作:

  1. 使用卷积层进行_filter_操作。
  2. 使用ReLU激活函数进行_detect_操作。
  3. 使用最大池化层进行_condense_操作。

卷积和池化操作共享一个共同特征:它们都是在一个滑动窗口上执行的。对于卷积来说,这个“窗口”由内核的尺寸参数kernel_size确定。对于池化来说,它是池化窗口,由pool_size给出。

一个二维滑动窗口。

还有两个影响卷积和池化层的额外参数——这些是窗口的strides和是否在图像边缘使用padding

  • strides参数表示窗口在每一步移动多远,
  • padding参数描述了我们如何处理输入图像边缘的像素。

使用这两个参数,定义这两个层如下:

from tensorflow import keras
from tensorflow.keras import layers

model = keras.Sequential([
    layers.Conv2D(filters=64,
                  kernel_size=3,
                  strides=1,
                  padding='same',
                  activation='relu'),
    layers.MaxPool2D(pool_size=2,
                     strides=1,
                     padding='same')
    # ……
])

步幅(stride)

每次移动窗口的距离称为步幅(stride)。我们需要在图像的两个维度上指定步幅:一个用于从左到右移动,一个用于从上到下移动。以下动画展示了strides=(2, 2),每次步幅移动2个像素。

步幅为 (2, 2) 的滑动窗口。

步幅有什么影响?当任一方向的步幅大于1时,滑动窗口在每一步都会跳过输入中的一些像素。

因为我们希望获得用于分类的高质量特征,卷积层通常会设置为strides=(1, 1)。增加步幅意味着我们会错过汇总中的潜在有价值的信息。然而,最大池化层的步幅几乎总是大于1的值,如(2, 2)(3, 3),但不会超过窗口本身的大小。

最后,需要注意的是,当strides的值在两个方向上相同时,只需设置一个数字;例如,可以使用strides=2来代替strides=(2, 2)进行参数设置。

填充(Padding)

在执行滑动窗口计算时,会遇到一个问题,即在输入的边界上应该如何处理。如果完全保持窗口在输入图像内部,那么窗口将永远不会像处理其他像素那样准确地位于边界像素上。由于我们不是对所有像素完全相同地进行处理,因此可能会出现问题。

卷积对这些边界值的处理由其padding参数确定。在 TensorFlow 中,您有两个选择:padding='same'padding='valid'。这两种方式都有各自的利弊:

  1. 当设置为padding='valid'时,卷积窗口将完全位于输入内部。缺点是输出会减小(丢失像素),对于更大的卷积核,输出会减小得更多。这会限制网络可以包含的层数,特别是在输入尺寸较小的情况下。

  2. 另一种选择是使用padding='same'。这里的关键是在输入的边界周围使用0进行填充,只需使用足够的0来使输出的尺寸与输入的尺寸相同。然而,这可能会削弱边界像素的影响。下面的动画展示了使用'same'填充的滑动窗口。

Illustration of zero (same) padding.

二、【代码示例】

步骤1:导入包、函数封装

import tensorflow as tf
import matplotlib.pyplot as plt
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
from itertools import product
from skimage import draw, transform

def circle(size, val=None, r_shrink=0):
    circle = np.zeros([size[0]+1, size[1]+1])
    rr, cc = draw.circle_perimeter(
        size[0]//2, size[1]//2,
        radius=size[0]//2 - r_shrink,
        shape=[size[0]+1, size[1]+1],
    )
    if val is None:
        circle[rr, cc] = np.random.uniform(size=circle.shape)[rr, cc]
    else:
        circle[rr, cc] = val
    circle = transform.resize(circle, size, order=0)
    return circle

def show_kernel(kernel, label=True, digits=None, text_size=28):
    # Format kernel
    kernel = np.array(kernel)
    if digits is not None:
        kernel = kernel.round(digits)

    # Plot kernel
    cmap = plt.get_cmap('Blues_r')
    plt.imshow(kernel, cmap=cmap)
    rows, cols = kernel.shape
    thresh = (kernel.max()+kernel.min())/2
    # Optionally, add value labels
    if label:
        for i, j in product(range(rows), range(cols)):
            val = kernel[i, j]
            color = cmap(0) if val > thresh else cmap(255)
            plt.text(j, i, val, 
                     color=color, size=text_size,
                     horizontalalignment='center', verticalalignment='center')
    plt.xticks([])
    plt.yticks([])


def show_extraction(image,
                    kernel,
                    conv_stride=1,
                    conv_padding='valid',
                    activation='relu',
                    pool_size=2,
                    pool_stride=2,
                    pool_padding='same',
                    figsize=(10, 10),
                    subplot_shape=(2, 2),
                    ops=['Input', 'Filter', 'Detect', 'Condense'],
                    gamma=1.0):
    # Create Layers
    model = tf.keras.Sequential([
                    tf.keras.layers.Conv2D(
                        filters=1,
                        kernel_size=kernel.shape,
                        strides=conv_stride,
                        padding=conv_padding,
                        use_bias=False,
                        input_shape=image.shape,
                    ),
                    tf.keras.layers.Activation(activation),
                    tf.keras.layers.MaxPool2D(
                        pool_size=pool_size,
                        strides=pool_stride,
                        padding=pool_padding,
                    ),
                   ])

    layer_filter, layer_detect, layer_condense = model.layers
    kernel = tf.reshape(kernel, [*kernel.shape, 1, 1])
    layer_filter.set_weights([kernel])

    # Format for TF
    image = tf.expand_dims(image, axis=0)
    image = tf.image.convert_image_dtype(image, dtype=tf.float32) 
    
    # Extract Feature
    image_filter = layer_filter(image)
    image_detect = layer_detect(image_filter)
    image_condense = layer_condense(image_detect)
    
    images = {}
    if 'Input' in ops:
        images.update({'Input': (image, 1.0)})
    if 'Filter' in ops:
        images.update({'Filter': (image_filter, 1.0)})
    if 'Detect' in ops:
        images.update({'Detect': (image_detect, gamma)})
    if 'Condense' in ops:
        images.update({'Condense': (image_condense, gamma)})
    
    # Plot
    plt.figure(figsize=figsize)
    for i, title in enumerate(ops):
        image, gamma = images[title]
        plt.subplot(*subplot_shape, i+1)
        plt.imshow(tf.image.adjust_gamma(tf.squeeze(image), gamma))
        plt.axis('off')
        plt.title(title)

步骤2:定义核函数

import tensorflow as tf
import matplotlib.pyplot as plt
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
from itertools import product
from skimage import draw, transform

def circle(size, val=None, r_shrink=0):
    circle = np.zeros([size[0]+1, size[1]+1])
    rr, cc = draw.circle_perimeter(
        size[0]//2, size[1]//2,
        radius=size[0]//2 - r_shrink,
        shape=[size[0]+1, size[1]+1],
    )
    if val is None:
        circle[rr, cc] = np.random.uniform(size=circle.shape)[rr, cc]
    else:
        circle[rr, cc] = val
    circle = transform.resize(circle, size, order=0)
    return circle

def show_kernel(kernel, label=True, digits=None, text_size=28):
    # Format kernel
    kernel = np.array(kernel)
    if digits is not None:
        kernel = kernel.round(digits)

    # Plot kernel
    cmap = plt.get_cmap('Blues_r')
    plt.imshow(kernel, cmap=cmap)
    rows, cols = kernel.shape
    thresh = (kernel.max()+kernel.min())/2
    # Optionally, add value labels
    if label:
        for i, j in product(range(rows), range(cols)):
            val = kernel[i, j]
            color = cmap(0) if val > thresh else cmap(255)
            plt.text(j, i, val, 
                     color=color, size=text_size,
                     horizontalalignment='center', verticalalignment='center')
    plt.xticks([])
    plt.yticks([])


def show_extraction(image,
                    kernel,
                    conv_stride=1,
                    conv_padding='valid',
                    activation='relu',
                    pool_size=2,
                    pool_stride=2,
                    pool_padding='same',
                    figsize=(10, 10),
                    subplot_shape=(2, 2),
                    ops=['Input', 'Filter', 'Detect', 'Condense'],
                    gamma=1.0):
    # Create Layers
    model = tf.keras.Sequential([
                    tf.keras.layers.Conv2D(
                        filters=1,
                        kernel_size=kernel.shape,
                        strides=conv_stride,
                        padding=conv_padding,
                        use_bias=False,
                        input_shape=image.shape,
                    ),
                    tf.keras.layers.Activation(activation),
                    tf.keras.layers.MaxPool2D(
                        pool_size=pool_size,
                        strides=pool_stride,
                        padding=pool_padding,
                    ),
                   ])

    layer_filter, layer_detect, layer_condense = model.layers
    kernel = tf.reshape(kernel, [*kernel.shape, 1, 1])
    layer_filter.set_weights([kernel])

    # Format for TF
    image = tf.expand_dims(image, axis=0)
    image = tf.image.convert_image_dtype(image, dtype=tf.float32) 
    
    # Extract Feature
    image_filter = layer_filter(image)
    image_detect = layer_detect(image_filter)
    image_condense = layer_condense(image_detect)
    
    images = {}
    if 'Input' in ops:
        images.update({'Input': (image, 1.0)})
    if 'Filter' in ops:
        images.update({'Filter': (image_filter, 1.0)})
    if 'Detect' in ops:
        images.update({'Detect': (image_detect, gamma)})
    if 'Condense' in ops:
        images.update({'Condense': (image_condense, gamma)})
    
    # Plot
    plt.figure(figsize=figsize)
    for i, title in enumerate(ops):
        image, gamma = images[title]
        plt.subplot(*subplot_shape, i+1)
        plt.imshow(tf.image.adjust_gamma(tf.squeeze(image), gamma))
        plt.axis('off')
        plt.title(title)

在这里插入图片描述

步骤3:结果对比

show_extraction(
    image, kernel,
    
    conv_stride=1,
    pool_size=2,
    pool_stride=2,

    subplot_shape=(1, 4),
    figsize=(14, 6),
)

在这里插入图片描述

show_extraction(
    image, kernel,

    conv_stride=3, # 修改为3 
    pool_size=2,
    pool_stride=2,

    subplot_shape=(1, 4),
    figsize=(14, 6),
)

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/917747.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WoShop跨境电商系统开发:打造全球畅销产品

随着全球贸易的发展,跨境电商成为了许多企业拓展市场、增加盈利的重要途径。而要在跨境电商领域取得成功,开发一个高效、稳定的跨境电商系统是至关重要的。本文将为您详细介绍跨境电商系统开发,以及打造全球畅销产品的关键要素和方法。 一、…

H5页面跳转到公众号关注页面

效果展示: 未关注展示关注;已关注展示发消息 实现步骤: 登录微信公众平台 : https://mp.weixin.qq.com/鼠标右键选择查看网页源代码,找到uin_base64值如果没有uin_base64,那就找到uin进行base64编码编码地…

在使用springer模板的时候,引用书 book时候,末尾的引文地方出现问号???

文章目录 背景解决办法 背景 其实springer有很多模板的,比如nature系列有一个模板,计算机系列有一个模板,计算机系列的模板引用参考文献时好像不会出现标题的问题,我是使用nature系列模板出现这个问题的,如下&#xf…

Linux网络服务 七:iptables防火墙工具

文章目录 1.防火墙简介1.1 什么是防火墙1.2 Netfilter1.3 firewalld和iptables 2. iptables工具简述2.1 iptables的定义2.2 三种报文流向2.3iptables的表和链2.3.1**四表** ----规则表2.3.2**五链** ----规则链 3.iptables配置及操做3.1 基本语法3.1.1 控制类型项 (要大写!!!)3…

AR地图微信小程序:数字化时代下地图应用的新突破

随着数字化时代的到来,地图应用成为人们日常生活中不可或缺的工具。而随着增强现实(AR)技术的快速发展,AR地图微信小程序应运而生,为用户提供了一种全新的地图导航体验。本文将深入探讨AR地图微信小程序的专业性和思考…

LoRA继任者ReLoRA登场,通过叠加多个低秩更新矩阵实现更高效大模型训练效果

论文链接: https://arxiv.org/abs/2307.05695 代码仓库: https://github.com/guitaricet/peft_pretraining 一段时间以来,大模型(LLMs)社区的研究人员开始关注于如何降低训练、微调和推理LLMs所需要的庞大算力&#xf…

【洁洁送书第五期】为什么我们要了解可观测性工程

导读 可观测性已成为一个热门话题,并广受关注。随着它的普及,“可观测性”不幸被误作“监控”或“系统遥测”的同义词。可观测性是软件系统的一个特征。而且,只有当团队采用新的实践进行持续开发时,才能在生产软件系统中有效利用这…

22款美规奔驰S500升级原厂香氛负离子系统,清香宜人,久闻不腻

奔驰原厂香氛合理性可通过车内空气调节组件营造芳香四溢的怡人氛围。通过更换手套箱内香氛喷雾发生器所用的香水瓶,可轻松选择其他香氛。香氛的浓度和持续时间可调。淡雅的香氛缓缓喷出,并且在关闭后能够立刻散去。车内气味不会永久改变,香氛…

怎么维护自己的电脑

文章目录 我的电脑日常维护措施维护技巧键盘&屏幕清洁清理磁盘空间控制温度 电脑换电池 无论是学习还是工作,电脑都是IT人必不可少的重要武器,一台好电脑除了自身配置要经得起考验,后期主人对它的维护也是决定它寿命的重要因素&#xff0…

什么是算法评价指标

在我们建立一个学习算法时,或者说训练一个模型时,我们总是希望最大化某一个给定的评价指标(比如说准确度Acc),但算法在学习过程中又会尝试优化某一个损失函数(比如说均方差MSE或者交叉熵Cross-entropy&…

如何甄选一款优异的“恶意代码辅助检测系统”

恶意代码辅助检测系统是一款保密资质认证、涉密资质认证、保密条件备案认证、军工资质认证、涉密信息系统集成资质认证、保密室建设中必配的安全保密产品之一,但是如何甄选一款优异的“恶意代码辅助检测系统”?却往往是摆在客户面前的难题。日前&#xf…

Redis多机实现

Background 为啥要有多机--------------1.容错 2.从服务器分担读压力。 主从结构一大难题------------如何保障一致性,对这个一致性要求不是很高,因为redis是用来做缓存的 同时我们要自动化进行故障转移-------哨兵机制,同时哨兵也可能cra…

多城市求职招聘小程序开发搭建功能演示

专门针对微信生态开发的一款求职招聘系统,目前提供了企业入驻、发布职位、在线求职、职位匹配、简历填写、兼职板块、附近职位、招聘会等服务。可以帮助求职者快速高效的找到适合自己的工作。 想做招聘类小程序的可以看看这款小程序,丰富的功能场景可以…

实证论文必备-DID丨原理+操作+论文复刻+前沿

DID:双重差分法,常用在政策效果评估中,无论是在毕业论文还是期刊发表中都比较常见,与传统回归统计类似,其研究对象为面板数据,相比于传统回归估计,双重差分法针对政策的估计具有更好的适用性和精…

Linux下两个必学的查找命令find grep

查找文件名,使用 find命令: 例如:我想在 根目录/ 下查找 名为 libmy.a 的文件 sudo find / -name "libmy.a" 详细示例: 1、搜索当前目录下所有文件名中包含 "test" 的文件:find . -name "test"2、搜索当前目录下所有文件名以 ".tx…

国密算法介绍

一、简述 商用密码 商用密码是中华人民共和国政府用于非国家机密信息保护所采用的一系列密码技术和密码产品的总称,其相关技术为国家秘密。商用密码的研发及使用由国家密码管理局统一管理。 国密算法 国密算法是指中国自主设计和使用的密码算法标准,其…

网络传输介质的连接

目录 1.以太网接口 1.RJ-45接口 2.光纤接口 3.信息插座 2.双绞线的连接规范 1.以太网接口 以太网中由于传输介质的不同,连接线缆的接口也不同,本节将介绍目前最常用的传输介质--双绞线和光纤所使用的接口。 1.RJ-45接口 RJ是Registered Jack的缩写在…

leetcode:338. 比特位计数(python3解法)

难度&#xff1a;简单 给你一个整数 n &#xff0c;对于 0 < i < n 中的每个 i &#xff0c;计算其二进制表示中 1 的个数 &#xff0c;返回一个长度为 n 1 的数组 ans 作为答案。 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;[0,1,1] 解释&#xff1a; 0…

门店数字化店务经营系统怎么做?门店数字化系统推荐

为什么你的门店无人问津&#xff0c;有的门店却天天都有到店客户&#xff1f;为什么你的门店要花费两三天才能统计好经营情况&#xff0c;有的门店却能够做到“数据实时可查”&#xff1f;经营管理和营销获客是每个门店发展的重中之重&#xff0c;今天也为大家分享一套完善的门…

python 基础篇 day 3 运算符大全

文章目录 什么是运算符算术运算符种类举例注意运算顺序&#xff1a;整数除法和浮点数除法取模运算幂运算字符串拼接注意整数与浮点数之间的运算注意溢出问题 赋值运算符种类举例注意事项赋值顺序多重赋值增量赋值运算符赋值运算符链式操作注意可变对象的赋值注意不可变对象的赋…