0
点赞
收藏
分享

微信扫一扫

【剪枝实战】使用VGGNet训练、稀疏训练、剪枝、微调等,剪枝出只有3M的模型

unadlib 03-16 07:00 阅读 4
算法图论

最小生成树的性质

无向图G的顶点集为 V V V,设 U U U V V V的真子集, u ∈ U u\in U uU v ∈ ( V − U ) v\in (V- U) v(VU),边u-v是连通 U U U、的所有边中权重最小的一条,则边u-v一定在G的最小生成树(MST)中。
反证法证明:假设T是一个MST,边u-v不在该MST中,先把它加入到T,则出现包含该边的环;T中必存在另一条边 u ′ − v ′ u^\prime-v^\prime uv,连接题中两个集合,删除它后,环消失,出现新的MST,并且比原MST的权重更小,矛盾。

Prim算法

思路就是任取一个顶点作为初始U,不断寻找连接两个子集的所有边中权重最小的一条,把此边在 V − U V-U VU上的顶点移到 U U U,重复这个操作,直至U包含全部顶点。

Kruscal算法

直接将所有边按权重排序,从小到大,每次尝试添加一条到MST,如果加入后没有产生环就加入该边,否则跳过。

松弛操作

两种算法都用了求最值问题的松弛操作思路,相似的例子,求K个已排序数组的最短公共区间,该区间包含每个数组至少一个元素,初始化选择各个数组首个元素组成集合的最小最大值,然后松弛,选择最小值所在数组向右取元素,更新区间。

#include <vector>
#include <utility>
#include <numeric>
#include <iostream>
#include <limits>
#include <tuple>
using namespace std;
class Solution {
public:
    vector<int> smallestRange(vector<vector<int> > &nums)
    {
        bool stop = false;
        int length = 2e5;
        int left = -1e5;
        int right = 1e5;
        vector<size_t> v_pos;
        vector<size_t> v_size;
        vector<int> holder;
        std::vector<int> lrlen{left, right, length};
        Init(nums, v_pos, v_size, holder);
        UpdateLeftRight(nums, v_pos, v_size, holder, lrlen, stop);
        while (!stop) {
            UpdateLeftRight(nums, v_pos, v_size, holder, lrlen, stop);
        }
        return {lrlen[0], lrlen[1]};
    }

    tuple<size_t, int, int> GetMinMax(const vector<int> &holder_)
    {
        int min = numeric_limits<int>::max();
        int max = numeric_limits<int>::min();
        size_t pos = 0;
        for (size_t i = 0; i < holder_.size(); i++) {
            if (min > holder_[i]) {
                min = holder_[i];
                pos = i;
            }
            if (max < holder_[i]) {
                max = holder_[i];
            }
        }
        return {pos, min, max};
    }
    void UpdateLeftRight(const vector<vector<int> > &nums, vector<size_t> &v_pos, vector<size_t> &v_size,
                         vector<int> &holder, std::vector<int> &lrlen, bool &stop)
    {
        auto res = GetMinMax(holder);
        int tmp_left = get<1>(res);
        int tmp_right = get<2>(res);
        size_t pos = get<0>(res);
        if (v_pos[pos] == (nums[pos].size() - 1)) {
            stop = true;
        }
        v_pos[pos]++;
        int tmp_length = tmp_right - tmp_left;
        if (tmp_length < lrlen[2] || (tmp_length == lrlen[2] && tmp_left < lrlen[0])) {
            lrlen[0] = tmp_left;
            lrlen[1] = tmp_right;
            lrlen[2] = tmp_length;
        }
        holder.clear();
        for (size_t i = 0; i < v_pos.size(); i++) {
            holder.push_back(nums[i][v_pos[i]]);
        }
    }
    void Init(const vector<vector<int> > &nums, vector<size_t> &v_pos, vector<size_t> &v_size, vector<int> &holder)
    {
        v_pos.clear();
        v_size.clear();
        holder.clear();
        for (size_t i = 0; i < nums.size(); i++) {
            v_pos.push_back(0);
            v_size.push_back(nums[i].size());
            holder.push_back(nums[i][0]);
        }
    }
};
int main()
{
    Solution A;
    vector<int> a{4, 10, 15, 24, 26};
    vector<int> b{0, 9, 12, 20};
    vector<int> c{5, 18, 22, 30};
    vector<vector<int> > q{a, b, c};
    auto res = A.smallestRange(q);
    for (auto i : res) {
        cout << i << " ";
    }
    cout << endl;
    a.clear();
    b.clear();
    c.clear();
    for (int i = 1; i < 4; i++) {
        a.push_back(i);
        b.push_back(i);
        c.push_back(i);
    }
    vector<vector<int> > qb{a, b, c};
    res = A.smallestRange(qb);
    for (auto i : res) {
        cout << i << " ";
    }
    return 0;
}
举报

相关推荐

5、模型的剪枝、测试

0 条评论