|
|
@@ -14,22 +14,20 @@ const (
|
|
|
Sample int = 10000
|
|
|
Batch int = 5
|
|
|
Dropout float64 = 0.5
|
|
|
- RateWo float64 = 0.1
|
|
|
- RateWi float64 = 0.1
|
|
|
- RateB float64 = 0.1
|
|
|
+ Rate float64 = 0.1
|
|
|
)
|
|
|
|
|
|
type (
|
|
|
Parameter struct {
|
|
|
- Wo, Wi, B, A Matrix
|
|
|
+ W, B, A Matrix
|
|
|
}
|
|
|
|
|
|
Layer struct {
|
|
|
- d int
|
|
|
- f func(Matrix) Matrix
|
|
|
- p Parameter
|
|
|
- D Vector
|
|
|
- O, I, E Matrix
|
|
|
+ d int
|
|
|
+ f func(Matrix) Matrix
|
|
|
+ p Parameter
|
|
|
+ D Vector
|
|
|
+ A, E Matrix
|
|
|
}
|
|
|
)
|
|
|
|
|
|
@@ -65,24 +63,35 @@ func GetEmbedding(G Graph, u, k int, l []Layer, train bool) Matrix {
|
|
|
}
|
|
|
return l[k].E
|
|
|
}
|
|
|
- l[k-1].O, l[k-1].I, l[k].E = MakeMatrix(1, l[k-1].d), MakeMatrix(1, l[k-1].d), MakeMatrix(1, l[k].d)
|
|
|
- Do, Di := 0, 0
|
|
|
- for v, w := range G.A[u] {
|
|
|
- if w == 1 {
|
|
|
- l[k-1].O.Add(GetEmbedding(G, v, k-1, l, train))
|
|
|
- Do++
|
|
|
- } else {
|
|
|
- l[k-1].I.Add(GetEmbedding(G, v, k-1, l, train))
|
|
|
- Di++
|
|
|
- }
|
|
|
- }
|
|
|
- if Do > 0 {
|
|
|
- l[k].E.Add(l[k-1].O.Divide(float64(Do)).Multiply(l[k].p.Wo))
|
|
|
- }
|
|
|
- if Di > 0 {
|
|
|
- l[k].E.Add(l[k-1].I.Divide(float64(Di)).Multiply(l[k].p.Wi))
|
|
|
+ l[k-1].A, l[k].E = MakeMatrix(1, l[k-1].d), MakeMatrix(1, l[k].d)
|
|
|
+ // GCN
|
|
|
+ // deg := 0
|
|
|
+ // for v := range G.A[u] {
|
|
|
+ // l[k-1].A.Add(GetEmbedding(G, v, k-1, l, train))
|
|
|
+ // deg++
|
|
|
+ // }
|
|
|
+ // l[k].E.Add(GetEmbedding(G, u, k-1, l, train).Multiply(l[k].p.B))
|
|
|
+ // if deg > 0 {
|
|
|
+ // l[k].E.Add(l[k-1].A.Divide(float64(deg)).Multiply(l[k].p.W))
|
|
|
+ // }
|
|
|
+ // GAT
|
|
|
+ A := MakeMatrix(0, l[k-1].d)
|
|
|
+ for v := range G.A[u] {
|
|
|
+ A = append(A, GetEmbedding(G, v, k-1, l, train)[0])
|
|
|
}
|
|
|
l[k].E.Add(GetEmbedding(G, u, k-1, l, train).Multiply(l[k].p.B))
|
|
|
+ if A.N() > 0 {
|
|
|
+ C := MakeMatrix(1, A.N())
|
|
|
+ Me := l[k-1].E[0].Modulus()
|
|
|
+ for i := 0; i < A.N(); i++ {
|
|
|
+ Ma := A[i].Modulus()
|
|
|
+ if Me != 0 && Ma != 0 {
|
|
|
+ C[0][i] = l[k-1].E[0].Dot(A[i]) / Me / Ma
|
|
|
+ }
|
|
|
+ }
|
|
|
+ l[k-1].A.Add(Softmax(C).Multiply(A))
|
|
|
+ l[k].E.Add(l[k-1].A.Multiply(l[k].p.W))
|
|
|
+ }
|
|
|
if train && l[k].D != nil {
|
|
|
l[k].E.Dropout(l[k].D)
|
|
|
}
|
|
|
@@ -108,25 +117,25 @@ func StartRefine(wg *sync.WaitGroup, A, B Matrix, c float64) {
|
|
|
}
|
|
|
|
|
|
func Train(G Graph) []Layer {
|
|
|
- p1 := Parameter{MakeRandomMatrix(Input, Hidden), MakeRandomMatrix(Input, Hidden), MakeRandomMatrix(Input, Hidden), MakeRandomMatrix(Input*2, 1)}
|
|
|
- p2 := Parameter{MakeRandomMatrix(Hidden, Output), MakeRandomMatrix(Hidden, Output), MakeRandomMatrix(Hidden, Output), MakeRandomMatrix(Hidden*2, 1)}
|
|
|
- l := []Layer{{d: Input}, {d: Hidden, f: ReLU, p: p1}, {d: Output, f: Softmax, p: p2}}
|
|
|
+ p0 := Parameter{A: MakeRandomMatrix(Input*2, 1)}
|
|
|
+ p1 := Parameter{W: MakeRandomMatrix(Input, Hidden), B: MakeRandomMatrix(Input, Hidden), A: MakeRandomMatrix(Hidden*2, 1)}
|
|
|
+ p2 := Parameter{W: MakeRandomMatrix(Hidden, Output), B: MakeRandomMatrix(Hidden, Output)}
|
|
|
+ l := []Layer{{d: Input, p: p0}, {d: Hidden, f: ReLU, p: p1}, {d: Output, f: Softmax, p: p2}}
|
|
|
for i := 0; i < Sample; i++ {
|
|
|
if i%100 == 0 {
|
|
|
fmt.Println("sampling", i)
|
|
|
}
|
|
|
var wg sync.WaitGroup
|
|
|
l[0].D, l[1].D = MakeDropoutVector(Input), MakeDropoutVector(Hidden)
|
|
|
- DWo2, DWi2, DB2 := MakeMatrix(Hidden, Output), MakeMatrix(Hidden, Output), MakeMatrix(Hidden, Output)
|
|
|
- DWo1, DWi1, DB1 := MakeMatrix(Input, Hidden), MakeMatrix(Input, Hidden), MakeMatrix(Input, Hidden)
|
|
|
+ DW2, DB2 := MakeMatrix(Hidden, Output), MakeMatrix(Hidden, Output)
|
|
|
+ DW1, DB1 := MakeMatrix(Input, Hidden), MakeMatrix(Input, Hidden)
|
|
|
for j := 0; j < Batch; j++ {
|
|
|
u := nodeId[rand.Intn(len(nodeId))]
|
|
|
GetEmbedding(G, u, 2, l, true)
|
|
|
- // GCN
|
|
|
- delta := MakeMatrix(1, Output).Sub(l[2].E)
|
|
|
- delta[0][G.L[u]] += 1
|
|
|
- StartCalc(&wg, DWo2, l[1].O, delta)
|
|
|
- StartCalc(&wg, DWi2, l[1].I, delta)
|
|
|
+ delta := MakeMatrix(1, Output)
|
|
|
+ delta[0][G.L[u]] = 1
|
|
|
+ delta.Sub(l[2].E).Divide(float64(Batch))
|
|
|
+ StartCalc(&wg, DW2, l[1].A, delta)
|
|
|
StartCalc(&wg, DB2, l[1].E, delta)
|
|
|
delta = delta.Multiply(l[2].p.B.Transpose())
|
|
|
for k := 0; k < Hidden; k++ {
|
|
|
@@ -134,18 +143,14 @@ func Train(G Graph) []Layer {
|
|
|
delta[0][k] = 0
|
|
|
}
|
|
|
}
|
|
|
- StartCalc(&wg, DWo1, l[0].O, delta)
|
|
|
- StartCalc(&wg, DWi1, l[0].I, delta)
|
|
|
+ StartCalc(&wg, DW1, l[0].A, delta)
|
|
|
StartCalc(&wg, DB1, l[0].E, delta)
|
|
|
- // GAT
|
|
|
wg.Wait()
|
|
|
}
|
|
|
- StartRefine(&wg, l[2].p.Wo, DWo2, float64(Batch)/RateWo)
|
|
|
- StartRefine(&wg, l[2].p.Wi, DWi2, float64(Batch)/RateWi)
|
|
|
- StartRefine(&wg, l[2].p.B, DB2, float64(Batch)/RateB)
|
|
|
- StartRefine(&wg, l[1].p.Wo, DWo1, float64(Batch)/RateWo)
|
|
|
- StartRefine(&wg, l[1].p.Wi, DWi1, float64(Batch)/RateWi)
|
|
|
- StartRefine(&wg, l[1].p.B, DB1, float64(Batch)/RateB)
|
|
|
+ StartRefine(&wg, l[2].p.W, DW2, 1/Rate)
|
|
|
+ StartRefine(&wg, l[2].p.B, DB2, 1/Rate)
|
|
|
+ StartRefine(&wg, l[1].p.W, DW1, 1/Rate)
|
|
|
+ StartRefine(&wg, l[1].p.B, DB1, 1/Rate)
|
|
|
wg.Wait()
|
|
|
}
|
|
|
return l
|