【Eigen】要素ごとにラムダ式を実行してくれるunaryExpr

 

■環境

Visual Studio Community 2017
Eigen 3.3.6

 

■使い方

全要素にとある処理を実行したいとき、.tanh()など用意されている関数ならば良いのですが
そうでないとき、いちいちfor文使うのは不便ですね。(依存症)
単純な四則演算なら.array() += n;とかでできなくも……ああ、これでもできない。

そんなときにunaryExpr。



#include 
#include "Eigen/Core"

using namespace std;
using namespace Eigen;

int main()
{
    MatrixXf test = MatrixXf::Random(3, 3);

    test = test.unaryExpr([](float p) { return (p > 0.0f) ? p : 0.0f; }); // ReLU

    cout << test;

    while(true){} // 時を止める用

    return 0;
}

ラムダ式の引数 p は各要素の値です。
各要素のラムダ式の戻り値で構成された行列は別オブジェクトであり、代入しない限りtestは変更されません。

 

■softmaxにも使える

他に使える例としては、softmaxがあります。

softmaxって、やり方だけ見ると面倒くさいです。
全要素から最大要素の値を引いてexp関数を適用して、そのあと全要素の和で割る。
普通の配列だと煩雑になりがちですが、Eigen使うと二行で書けます。



#include <iostream>

#include "Eigen/Core"

using namespace std;
using namespace Eigen;

int main()
{
    VectorXf test = VectorXf::Random(5);

    // softmax
    test = test.unaryExpr([&](float p) { return exp(p - test.maxCoeff()); });
    test.array() /= test.sum();

    cout << test;

    while(true){} // 時を止める用

    return 0;
}

今回は参照キャプチャ([&])を使っています。
unaryExprが実行される段階ではtestの中身は書き換えられていないので、test.maxCoeff()がそのまま使えます。

ラムダ式は最初見たときは何に使うのか今一つぴんときませんでしたが、使えるようになると便利ですね!

おすすめ

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です