神经网络系列---池化


文章目录


池化

最大池化

最大池化(Max Pooling)是卷积神经网络中常用的一种池化技术。其操作是:在输入特征图的一个局部窗口内选取最大的值作为该窗口的输出。

数学表达式如下:

考虑一个输入特征图 A A A,并定义一个大小为 f × f f \times f f×f 的池化窗口和步长 s s s。对于输出特征图 M M M 中的元素 M ( i , j ) M(i,j) M(i,j),其值由以下公式确定:

M ( i , j ) = max ⁡ u = 0 f − 1 max ⁡ v = 0 f − 1 A ( i × s + u , j × s + v ) M(i,j) = \max_{u=0}^{f-1} \max_{v=0}^{f-1} A(i \times s + u, j \times s + v) M(i,j)=maxu=0f−1maxv=0f−1A(i×s+u,j×s+v)

其中:

  • M ( i , j ) M(i,j) M(i,j) 是输出特征图的第 ( i , j ) (i,j) (i,j) 个元素。
  • max ⁡ \max max 表示最大值操作。
  • u u u 和 v v v 都是在 0 , f − 1 0, f-1 0,f−1 范围内变化的索引,它们用于遍历池化窗口内的每一个元素。
  • s s s 是步长,定义了池化窗口在输入特征图上移动的距离。
  • A ( i × s + u , j × s + v ) A(i \times s + u, j \times s + v) A(i×s+u,j×s+v) 是输入特征图 A A A 中与输出特征图 M ( i , j ) M(i,j) M(i,j) 对应的局部窗口的元素。

这个公式简单地描述了最大池化的操作:对于每个输出元素 M ( i , j ) M(i,j) M(i,j),都在输入特征图 A A A 的相应局部窗口中找到最大的值。

cpp 复制代码
//最大池化
Eigen::MatrixXf Pooling::maxPoolingForward(const Eigen::MatrixXf& input,int m_poolSize,int m_stride)
{
    int outputHeight = (input.rows() - m_poolSize) / m_stride + 1;
    int outputWidth = (input.cols() - m_poolSize) / m_stride + 1;

    Eigen::MatrixXf output(outputHeight, outputWidth);

    for (int i = 0; i < outputHeight; ++i)
    {
        for (int j = 0; j < outputWidth; ++j)
        {
            output(i, j) = input.block(i * m_stride, j * m_stride, m_poolSize, m_poolSize).maxCoeff();
        }
    }

    return output;
}
//最大池化 反向
Eigen::MatrixXf Pooling::maxPoolingBackward(const Eigen::MatrixXf& input, const Eigen::MatrixXf& gradient,int m_poolSize,int m_stride)
{
    Eigen::MatrixXf output = Eigen::MatrixXf::Zero(input.rows(), input.cols());

    int outputHeight = gradient.rows();
    int outputWidth = gradient.cols();

    for (int i = 0; i < outputHeight; ++i)
    {
        for (int j = 0; j < outputWidth; ++j)
        {
            int row,col;
            input.block(i * m_stride, j * m_stride, m_poolSize, m_poolSize).maxCoeff(&row,&col);
            output(i * m_stride + row, j * m_stride + col) += gradient(i, j);

        }
    }

    return output;
}

平均池化

平均池化(Average Pooling)是卷积神经网络中另一种常用的池化技术。其操作是在输入特征图的一个局部窗口内计算所有值的平均值,然后将此平均值作为该窗口的输出。

数学表达式如下:

考虑一个输入特征图 A A A,并定义一个大小为 f × f f \times f f×f 的池化窗口和步长 s s s。对于输出特征图 M M M 中的元素 M ( i , j ) M(i,j) M(i,j),其值由以下公式确定:

M ( i , j ) = 1 f × f ∑ u = 0 f − 1 ∑ v = 0 f − 1 A ( i × s + u , j × s + v ) M(i,j) = \frac{1}{f \times f} \sum_{u=0}^{f-1} \sum_{v=0}^{f-1} A(i \times s + u, j \times s + v) M(i,j)=f×f1∑u=0f−1∑v=0f−1A(i×s+u,j×s+v)

