2016-08-01 15 views
0

これは私のメインコードです。なぜなら、アイデアは実際には出てこないようです。これが事を明確にすることを望む。それは...ニューラルネット活性化関数C++組み込み可能なオブジェクト

activation.cpp

typedef struct 
{ 
    virtual float operator() (float x) const = 0; 
    virtual float gradient (float x, float g) const = 0; 

} activation; 


struct sigmoid : activation 
{ 
    float operator() (float x) 
    { return 1.f/(1.f + expf(-x)); } 

    float gradient(float x, float g) 
    { float s = (*this)(x); return g * s * (1.f - s); } 

}; 


struct relu : activation 
{ 
    float operator() (float x) 
    { return x; } 

    float gradient(float x, float g) 
    { return g; } 

}; 

私はこれらのファンクタのオブジェクトは、彼らが上にある、彼らは常に同じになるように含めるよう呼び出し可能になりたいから構成さ

EG

main.cppに

#include "activation.cpp" 
int main() { cout << sigmoid(0) << sigmoid.gradient(0) << endl; } 

プリント

0.50.25 
+3

なぜ彼らはファンクタですか? –

+0

スタイルとコードの読みやすさと一貫性のための詳細 – user2255757

+0

この質問はファンクタオブジェクトのためだけではありませんが、一般的なインスタンス化の質問 – user2255757

答えて

1

A(3)経由数子を呼び出すために、そしてA変数、ないタイプの名前にする必要があります。これは、Aがファンクタのインスタンスでなければならないことを意味します。ファンクタのタイプが公開されているため複雑になります。その場合、他の人が構築やコピー、アドレス指定などを禁じる必要があります。あるいは、Aを通常の関数にする。

functors.h

int A(int x); 

functors.cpp

struct AFunctor { 
    int operator()(int x) const {return 3*x;} ; 
}; 
int A(int x) { 
    static AFunctor a; 
    return a(x); 
}  

main.cppに

#include "functors.h" 
int main() 
{cout << A(3) << endl;} 

この時点では明らかである、シングルトンを持ってする理由は、文字通りありません通りこのようなファンクタ。 Functorは通常はステートフルであり、左右に作成することも、その両方を行うこともできます。


シングルトン・ファンクタを間違いなく使用していることが明らかになったので、これは私が推測する方法です。

functors.h

struct activation 
{ 
    virtual float operator() (float x) const = 0; 
    virtual float gradient (float x, float g) const = 0; 
}; 

struct sigmoidFunctor : activation 
{ 
    float operator() (float x);  
    float gradient(float x, float g); 
    static sigmoidFunctor& get(); 
private 
    sigmoidFunctor()=default; 
    sigmoidFunctor(const sigmoidFunctor&)=delete; 
}; 
extern sigmoidFunctor& sigmoid; 

struct reluFunctor : activation 
{ 
    float operator() (float x);  
    float gradient(float x, float g); 
    static reluFunctor& get(); 
private 
    reluFunctor()=default; 
    reluFunctor(const reluFunctor&)=delete; 
}; 
extern reluFunctor& relu; 

複雑で広大な増加によって証明されるようにfunctors.cpp

float sigmoidFunctor::operator() (float x) 
{ return 1.f/(1.f + expf(-x)); } 

float sigmoidFunctor::gradient(float x, float g) 
{ float s = (*this)(x); return g * s * (1.f - s); } 

sigmoidFunctor& sigmoidFunctor::get() { 
    static sigmoidFunctor sigmoid; 
    return sigmoid; 
} 
sigmoidFunctor& sigmoid = sigmoidFunctor.get(); 


float reluFunctor::operator() (float x) 
{ return x; } 

float reluFunctor::gradient(float x, float g) 
{ return g; } 

reluFunctor& reluFunctorFunctor::get() { 
    static reluFunctor relu; 
    return relu; 
} 
reluFunctor& relu = reluFunctor.get(); 

は、私は強く再考するあなたを促します。通常、シングルトンはすべてを混乱させるだけです。

+0

これはどんなものでも良いはずです:P .... –

+0

1私が欲しいものではありません、2私は明らかに1が必要なので、理由があります。 – user2255757

+2

@ user2255757理由を教えてもらえますか?私は定期的な機能がうまくいかない理由を見逃す。 – NathanOliver

関連する問題