vendredi 23 juillet 2021

Dynamic Eigen Matrix Random Initialization

I have a vector<MatrixXf*> called weights. In the loop, a new MatrixXf is allocated, pointer pushed to the vector, and meant to be initialized to random values. However, I want to avoid setRandom() in favor of my He distribution.

The uncommented code below works as-is, but it feels very clunky to create a 'local' matrix that may be in the stack (or heap, but the class doc is vague) and copy it into my destination matrix. The commented lines are things I've tried before that had no effect (matrix values remained 0).

What would be the better solution?

    /* context */
    typedef Eigen::MatrixXf Matrix;
    vector<Matrix*> weights;
    random_device rd;
    mt19937 rgen(rd());
    vector<uint> topology;

    ...

    // Initialize weights (using He)
    if (i > 0) {
        normal_distribution<float> dist(0.0, sqrt(2.0/topology[i-1]));
        auto he = [&](){return dist(rgen);};

        if (i != topology.size() - 1) {
            Matrix m = Eigen::MatrixXf::NullaryExpr(topology[i-1] + 1, topology[i] + 1, he);
            weights.push_back(new Matrix(topology[i-1] + 1, topology[i] + 1));
            (*weights.back()) = m;

            //weights.back()->NullaryExpr(weights.back()->rows(), weights.back()->cols(), he);
            //weights.back()->NullaryExpr([&](){return dist(rgen);});

            weights.back()->col(topology[i]).setZero();
            weights.back()->coeffRef(topology[i-1], topology[i]) = 1.0;
        } else {
            Matrix m = Eigen::MatrixXf::NullaryExpr(topology[i-1] + 1, topology[i], he);
            weights.push_back(new Matrix(topology[i-1] + 1, topology[i]));
            (*weights.back()) = m;

            //weights.back()->NullaryExpr(weights.back()->rows(), weights.back()->cols(), he);
            //weights.back()->NullaryExpr([&](){return dist(rgen);});
        }
        cout << "Topology Loop: i=" << i << " and nodes=" << topology[i] << endl;
        cout << *weights.back() << endl;
    }



Aucun commentaire:

Enregistrer un commentaire