2016-11-16 10 views
0

私は、グラフベースのバックプロパゲーションニューラルネットを個人的なプロジェクトとして作成しています。まだ前方の小道階段に。それはコンパイルする。正常に半分の時間を実行し、最後の半分の時間でクラッシュします。ガベージコレクションの段階で死んでいるようです。私は仮想関数とstatic_castの新機能ですから、その部分が責任を負うのだろうかと思います。 GDBは "プログラム受信シグナルSIGABRT、Aborted。0x00000000100404740を__gnu_cxx :: new_allocator :: deallocate(double *、unsigned long)()"と書いています。断続的な「中断されたコアダンプ」。たぶんstatic_castの不具合?

コードの前半部分を構成する関数は、彼らは(グラフなしで)私のニューラルネットのより単純な古いバージョンで動作します。私はそれがどこかの構造体にあると確信しています。

更新:タイムベースのランダムシードの代わりに123の乱数生成をシードすると、毎回実行されます。 seed = 124は毎回失敗します。一定の重みを優先してランダム性を取り除くことで、毎回実行することもできます。私はうんざりです!

#include <bits/stdc++.h> 
using namespace std; 

#define p(x) cout << #x << " = "<< x<< endl 
#define min(a,b) a<b ? a : b 
typedef vector<double> d1; 
typedef vector<d1> d2; 
typedef vector<d2> d3; 
typedef vector<int> i1; 

int argmax(d1 x){ 
    p(x.size()); 
    int maxIndex=0; 
    double maxValue=x[0]; 
    for (int i=1; i<x.size(); i++){ 
    if (x[i] > maxValue){ 
     maxValue = x[i]; 
     maxIndex = i; 
    } 
    } 
    return maxIndex; 
} 

d1 zeros(int n){ 
    return d1(n); 
} 

d2 zeros(int rows, int cols){ 
    return d2(rows, d1(cols, 0)); 
} 

d3 zeros(int x, int rows, int cols){ 
    return d3(x, d2(rows, d1(cols, 0))); 
} 

void print(d1 x){ 
    for (double d: x) 
    cout << d << endl; 
    cout << endl; 
} 

void print(d2 x){ 
    for (auto row: x){ 
    for (double d: row){ 
     cout << d << " "; 
    } 
    cout << endl; 
    } 
    cout << endl; 
} 

void print(d3 x){ 
    for (d2 X: x) 
    print(X); 
} 



void toRank2(d1&x, int rows, d2& y){ 
    for (int i=0; i<x.size()/rows; i++){ 
    y.emplace_back(); 
    for (int row=0; row<rows; row++){ 
     y[i].push_back(x[i*rows+row]); 
    } 
    } 
} 

void toRank3(d1& x, int rows, int cols, d3& y){ 
    for (int i=0; i<x.size()/rows/cols; i++){ 
    y.emplace_back(); 
    for (int row=0; row<rows; row++){ 
     y[i].emplace_back(); 
     for (int col=0; col<cols; col++){ 
     y[i][row].push_back(x[i*rows*cols+row*cols+col]); 
     } 
    } 
    } 
} 

d1 getRandomDoubles(int size, double mean=0, double standard_deviation=1){ 
    static normal_distribution<double> distribution(mean, standard_deviation); 
    int seed=time(NULL); 
    static default_random_engine generator(seed); 
    d1 data(size); 
    generate(data.begin(), data.end(), []() { return distribution(generator); }); 
    return data; 
} 

d2 getRandomDoubles(int rows, int cols, double mean=0, double standard_deviation=1){ 
    d1 d = getRandomDoubles(rows*cols, mean, standard_deviation); 
    d2 e; 
    toRank2(d, cols, e); 
    return e; 
} 

d3 getRandomDoubles(int depth, int rows, int cols, double mean=0, double standard_deviation=1){ 
    d1 d = getRandomDoubles(depth*rows*cols, mean, standard_deviation);; 
    d3 e; 
    toRank3(d, rows, cols, e); 
    return e; 
} 

struct Node{ 
    vector<Node*> parents, children; 
    bool ready=false; 
    // 
    // bool check_ready(){ 
    // for (Node* n: parents) 
    // if (!n->check_ready()) 
    // return false; 
    // return true; 
    // } 
    // 
    void add_child(Node& n){ 
    children.push_back(&n); 
    n.parents.push_back(this); 
    } 

