2

ArrayFire で配列を飽和させようとしています。0.75 より大きい値はすべて 1.0 に飽和し、0.25 より小さい値はすべて 0.0 に飽和します。以下の表現を使用しています。

a(a > 0.75) = 1.0;
a(a < 0.25) = 0.0;

これは af::array タイプです。しばらくは機能しますが、0.75 を超える値がない配列を取得するとすぐに、次の例外が発生します。

terminate called after throwing an instance of 'af::exception'
  what():  ArrayFire Exception (Invalid input size:203):
In function verifyDims
In file src/api/c/data.cpp:36
Invalid dimension for argument 1
Expected: ndims >= 1

In function af::array af::constant(T, const af::dim4&, af::dtype) [with T = double; af::dtype = af_dtype]
In file src/api/cpp/data.cpp:28

呼び出すaf::print("", a > 0.75);と、クラッシュする直前に次の出力が得られます。

[10 1 1 1]
         0 
         0 
         0 
         0 
         0 
         0 
         0 
         0 
         0 
         0 

この配列がすべてゼロであることをどういうわけか見て (0.75 より大きいので、そうあるべきです)、次元がゼロであると言っていますか? それは私が間違っていることですか、それとも彼らのコードのバグですか?

次のコードはそれを修正しているようですが、この解決策はやや非効率的だと思います。

af::array bellow = a[levels - 1] < 0.25f;
af::array above = a[levels - 1] > 0.75f;

if(af::anyTrue<bool>(above))
    a[levels - 1](above) = 0.75f;

if(af::anyTrue<bool>(bellow))
    a[levels - 1](bellow) = 0.25f;

関数全体を見たい人のために、私はニューラル ネットワークで適切な勾配を実行しています。a は実際には af::array 型の配列です。質問を簡単にするために、それを省略しました。

void train(const float* in, const float* expected_out, float learning_rate)
{
    std::unique_ptr<af::array[]> a(new af::array[levels]),
            z(new af::array[levels]), d(new af::array[levels]);

    af::array in_array(inputs, in);
    af::array y(dims[levels - 1], expected_out);

    z[0] = af::matmul(weights[0], in_array) + biases[0];
    a[0] = sigma(z[0]);


    for(size_t i = 1; i < levels; i++)
    {
        z[i] = af::matmul(weights[i], a[i - 1]) + biases[i];
        a[i] = sigma(z[i]);
    }


    a[levels - 1](a[levels - 1] < 0.25f) = 0.0f;
    a[levels - 1](a[levels - 1] > 0.75f) = 1.0f;

    d[levels - 1] = (y - a[levels - 1]) * sigma_prime(z[levels - 1]);
    for(size_t i = levels - 1; i-- > 0;)
        d[i] = af::matmul(weights[i + 1].T(), d[i + 1]) * sigma_prime(z[i]);

    for(size_t i = 0; i < levels; i++)
    {
        biases[i] += learning_rate * d[i];
        weights[i] += learning_rate * af::matmul(d[i], (i ? a[i - 1] : in_array).T());
    }
}
4

1 に答える 1

4
于 2016-03-28T22:13:27.867 に答える