2016-08-01 62 views
0

這是我的主要代碼,因爲它似乎並沒有真正的想法。希望這可以澄清事情。它由神經網絡激活功能C++包括Unitialisable對象

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;} 

如應該在這一點上明顯的,有字面上沒有理由讓一個單身像這樣的函子。仿函數通常是有狀態的,或者你可以左右創建它們,或者兩者兼而有之。


既然現在很清楚你肯定想要單身仿函數,這將是我想要的方式。

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有一個原因,因爲我明顯想要一個。 – user2255757

+2

@ user2255757你能告訴我們原因嗎?我不明白爲什麼常規功能不起作用。 – NathanOliver