    void forward_propagate(){ 
    cout << "starting r2 forward" <<endl; 
    // if (parents.size()==0 || updated_parents == parents.size()-1) 
    for (Node* n: children){ 
     cout << "loop" << endl; 
     n->update_state(); 
     // cout << "root child forward" << endl; 
    } 
    cout << "exiting r2 forward" << endl; 
    //updated_parents++; 
    } 

    virtual void update_state(){ 
    //if (parents.size()==0 || updated_parents == parents.size() - 1) 
    forward_propagate(); 
    } 
}; 

struct r1:Node{ 
    vector<double> state; 
    int r; 

    r1(){} 

    r1(int R){ 
    r=R; 
    state = vector<double>(r); 
    } 
}; 

struct r2:Node{ 
    vector<vector<double>> state; 
    int r,c; 

    r2(){} 
    r2(int R, int C){ 
    r=R; 
    c=C; 
    state = zeros(r, c); 
    } 
}; 

struct r3:Node{ 
    d3 state; 
    int r, c, d; 
    r3(){} 
    r3(int R, int C, int D){ 
    r=R; 
    c=C; 
    d=D; 
    state = zeros(R,C,D); 
    } 
}; 

struct MatrixProduct1_1: r1{ 
    MatrixProduct1_1(int n):r1(n){} 

    void update_state() override{ 
    cout << "mat11" << endl; 
    d2& W = static_cast<r2*>(parents[0])->state; 
    d1& x = static_cast<r1*>(parents[1])->state; 
    state = zeros(r); 
    for (int i=0; i<W.size(); i++) 
    for (int j=0; j<W[0].size(); j++) 
    state[i] += W[i][j]*x[j]; 
    forward_propagate(); 
    } 
}; 

struct MatrixProduct2_1: r1{ 
    MatrixProduct2_1(int n):r1(n){} 

    void update_state() override{ 
    cout << "matt21" << endl; 
    d3& W = static_cast<r3*>(parents[0])->state; 
    d2& x = static_cast<r2*>(parents[1])->state; 
    state = zeros(r); 
    for (int i=0; i<W.size(); i++) 
    for (int j=0; j<W[0].size(); j++) 
    for (int k=0; k<W[0][0].size(); k++) 
    state[k] += W[i][j][k]*x[i][j]; 
    forward_propagate(); 
    } 
}; 

struct Convolution: r2{ 
    Convolution(int r, int c): r2(r, c){} 
    void update_state() override{ 
    cout << "convolving" << endl; 
    state = zeros(r, c); 
    d2& W = static_cast<r2*>(parents[0])->state; 
    d2& x = static_cast<r2*>(parents[1])->state; 

    int wCenterX = W[0].size()/2; 
    int wCenterY = W.size()/2; 
    int rows = x.size(), cols = x[0].size(); 
    int wRows = W.size(), wCols = W[0].size(); 

    //#pragma omp parallel for 
    for(int i=0; i < rows; i++) 
    for(int j=0; j < cols; j++) 
    for(int m=0; m < W.size(); m++){ 
     int mm = W.size() - 1 - m; 
     for(int n=0; n < wCols; n++){ 
     int nn = wCols - 1 - n; 
     int ii = i + (m - wCenterY); 
     int jj = j + (n - wCenterX); 
     if (ii >= 0 && ii < rows && jj >= 0 && jj < cols) 
     state[i][j] += x[ii][jj] * W[mm][nn]; 
     } 
    } 
    forward_propagate(); 
    } 
}; 


struct RELU: r2{ 
    RELU(int r, int c):r2(r, c){} 
    void update_state() override{ 
    cout << "relu2" << endl; 
    state = zeros(r,c); 
    d2& x = static_cast<r2*>(parents[0])->state; 
    for (int i=0; i<state.size(); i++) 
    for (int j=0; j<state[0].size(); j++) 
    if (x[i][j] > 0) 
    state[i][j] = x[i][j]; 
    forward_propagate(); 
    } 
}; 

