首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >CNN多维卷积阵列上最大池运算的最佳时间复杂度

CNN多维卷积阵列上最大池运算的最佳时间复杂度
EN

Stack Overflow用户
提问于 2021-04-02 19:06:00
回答 1查看 361关注 0票数 0

在思考这个问题时,我发现了一个在O( m_n )时间内工作的算法,如果卷积2d数组是m_n的话。

看看怎么做。在一维情况下,我们需要在数组中的大小为k的每一个窗口中找到最大值的答案。用德克。有关更多详细信息,请参见此https://www.geeksforgeeks.org/sliding-window-maximum-maximum-of-all-subarrays-of-size-k/

假设在二维情况下k是滤波器的大小,步长为10填充,n*m矩阵。

Step1,然后计算所有大小窗口的最大值k,给出了每行大小k的最大窗口的答案。在计算完所有行之后。

在转换矩阵中的Step2之后,对于大小为k的滑动窗口中最大的列,对修改后的矩阵中的每一列做同样的操作。在重复之后,在矩阵的位置i,j开始于单元格i,j作为左上角,i+k-1,j+k-1作为右下角,得到大小为k*k的整个子数组的最大值。

证据很简单。

当你有最大的k行,那么在一个大小窗口中计算最大值时,k在列上给出了整个矩阵上的最大值。

示例

5 3 2 1 4

2 3 1 5 3

1 2 3 4 6

1 2 3 4 5

5 4 3 2 1

假设n=5,m=5和k=3。

修改后的矩阵看起来

5 3 4

3 5 3

3 4 6

3 4 5

5 4 3

进一步应用step2看起来就像。

5 5 6

3 5 6

5 4 6

这就是我们面前的最大集合层。

这是一个很好的算法,可以给CNN模型带来优化,还是有更好的现有算法?请发表你的意见?

EN

Stack Overflow用户

发布于 2022-04-06 07:46:21

2 Time池最佳时间复杂度为O(nm)

以下是我的C++代码:

代码语言:javascript
运行
复制
#include <iostream>
#include <vector>
#include <deque>
#include <cstring>

using namespace std;

typedef long long LL;

const int N = 1e3;
int g[N][N];

void max_window(int l1, int l2, int r1, int r2, int k) {
    vector<int> nums;

    // Time: max(n, m)
    for (int i = l1; i <= r1; i ++) {
        for (int j = l2; j <= r2; j ++) {
            nums.push_back(g[i][j]);
        }
    }

    vector<int> res;
    deque<int> q;
    for (int i = 0; i < nums.size(); i ++) {
        while (q.size() && i - q.front() >= k) q.pop_front();

        while (q.size() && nums[q.back()] <= nums[i]) q.pop_back();

        q.push_back(i);        
        if (i >= k - 1) res.push_back(nums[q.front()]);
    }

    int cnt = 0;
    for (int i = l1; i <= r1; i ++) {
        for (int j = l2; j <= r2; j ++) {
            if (cnt >= res.size()) break;
            g[i][j] = res[cnt];
            cnt ++;
        }
    }
    return;
}


int main(){
    #ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    #endif

    int n, m, a, b;
    cin >> n >> m >> a >> b;
    for (int i = 0; i < n; i ++) {
        for (int j = 0; j < m; j ++) {
            cin >> g[i][j];
        }
    }

    for (int i = 0; i < n; i ++) {
        for (int j = 0; j < m; j ++) {
            cout << g[i][j] << " ";
        }
        cout << endl;
    }
    cout << endl;

    // shape: n x m
    for (int i = 0; i < n; i ++) {  
        max_window(i, 0, i, n - 1, b);
    }


    for (int j = 0; j < m - b + 1; j ++) {  // shape:n x (m - b + 1)
        max_window(0, j, m - 1, j, a);
    }

    // shape:(n - a + 1) x (m - b + 1)
    for (int i = 0; i < n - a + 1; i ++) {
        for (int j = 0; j < m - b + 1; j ++) {
            cout << g[i][j] << " ";
        }
        cout << endl;
    }
    
    return 0;
}

输入:

代码语言:javascript
运行
复制
5 5 3 3
5 3 2 1 4
2 3 1 5 3
1 2 3 4 6
1 2 3 4 5
5 4 3 2 1

输出:

代码语言:javascript
运行
复制
5 3 2 1 4 
2 3 1 5 3
1 2 3 4 6
1 2 3 4 5
5 4 3 2 1

5 5 6
3 5 6
5 4 6

顺便说一句,这里是最佳时间复杂度为O(n)的一维最大池示例。https://leetcode.com/problems/sliding-window-maximum/

票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66924060

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档