Skip to content

Commit

Permalink
обучение распознаванию крестика
Browse files Browse the repository at this point in the history
  • Loading branch information
kpmy committed Sep 13, 2015
1 parent 10f1dc3 commit 629701b
Show file tree
Hide file tree
Showing 9 changed files with 301 additions and 81 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,3 @@ _testmain.go
*.exe
*.test
*.prof
*.pc
Binary file added gone.to/0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added gone.to/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added gone.to/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
172 changes: 96 additions & 76 deletions gone.to/main.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package main

import (
"encoding/json"
"github.com/kpmy/ypk/assert"
"gone/perc"
"gone/perc/std"
"io"
"github.com/kpmy/ypk/fn"
"gone/model"
"gone/model/proc"
"gone/model/std"
"image"
"image/color"
_ "image/png"
"log"
"math/rand"
"os"
"time"
)

const (
Expand All @@ -23,97 +27,113 @@ func init() {
log.SetFlags(0)
}

type Link struct {
NodeId int `json:"node"`
LinkId int `json:"out"`
}
func generate() *model.Layer {
rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
s := std.New(proc.Sensoric, Nsens, MaxSensOut, func() int {
x := rnd.Intn(2)
if x == 0 {
return 1
} else {
return -1
}
})
a := std.New(proc.Associative, Nass, Nreact, func() int { return rnd.Intn(201) - 100 })
r := std.New(proc.Reactive, Nreact, 1, nil)

type NodeStruct struct {
Outs []int `json:"out"`
Ins []Link `json:"in,omitempty"`
std.Join(s, a)
std.Join(a, r)
return s
}

type LayerStruct struct {
Nodes []*NodeStruct `json:"node"`
}
const name = "pc"

func Store(wr io.Writer, first *model.Layer) error {
res := make([]*LayerStruct, 0)
for l := first; l != nil; l = l.Next {
next := &LayerStruct{}
for _, n := range l.Nodes {
node := &NodeStruct{}
for _, w := range n.Weights {
node.Outs = append(node.Outs, w)
}
for k, _ := range n.In {
link := Link{NodeId: k.NodeId, LinkId: k.LinkId}
node.Ins = append(node.Ins, link)
func main() {
var s, r *model.Layer
if _, err := os.Stat(name); os.IsNotExist(err) {
s = generate()

if f, err := os.Create(name); err == nil {
if err := std.Store(f, s); err != nil {
log.Fatal(err)
}
next.Nodes = append(next.Nodes, node)
f.Close()
}
res = append(res, next)
} else {
log.Println("file exists")
}
return json.NewEncoder(wr).Encode(res)
}

func Load(rd io.Reader) (ret *model.Layer, err error) {
ll := make([]LayerStruct, 0)
if err = json.NewDecoder(rd).Decode(ll); err == nil {
var this *model.Layer
for _, l := range ll {
if ret == nil {
this = &model.Layer{}
ret = this
} else {
this.Next = &model.Layer{}
this = this.Next
}
for _, n := range l.Nodes {
node := model.NewNode()
for _, w := range n.Outs {
node.Weights = append(node.Weights, w)
}
node.Out = make([]interface{}, len(node.Weights))
for _, l := range n.Ins {
link := model.Link{LinkId: l.LinkId, NodeId: l.NodeId}
node.In[link] = nil
}
this.Nodes = append(this.Nodes, node)
}
if f, err := os.Open(name); err == nil {
defer f.Close()
if s, err = std.Load(f); err != nil {
log.Fatal(err)
}
}
return
}
white := color.RGBA{R: 0xff, G: 0xFF, B: 0xFF, A: 0xFF}
if fi, err := os.Open("0.png"); err == nil {
if i, _, err := image.Decode(fi); err == nil {
j := 0
log.Println("image", i.Bounds())
for y := i.Bounds().Min.Y; y < i.Bounds().Max.Y; y++ {
for x := i.Bounds().Min.X; x < i.Bounds().Max.X; x++ {
c := i.At(x, y)
if c == white {
s.Nodes[j].In[model.Link{NodeId: 0, LinkId: 0}] = 1
} else {
s.Nodes[j].In[model.Link{NodeId: 0, LinkId: 0}] = 0
}
j++
}
}

func main() {
s := std.New(Nsens, MaxSensOut, func() int {
x := rand.Intn(2)
if x == 0 {
return 1
} else {
return -1
log.Fatal(err)
}
})
a := std.New(Nass, Nreact, func() int { return rand.Intn(201) - 100 })
r := std.New(Nreact, 1, nil)

std.Join(s, a)
std.Join(a, r)
} else {
log.Fatal(err)
}

log.Println(s)
/* for _, n := range s.Nodes {
n.In[model.Link{NodeId: 0, LinkId: 0}] = rand.Intn(2)
} */
t := make([]int, Nreact)
for i := 0; i < len(t); i++ {
t[i] = -1
}
t[0] = 1

if f, err := os.Create("0.pc"); err == nil {
Store(f, s)
f.Close()
for stop := false; !stop; { //autolearn for t pattern
for l := s; !fn.IsNil(l); l = l.Next {
proc.Process(l)
if l.Next != nil {
proc.Transfer(l)
} else {
r = l
}
}
a := make([]int, Nreact)
for i, n := range r.Nodes {
a[i] = n.Out[0].(int)
}
log.Println(t)
log.Println(a)
stop = true
for i, _ := range t {
switch {
case t[i] == 1 && a[i] == 1: //ok
case t[i] == 1 && a[i] != t[i]:
std.Update(s.Next, r.Nodes[i].In, 1)
stop = false
case t[i] == -1 && a[i] != t[i]:
std.Update(s.Next, r.Nodes[i].In, -1)
stop = false
}
}
}

if f, err := os.Open("0.pc"); err == nil {
if s, err = Load(f); err != nil {
if f, err := os.Create(name + ".0"); err == nil {
if err := std.Store(f, s); err != nil {
log.Fatal(err)
}
f.Close()
}

log.Println(s)
}
3 changes: 2 additions & 1 deletion perc/model.go → model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ type Node struct {
}

func (n *Node) String() string {
return fmt.Sprint("<", n.In, "->", len(n.Out), ">")
return fmt.Sprint("<", len(n.In), "->", len(n.Out), ">")
}

type Layer struct {
Nodes []*Node
Role string
Next *Layer
}

Expand Down
123 changes: 123 additions & 0 deletions model/proc/proc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package proc

import (
"github.com/kpmy/ypk/assert"
"github.com/kpmy/ypk/fn"
"github.com/kpmy/ypk/halt"
"gone/model"
"sync"
)

const (
Sensoric = "sensor"
Associative = "assoc"
Reactive = "react"
)

var fm map[string]func(*model.Node)

var defLink model.Link = model.Link{NodeId: 0, LinkId: 0}

func init() {
fm = make(map[string]func(*model.Node))

fm[Sensoric] = func(n *model.Node) {
v := n.In[defLink].(int)
for i, w := range n.Weights {
n.Out[i] = Sfunc(w, v)
}
}

fm[Associative] = func(n *model.Node) {
var vl []int
for _, v := range n.In {
vl = append(vl, v.(int))
}
v := Afunc(vl...)
for i, w := range n.Weights {
n.Out[i] = Afuncw(w, v)
}
}
fm[Reactive] = func(n *model.Node) {
var vl []int
for _, v := range n.In {
vl = append(vl, v.(int))
}
n.Out[0] = Rfunc(vl...)
}
}

func Sfunc(weight, signal int) int {
return weight * signal
}

func Afunc(signal ...int) int {
var r int
for _, x := range signal {
r = r + x
}
if r >= 8 {
r = 1
} else {
r = 0
}
return r
}

func Afuncw(weight, signal int) int {
return weight * signal
}

func Rfunc(signal ...int) int {
//log.Println(signal)
var r int
for _, x := range signal {
r = r + x
}
if r > 0 {
r = 1
} else if r < 0 {
r = -1
} else {
r = 0
}
return r
}

func Process(l *model.Layer) {
assert.For(l != nil, 20)
if fn, ok := fm[l.Role]; ok {
wg := new(sync.WaitGroup)
for _, n := range l.Nodes {
wg.Add(1)
go func(n *model.Node) {
fn(n)
wg.Done()
}(n)
}
wg.Wait()
} else {
halt.As(100, l.Role)
}
}

func Transfer(l *model.Layer) {
assert.For(l != nil && l.Next != nil, 20)
wg := new(sync.WaitGroup)
for _, n := range l.Next.Nodes {
wg.Add(1)
go func(n *model.Node) {
tmp := make(map[model.Link]interface{})
for k, _ := range n.In {
v := l.Nodes[k.NodeId].Out[k.LinkId]
if fn.IsNil(v) {
halt.As(100, k)
}
tmp[k] = v
}
n.In = tmp
wg.Done()
}(n)
}
wg.Wait()
}
Loading

0 comments on commit 629701b

Please sign in to comment.