struct Softmax: r1{ 
    Softmax(int r):r1(r){} 
    void update_state() override{ 
    cout << "softmax" << endl; 
    state = zeros(r); 
    p(parents.size()); 
    d1& x = static_cast<r1*>(parents[0])->state; 
    cout << "got state" << endl; 
    //p(x.size()); 
    //print(x); 

    p(x.size()); 
    cout << "argmax " << argmax(x) << endl; 
    double largest = x[argmax(x)]; 
    double lndenom = largest; 
    double expsum = 0; 
    cout << "starting expsum" << endl; 
    for (int i=0; i<x.size(); i++) 
    //expsum += exp(x[i]-largest); 
    expsum += x[i] - largest; 
    cout << "next loop " << endl; 
    for (int i=0; i<x.size(); i++) 
    // state[i] = exp(x[i]-largest)/expsum; 
    state[i] = x[i]-largest; 
    cout << "forward proping" << endl; 
    cout << "weird" << endl; 
    // forward_propagate(); 
    cout << "done with softmax" <<endl; 
    } 
}; 

struct Add1: r1{ 
    Add1(int r):r1(r){} 
    void update_state() override{ 
    cout << "add1ing" << endl; 
    d1& x = static_cast<r1*>(parents[0])->state; 
    d1& y = static_cast<r1*>(parents[1])->state; 
    for (int i=0; i<r; i++) 
    state[i] = x[i]+y[i]; 
    forward_propagate(); 
    } 
}; 

struct Add2: r2{ 
    Add2(int r, int c): r2(r, c){} 
    void update_state() override{ 
    d2& x = static_cast<r2*>(parents[0])->state; 
    d2& y = static_cast<r2*>(parents[1])->state; 
    for (int i=0; i<x.size(); i++) 
    for (int j=0; j<x[0].size(); j++) 
    state[i][j] = x[i][j] + y[i][j]; 
    forward_propagate(); 
    } 
}; 

struct MaxPool: r2{ 
    MaxPool(int r, int c): r2(r, c){} 
    void update_state() override{ 
    d2& x = static_cast<r2*>(parents[0])->state; 
    for (int i=0; i<x.size(); i+=2) 
    for (int j=0; j<x[0].size(); j+=2) 
    state[i/2][j/2] = max(max(x[i][j], x[i+1][j]), max(x[i+1][j], x[i+1][j+1])); 
    forward_propagate(); 
    } 
}; 

int main(){ 
    Node root; 
    r2 x; 
    x.state = getRandomDoubles(28,28); 
    r2 wConv; 
    wConv.state = getRandomDoubles(10, 10); 
    root.add_child(x); 
    root.add_child(wConv); 
    Convolution c(28,28); 
    wConv.add_child(c); 
    x.add_child(c); 
    Add2 a(28,28); 
    r2 bConv(28,28); 
    bConv.state = getRandomDoubles(28,28); 
    c.add_child(a); 
    bConv.add_child(a); 
    RELU r(28,28); 
    a.add_child(r); 
    MaxPool max(14, 14); 
    r.add_child(max); 
    r3 wFull(10,28,28); 
    wFull.state = getRandomDoubles(10,28,28); 
    // print(wFull.state); 
    // return 0; 
    MatrixProduct2_1 full(10); 
    wFull.add_child(full); 
    max.add_child(full); 
    r1 bFull(10); 
    bFull.state = getRandomDoubles(10); 
    Add1 aFull(10); 
    aFull.state[0] = 123; 
    full.add_child(aFull); 
    bFull.add_child(aFull); 
    Softmax s(10); 
    aFull.add_child(s); 
    // d1& x =   static_cast<r1*>(parents[0])->state; 
    // d1& asdf = static_cast<r1*>(s.parents[0])->state; 
    // print(asdf); 
    //root.forward_propagate(); 
    x.forward_propagate(); 
    //print(s.state); 
    cout << "returning main"; 
} 
+1

'min'マクロは失敗していることで有名ですが、これは悪いバージョンです。私たちは完璧な 'std :: min'を持っているので、無意味です。あなたが再発明している唯一のホイールではない - 'argmax'はちょうど' std :: max_element'です。 – MSalters

答えて

1

static_castは、めったに必要ありません。これは例外ではありません。あなたのノードは、本当にその隣人がどのようなタイプを持っているか知っているべきです

私はすぐに具体的な問題を見つけることはできませんが、私は神経ネットワークに精通しています。 struct MatrixProduct1_1: r1のようなコードはかなり赤いアラートです。なぜ構造体なのですが、なぜそれがr1から継承されますか?ニューラルネットワーク理論では、行列積は、ノードの2つの層の完全な接続を表現する方法です。次に、ノードは通常、スカラー活性化を有する。