其中:

  • M ( i , j ) M(i,j) M(i,j) 是输出特征图的第 ( i , j ) (i,j) (i,j) 个元素。
  • ∑ \sum ∑ 表示求和操作。
  • u u u 和 v v v 都是在 0 , f − 1 0, f-1 0,f−1 范围内变化的索引,它们用于遍历池化窗口内的每一个元素。
  • s s s 是步长,定义了池化窗口在输入特征图上移动的距离。
  • A ( i × s + u , j × s + v ) A(i \times s + u, j \times s + v) A(i×s+u,j×s+v) 是输入特征图 A A A 中与输出特征图 M ( i , j ) M(i,j) M(i,j) 对应的局部窗口的元素。
  • f × f f \times f f×f 是池化窗口的大小。

这个公式描述了平均池化的操作:对于每个输出元素 M ( i , j ) M(i,j) M(i,j),都在输入特征图 A A A 的相应局部窗口中计算所有值的平均值。

cpp 复制代码
//平均池化
Eigen::MatrixXf Pooling::averagePoolingForward(const Eigen::MatrixXf& input,int m_poolSize,int m_stride)
{
    int outputHeight = (input.rows() - m_poolSize) / m_stride + 1;
    int outputWidth = (input.cols() - m_poolSize) / m_stride + 1;

    Eigen::MatrixXf output(outputHeight, outputWidth);

    for (int i = 0; i < outputHeight; ++i)
    {
        for (int j = 0; j < outputWidth; ++j)
        {
            output(i, j) = input.block(i * m_stride, j * m_stride, m_poolSize, m_poolSize).mean();
        }
    }

    return output;
}

// 反向传播对于平均池化比较简单,因为只需要分摊输入梯度到相应的位置。
Eigen::MatrixXf Pooling::averagePoolingBackward(const Eigen::MatrixXf& input,const Eigen::MatrixXf& gradient,int m_poolSize,int m_stride)
{
    Eigen::MatrixXf output = Eigen::MatrixXf::Zero(input.rows(), input.cols());

    int inputHeight = gradient.rows();
    int inputWidth = gradient.cols();

    for (int i = 0; i < inputHeight; ++i)
    {
        for (int j = 0; j < inputWidth; ++j)
        {
            output.block(i * m_stride, j * m_stride, m_poolSize, m_poolSize).array() += gradient(i, j) / (m_poolSize * m_poolSize);
        }
    }

    return output;
}
相关推荐
罗西的思考12 小时前
AI 时代的 “房谋杜断”:如何培养能力、品味与判断力
人工智能·算法·机器学习
字节跳动视频云技术团队13 小时前
720P 直升 8K,解密 2026 抖音美好奇妙夜巨幕超分黑科技
人工智能·音视频开发
打工仔折腾 AI13 小时前
在 Ubuntu ARM64 部署 Q1 V3.0 MuJoCo 模型:加载、单步推理与执行器响应解析
linux·运维·人工智能·python·深度学习·ubuntu·性能优化
逐米时代13 小时前
从试点验证到协同深化:制造业AI转型三年路线图设计方法
人工智能
GlobalInfo13 小时前
全球及中国风电叶片检测机器人行业研究报告(2026版):市场现状、行业前景与占有率分析
运维·网络·人工智能·机器人
stormzhangV14 小时前
AI 越强,失业越严重
人工智能·aigc
夏文强15 小时前
Rerank 与混合检索:怎么让 RAG 从「能用」变成「好用」
人工智能·大模型·向量数据库·rag·检索增强生成
救救孩子把15 小时前
AI面试八股文-23_23-Agent可观测性与生产监控面试题
人工智能·面试·职场和发展·agent·langsmith·langfuase
IT_陈寒15 小时前
Java静态变量初始化坑得我头皮发麻
前端·人工智能·后端
知行产研15 小时前
白马山领跑、南山矿扩编 31 台,安徽露天矿无人驾驶进入规模化阶段
人工智能