継承を使用してアクティベーション機能を実装することもできますが、それを継承するにはNodeを使用します。つまり、あなたはそれらをr1 .. r3のタイプにすることはできませんが、とにかくそれらを理解できませんでした。

TLDR:タイプが混乱している場合は、static_castで非表示にしますが、コンパイルするだけで正しいとは限りません。

-1

解決済み!このバグは、MatrixProd2_1で間違ったインデックスを使用したために発生しました。私は、ニューラルネットの終わりから始まるノードを削除し、バグの原因であると判断して、vector :: operator []引数についてアサートすることでそれを捕まえました。私は境界から外れていて、未定義の動作をしていました。なぜ特定のシードが(おそらくやや間違った結果を伴って)走ったのか、私にはっきりと分かりません。

また、mainでwFullを作成したときの形や、MatrixProd2_1で使用されているgetRandomDoublesの引数を変更しました。完全な新バージョン:

#include <bits/stdc++.h> 
using namespace std; 

#define p(x) cout << #x << " = "<< x<< endl 
//#define min(a,b) a<b ? a : b 
typedef vector<double> d1; 
typedef vector<d1> d2; 
typedef vector<d2> d3; 
typedef vector<int> i1; 
int seed; 
bool time_seed = true; 

int argmax(d1 x){ 
    p(x.size()); 
    int maxIndex=0; 
    double maxValue=x[0]; 
    for (int i=1; i<x.size(); i++){ 
    if (x[i] > maxValue){ 
     maxValue = x[i]; 
     maxIndex = i; 
    } 
    } 
    return maxIndex; 
} 

d1 zeros(int n){ 
    return d1(n); 
} 

d2 zeros(int rows, int cols){ 
    return d2(rows, d1(cols, 0)); 
} 

d3 zeros(int x, int rows, int cols){ 
    return d3(x, d2(rows, d1(cols, 0))); 
} 

void print(d1 x){ 
    for (double d: x) 
    cout << d << endl; 
    cout << endl; 
} 

void print(d2 x){ 
    for (auto row: x){ 
    for (double d: row){ 
     cout << d << " "; 
    } 
    cout << endl; 
    } 
    cout << endl; 
} 

void print(d3 x){ 
    for (d2 X: x) 
    print(X); 
} 



void toRank2(d1&x, int rows, d2& y){ 
    for (int i=0; i<x.size()/rows; i++){ 
    y.emplace_back(); 
    for (int row=0; row<rows; row++){ 
     y[i].push_back(x[i*rows+row]); 
    } 
    } 
} 

void toRank3(d1& x, int rows, int cols, d3& y){ 
    for (int i=0; i<x.size()/rows/cols; i++){ 
    y.emplace_back(); 
    for (int row=0; row<rows; row++){ 
     y[i].emplace_back(); 
     for (int col=0; col<cols; col++){ 
     y[i][row].push_back(x[i*rows*cols+row*cols+col]); 
     } 
    } 
    } 
} 

d1 getRandomDoubles(int size, double mean=1, double standard_deviation=1){ 
    static normal_distribution<double> distribution(mean, standard_deviation); 
    if (time_seed) 
    seed=time(NULL); 
    //int seed=123; //123 works, 124 fails 
    static default_random_engine generator(seed); 
    d1 data(size); 
    generate(data.begin(), data.end(), []() { return distribution(generator); }); 
    // generate(data.begin(), data.end(), [](){return -.1;}); 
    return data; 
} 

d2 getRandomDoubles(int rows, int cols, double mean=0, double standard_deviation=1){ 
    d1 d = getRandomDoubles(rows*cols, mean, standard_deviation); 
    d2 e; 
    toRank2(d, cols, e); 
    return e; 
} 

d3 getRandomDoubles(int depth, int rows, int cols, double mean=0, double standard_deviation=1){ 
    d1 d = getRandomDoubles(depth*rows*cols, mean, standard_deviation);; 
    d3 e; 
    toRank3(d, rows, cols, e); 
    return e; 
} 

struct Node{ 
    vector<Node*> parents, children; 
    bool ready=false; 
    // 
    // bool check_ready(){ 
    // for (Node* n: parents) 
    // if (!n->check_ready()) 
    // return false; 
    // return true; 
    // } 
    // 
    void add_child(Node& n){ 
    children.push_back(&n); 
    n.parents.push_back(this); 
    } 

    void forward_propagate(){ 
    cout << "starting r2 forward" <<endl; 
    // if (parents.size()==0 || updated_parents == parents.size()-1) 
    for (Node* n: children){ 
     cout << "loop" << endl; 
     n->update_state(); 
     // cout << "root child forward" << endl; 
    } 
    cout << "exiting r2 forward" << endl; 
    //updated_parents++; 
    } 

    virtual void update_state(){ 
    //if (parents.size()==0 || updated_parents == parents.size() - 1) 
    forward_propagate(); 
    } 
}; 

struct r1:Node{ 
    vector<double> state; 
    int r; 

    r1(){} 

    r1(int R){ 
    r=R; 
    state = vector<double>(r); 
    } 
}; 

struct r2:Node{ 
    vector<vector<double>> state; 
    int r,c; 

    r2(){} 
    r2(int R, int C){ 
    r=R; 
    c=C; 
    state = zeros(r, c); 
    } 
}; 

struct r3:Node{ 
    d3 state; 
    int r, c, d; 
    r3(){} 
    r3(int R, int C, int D){ 
    r=R; 
    c=C; 
    d=D; 
    state = zeros(R,C,D); 
    } 
}; 

struct MatrixProduct1_1: r1{ 
    MatrixProduct1_1(int n):r1(n){} 

    void update_state() override{ 
    cout << "mat11" << endl; 
    d2& W = static_cast<r2*>(parents[0])->state; 
    d1& x = static_cast<r1*>(parents[1])->state; 
    state = zeros(r); 
    for (int i=0; i<W.size(); i++) 
    for (int j=0; j<W[0].size(); j++) 
    state[i] += W[i][j]*x[j]; 
    forward_propagate(); 
    } 
}; 

struct MatrixProduct2_1: r1{ 
    MatrixProduct2_1(int n):r1(n){} 

    void update_state() override{ 
    cout << "matt21" << endl; 
    d3& W = static_cast<r3*>(parents[0])->state; 
    d2& x = static_cast<r2*>(parents[1])->state; 
    p(x.size()); 
    p(W.size()); 
    p(x[0].size()); 
    p(W[0].size()); 
    p(W[0][0].size()); 
    p(state.size()); 
    // assert (x.size()==W.size()); 
    // assert (x[0].size()==W[0].size()); 
    // assert (state.size()==W[0][0].size()); 
    assert (state.size() == W.size()); 

    state = zeros(r); 
    for (int i=0; i<W.size(); i++) 
    for (int j=0; j<W[0].size(); j++) 
    for (int k=0; k<W[0][0].size(); k++) 
    state[i] += W[i][j][k]*x[j][k]; 
    forward_propagate(); 
    } 
}; 

struct Convolution: r2{ 
    Convolution(int r, int c): r2(r, c){} 
    void update_state() override{ 
    cout << "convolving" << endl; 
    state = zeros(r, c); 
    d2& W = static_cast<r2*>(parents[0])->state; 
    d2& x = static_cast<r2*>(parents[1])->state; 

    int wCenterX = W[0].size()/2; 
    int wCenterY = W.size()/2; 
    int rows = x.size(), cols = x[0].size(); 
    int wRows = W.size(), wCols = W[0].size(); 

    //#pragma omp parallel for 
    for(int i=0; i < rows; i++) 
    for(int j=0; j < cols; j++) 
    for(int m=0; m < W.size(); m++){ 
     int mm = W.size() - 1 - m; 
     for(int n=0; n < wCols; n++){ 
     int nn = wCols - 1 - n; 
     int ii = i + (m - wCenterY); 
     int jj = j + (n - wCenterX); 
     if (ii >= 0 && ii < rows && jj >= 0 && jj < cols) 
     state[i][j] += x[ii][jj] * W[mm][nn]; 
     } 
    } 
    forward_propagate(); 
    } 
}; 


struct RELU: r2{ 
    RELU(int r, int c):r2(r, c){} 
    void update_state() override{ 
    cout << "relu2" << endl; 
    state = zeros(r,c); 
    d2& x = static_cast<r2*>(parents[0])->state; 
    for (int i=0; i<state.size(); i++) 
    for (int j=0; j<state[0].size(); j++) 
    if (x[i][j] > 0) 
    state[i][j] = x[i][j]; 
    forward_propagate(); 
    } 
}; 

struct Softmax: r1{ 
    Softmax(int r):r1(r){} 
    void update_state() override{ 
    cout << "softmax" << endl; 
    state = zeros(r); 
    p(parents.size()); 
    d1& x = static_cast<r1*>(parents[0])->state; 
    cout << "got state" << endl; 
    //p(x.size()); 
    //print(x); 

    p(x.size()); 
    cout << "argmax " << argmax(x) << endl; 
    double largest = x[argmax(x)]; 
    double lndenom = largest; 
    double expsum = 0; 
    cout << "starting expsum" << endl; 
    for (int i=0; i<x.size(); i++) 
    expsum += exp(x[i]-largest); 
    //expsum += x[i] - largest; 
    cout << "next loop " << endl; 
    for (int i=0; i<x.size(); i++) 
    state[i] = exp(x[i]-largest)/expsum; 
    //state[i] = x[i]-largest; 
    // state[i] = 3; 
    cout << "forward proping" << endl; 
    cout << "weird" << endl; 
    forward_propagate(); 
    cout << "done with softmax" <<endl; 
    } 
}; 

struct Add1: r1{ 
    Add1(int r):r1(r){} 
    void update_state() override{ 
    cout << "add1ing" << endl; 
    d1& x = static_cast<r1*>(parents[0])->state; 
    d1& y = static_cast<r1*>(parents[1])->state; 
    for (int i=0; i<r; i++) 
    state[i] = x[i]+y[i]; 
    forward_propagate(); 
    } 
}; 

struct Add2: r2{ 
    Add2(int r, int c): r2(r, c){} 
    void update_state() override{ 
    d2& x = static_cast<r2*>(parents[0])->state; 
    d2& y = static_cast<r2*>(parents[1])->state; 
    for (int i=0; i<x.size(); i++) 
    for (int j=0; j<x[0].size(); j++) 
    state[i][j] = x[i][j] + y[i][j]; 
    forward_propagate(); 
    } 
}; 

struct MaxPool: r2{ 
    MaxPool(int r, int c): r2(r, c){} 
    void update_state() override{ 
    d2& x = static_cast<r2*>(parents[0])->state; 
    for (int i=0; i<x.size(); i+=2) 
    for (int j=0; j<x[0].size(); j+=2) 
    state[i/2][j/2] = max(max(x[i][j], x[i+1][j]), max(x[i+1][j], x[i+1][j+1])); 
    forward_propagate(); 
    } 
}; 

int main(int argc, char *argv[]){ 
    if (argc>1){ 
    seed = atoi(argv[1]); 
    time_seed = false; 
    } 
    Node root; 
    r2 x; 
    x.state = getRandomDoubles(28,28); 
    //x.state[0][0]-=1000; 
    r2 wConv; 
    wConv.state = getRandomDoubles(10, 10); 
    root.add_child(x); 
    root.add_child(wConv); 
    Convolution c(28,28); 
    wConv.add_child(c); 
    x.add_child(c); 
    Add2 a(28,28); 
    r2 bConv(28,28); 
    bConv.state = getRandomDoubles(28,28); 
    c.add_child(a); 
    bConv.add_child(a); 
    RELU r(28,28); 
    a.add_child(r); 
    MaxPool max(14, 14); 
    r.add_child(max); 
// print(max.state); 
    r3 wFull(10,14,14); 
    wFull.state = getRandomDoubles(10,14,14); 
    //print(wFull.state); 
    // return 0; 
    MatrixProduct2_1 full(10); 
    wFull.add_child(full); 
    max.add_child(full); 
    //print(full.state); //suspiciously zero 
    r1 bFull(10); 
    bFull.state = getRandomDoubles(10); 
    Add1 aFull(10); 
    aFull.state[0] = 123; 
    full.add_child(aFull); 
    bFull.add_child(aFull); 
    Softmax s(10); 
    aFull.add_child(s); 
    // d1& x =   static_cast<r1*>(parents[0])->state; 
    // d1& asdf = static_cast<r1*>(s.parents[0])->state; 
    // print(asdf); 
    //root.forward_propagate(); 
    x.forward_propagate(); 
    //print(aFull.state); 
    print(s.state); 
    cout << "returning main"; 
} 
関連する問題