WIP(example/yolo)
This commit is contained in:
parent
565be523db
commit
a146032afa
|
@ -1 +0,0 @@
|
|||
package main
|
|
@ -1,595 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
black, red bool = true, false
|
||||
)
|
||||
|
||||
// Tree is a tree container that holds TNode elements
|
||||
type Tree struct {
|
||||
Root *Node
|
||||
size int
|
||||
Comparator Comparator
|
||||
}
|
||||
|
||||
// Node is a tree element
|
||||
type Node struct {
|
||||
Key interface{}
|
||||
Value interface{}
|
||||
Left *Node
|
||||
Right *Node
|
||||
Parent *Node
|
||||
color bool
|
||||
}
|
||||
|
||||
// NewTree creates a tree with a specified comparator
|
||||
func NewTree(c Comparator) *Tree {
|
||||
return &Tree{
|
||||
Root: nil,
|
||||
Comparator: c,
|
||||
size: 0,
|
||||
}
|
||||
}
|
||||
|
||||
// Put inserts a node to tree
|
||||
func (t *Tree) Put(k interface{}, v interface{}) (err error) {
|
||||
var insertedNode *Node
|
||||
|
||||
if t.Root == nil {
|
||||
t.Comparator = t.Comparator.Init()
|
||||
t.Root = &Node{Key: k, Value: v, color: red}
|
||||
insertedNode = t.Root
|
||||
} else {
|
||||
node := t.Root
|
||||
|
||||
var loop bool = true
|
||||
for loop {
|
||||
switch t.Comparator.Compare(k, node.Key) {
|
||||
case 0:
|
||||
node.Key = k
|
||||
node.Value = v
|
||||
return
|
||||
case -1:
|
||||
if node.Left == nil {
|
||||
node.Left = &Node{Key: k, Value: v, color: red}
|
||||
insertedNode = node.Left
|
||||
loop = false
|
||||
} else {
|
||||
node = node.Left
|
||||
}
|
||||
case 1:
|
||||
if node.Right == nil {
|
||||
node.Right = &Node{Key: k, Value: v, color: red}
|
||||
insertedNode = node.Right
|
||||
loop = false
|
||||
} else {
|
||||
node = node.Right
|
||||
}
|
||||
}
|
||||
} // end of for loop
|
||||
|
||||
insertedNode.Parent = node
|
||||
}
|
||||
|
||||
t.insertCase1(insertedNode)
|
||||
t.size++
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MustPut inserts new node. It will panic if err occurs.
|
||||
func (t *Tree) MustPut(k interface{}, v interface{}) {
|
||||
err := t.Put(k, v)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Get returns a corresponding value for specified key. If not found, returns
|
||||
// nil.
|
||||
func (t *Tree) Get(k interface{}) (retVal interface{}, found bool) {
|
||||
node := t.lookup(k)
|
||||
if node == nil {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return node.Value, true
|
||||
}
|
||||
|
||||
func (t *Tree) Remove(k interface{}) (err error) {
|
||||
var child *Node
|
||||
|
||||
node := t.lookup(k)
|
||||
if node == nil {
|
||||
err = fmt.Errorf("Node not found for specified key (%v)\n", k)
|
||||
return err
|
||||
}
|
||||
|
||||
if node.Left != nil && node.Right != nil {
|
||||
pred := node.maximumNode()
|
||||
node.Key = pred.Key
|
||||
node.Value = pred.Value
|
||||
node = pred
|
||||
}
|
||||
|
||||
if node.Left != nil || node.Right != nil {
|
||||
if node.Right == nil {
|
||||
child = node.Left
|
||||
} else {
|
||||
child = node.Right
|
||||
}
|
||||
|
||||
if node.color == black {
|
||||
node.color = nodeColor(child)
|
||||
t.deleteCase1(node)
|
||||
}
|
||||
|
||||
t.replaceNode(node, child)
|
||||
|
||||
if node.Parent == nil && child != nil {
|
||||
child.color = black
|
||||
}
|
||||
}
|
||||
|
||||
t.size--
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsEmpty returns whether tree is empty
|
||||
func (t *Tree) IsEmpty() (retVal bool) {
|
||||
return t.size == 0
|
||||
}
|
||||
|
||||
// Size returns number of nodes in tree
|
||||
func (t *Tree) Size() (retVal int) {
|
||||
return t.size
|
||||
}
|
||||
|
||||
// Keys returns all keys (in order)
|
||||
func (t *Tree) Keys() (retVal []interface{}) {
|
||||
keys := make([]interface{}, t.size)
|
||||
iter := t.Iterator()
|
||||
for i := 0; iter.Next(); i++ {
|
||||
keys[i] = iter.Key()
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
// Values returns all values of tree
|
||||
func (t *Tree) Values() (retVal []interface{}) {
|
||||
vals := make([]interface{}, t.size)
|
||||
iter := t.Iterator()
|
||||
for i := 0; iter.Next(); i++ {
|
||||
vals[i] = iter.Value()
|
||||
}
|
||||
|
||||
return vals
|
||||
}
|
||||
|
||||
// Left returns the left-most (min) node or nil if tree is empty.
|
||||
func (t *Tree) Left() *Node {
|
||||
var parent *Node
|
||||
current := t.Root
|
||||
for current != nil {
|
||||
parent = current
|
||||
current = current.Left
|
||||
}
|
||||
return parent
|
||||
}
|
||||
|
||||
// Right returns the right-most (max) node or nil if tree is empty.
|
||||
func (t *Tree) Right() *Node {
|
||||
var parent *Node
|
||||
current := t.Root
|
||||
for current != nil {
|
||||
parent = current
|
||||
current = current.Right
|
||||
}
|
||||
return parent
|
||||
}
|
||||
|
||||
// Floor finds floor node of the input key.
|
||||
//
|
||||
// NOTE: `floor node` is defined as the largest node that is smaller or equal
|
||||
// to given node. There may be no floor node if the tree is empty or all nodes
|
||||
// in the tree are larger than the given node.
|
||||
func (t *Tree) Floor(k interface{}) (retVal *Node, found bool) {
|
||||
found = false
|
||||
root := t.Root
|
||||
|
||||
for root != nil {
|
||||
switch t.Comparator.Compare(k, root.Key) {
|
||||
case 0:
|
||||
return root, true
|
||||
case -1:
|
||||
root = root.Left
|
||||
case 1:
|
||||
retVal, found = root, true
|
||||
root = root.Right
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return retVal, found
|
||||
}
|
||||
|
||||
// Ceil returns the ceiling node of the input node.
|
||||
//
|
||||
// Ceiling node is defined as the smallest node that is larger or
|
||||
// equal to the given node. There may not have a ceiling node if
|
||||
// tree is empty or all other nodes in the tree are smaller than
|
||||
// the given node.
|
||||
func (t *Tree) Ceil(k interface{}) (retVal *Node, found bool) {
|
||||
found = false
|
||||
root := t.Root
|
||||
|
||||
for root != nil {
|
||||
switch t.Comparator.Compare(k, root.Key) {
|
||||
case 0:
|
||||
return root, true
|
||||
case -1:
|
||||
retVal, found = root, true
|
||||
root = root.Left
|
||||
case 1:
|
||||
root = root.Right
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return retVal, found
|
||||
}
|
||||
|
||||
// Clear deletes all nodes
|
||||
func (t *Tree) Clear() {
|
||||
t.Root = nil
|
||||
t.size = 0
|
||||
}
|
||||
|
||||
// String returns a string representation of the tree.
|
||||
func (t *Tree) String() (retVal string) {
|
||||
str := "BinaryTree\n"
|
||||
|
||||
if !t.IsEmpty() {
|
||||
output(t.Root, "", true, &str)
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
// Node methods:
|
||||
//==============
|
||||
|
||||
func (n *Node) String() (retVal string) {
|
||||
return fmt.Sprintf("%v", n.Key)
|
||||
}
|
||||
|
||||
func output(n *Node, prefix string, isTail bool, str *string) {
|
||||
if n.Right != nil {
|
||||
newPrefix := prefix
|
||||
if isTail {
|
||||
newPrefix += "│ "
|
||||
} else {
|
||||
newPrefix += " "
|
||||
}
|
||||
output(n.Right, newPrefix, false, str)
|
||||
}
|
||||
*str += prefix
|
||||
if isTail {
|
||||
*str += "└── "
|
||||
} else {
|
||||
*str += "┌── "
|
||||
}
|
||||
*str += n.String() + "\n"
|
||||
if n.Left != nil {
|
||||
newPrefix := prefix
|
||||
if isTail {
|
||||
newPrefix += " "
|
||||
} else {
|
||||
newPrefix += "│ "
|
||||
}
|
||||
output(n.Left, newPrefix, true, str)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tree) lookup(k interface{}) (retVal *Node) {
|
||||
root := t.Root
|
||||
|
||||
for root != nil {
|
||||
switch t.Comparator.Compare(k, root.Key) {
|
||||
case 0:
|
||||
return root
|
||||
case -1:
|
||||
root = root.Left
|
||||
case 1:
|
||||
root = root.Right
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *Node) grandparent() (retVal *Node) {
|
||||
if n != nil && n.Parent != nil {
|
||||
return n.Parent.Parent
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *Node) uncle() (retVal *Node) {
|
||||
if n == nil || n.Parent == nil || n.Parent.Parent == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return n.Parent.sibling()
|
||||
}
|
||||
|
||||
func (n *Node) sibling() (retVal *Node) {
|
||||
if n == nil || n.Parent == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if n == n.Parent.Left {
|
||||
return n.Parent.Right
|
||||
}
|
||||
|
||||
return n.Parent.Left
|
||||
}
|
||||
|
||||
func (t *Tree) rotateLeft(n *Node) {
|
||||
right := n.Right
|
||||
t.replaceNode(n, right)
|
||||
|
||||
n.Right = right.Left
|
||||
|
||||
if right.Left != nil {
|
||||
right.Left.Parent = n
|
||||
}
|
||||
|
||||
right.Left = n
|
||||
n.Parent = right
|
||||
}
|
||||
|
||||
func (t *Tree) rotateRight(n *Node) {
|
||||
left := n.Left
|
||||
t.replaceNode(n, left)
|
||||
n.Left = left.Right
|
||||
|
||||
if left.Right != nil {
|
||||
left.Right.Parent = n
|
||||
}
|
||||
|
||||
left.Right = n
|
||||
n.Parent = left
|
||||
}
|
||||
|
||||
func (t *Tree) replaceNode(old, new *Node) {
|
||||
if old.Parent == nil {
|
||||
t.Root = new
|
||||
} else {
|
||||
if old == old.Parent.Left {
|
||||
old.Parent.Left = new
|
||||
} else {
|
||||
old.Parent.Right = new
|
||||
}
|
||||
}
|
||||
|
||||
if new != nil {
|
||||
new.Parent = old.Parent
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tree) insertCase1(node *Node) {
|
||||
if node.Parent == nil {
|
||||
node.color = black
|
||||
} else {
|
||||
t.insertCase2(node)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tree) insertCase2(n *Node) {
|
||||
if nodeColor(n.Parent) == black {
|
||||
return
|
||||
}
|
||||
t.insertCase3(n)
|
||||
}
|
||||
|
||||
func (t *Tree) insertCase3(n *Node) {
|
||||
uncle := n.uncle()
|
||||
if nodeColor(uncle) == red {
|
||||
n.Parent.color = black
|
||||
uncle.color = black
|
||||
n.grandparent().color = red
|
||||
t.insertCase1(n.grandparent())
|
||||
} else {
|
||||
t.insertCase4(n)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tree) insertCase4(n *Node) {
|
||||
grandparent := n.grandparent()
|
||||
if n == n.Parent.Right && n.Parent == grandparent.Left {
|
||||
t.rotateLeft(n.Parent)
|
||||
n = n.Left
|
||||
} else if n == n.Parent.Left && n.Parent == grandparent.Right {
|
||||
t.rotateRight(n.Parent)
|
||||
n = n.Right
|
||||
}
|
||||
t.insertCase5(n)
|
||||
}
|
||||
|
||||
func (t *Tree) insertCase5(n *Node) {
|
||||
n.Parent.color = black
|
||||
grandparent := n.grandparent()
|
||||
grandparent.color = red
|
||||
if n == n.Parent.Left && n.Parent == grandparent.Left {
|
||||
t.rotateRight(grandparent)
|
||||
} else if n == n.Parent.Right && n.Parent == grandparent.Right {
|
||||
t.rotateLeft(grandparent)
|
||||
}
|
||||
}
|
||||
|
||||
func (n *Node) maximumNode() (retVal *Node) {
|
||||
if n == nil {
|
||||
return nil
|
||||
}
|
||||
for n.Right != nil {
|
||||
n = n.Right
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (t *Tree) deleteCase1(n *Node) {
|
||||
if n.Parent == nil {
|
||||
return
|
||||
}
|
||||
t.deleteCase2(n)
|
||||
}
|
||||
|
||||
func (t *Tree) deleteCase2(n *Node) {
|
||||
sibling := n.sibling()
|
||||
if nodeColor(sibling) == red {
|
||||
n.Parent.color = red
|
||||
sibling.color = black
|
||||
if n == n.Parent.Left {
|
||||
t.rotateLeft(n.Parent)
|
||||
} else {
|
||||
t.rotateRight(n.Parent)
|
||||
}
|
||||
}
|
||||
t.deleteCase3(n)
|
||||
}
|
||||
|
||||
func (t *Tree) deleteCase3(n *Node) {
|
||||
sibling := n.sibling()
|
||||
if nodeColor(n.Parent) == black &&
|
||||
nodeColor(sibling) == black &&
|
||||
nodeColor(sibling.Left) == black &&
|
||||
nodeColor(sibling.Right) == black {
|
||||
sibling.color = red
|
||||
t.deleteCase1(n.Parent)
|
||||
} else {
|
||||
t.deleteCase4(n)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tree) deleteCase4(n *Node) {
|
||||
sibling := n.sibling()
|
||||
if nodeColor(n.Parent) == red &&
|
||||
nodeColor(sibling) == black &&
|
||||
nodeColor(sibling.Left) == black &&
|
||||
nodeColor(sibling.Right) == black {
|
||||
sibling.color = red
|
||||
n.Parent.color = black
|
||||
} else {
|
||||
t.deleteCase5(n)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tree) deleteCase5(n *Node) {
|
||||
sibling := n.sibling()
|
||||
if n == n.Parent.Left &&
|
||||
nodeColor(sibling) == black &&
|
||||
nodeColor(sibling.Left) == red &&
|
||||
nodeColor(sibling.Right) == black {
|
||||
sibling.color = red
|
||||
sibling.Left.color = black
|
||||
t.rotateRight(sibling)
|
||||
} else if n == n.Parent.Right &&
|
||||
nodeColor(sibling) == black &&
|
||||
nodeColor(sibling.Right) == red &&
|
||||
nodeColor(sibling.Left) == black {
|
||||
sibling.color = red
|
||||
sibling.Right.color = black
|
||||
t.rotateLeft(sibling)
|
||||
}
|
||||
t.deleteCase6(n)
|
||||
}
|
||||
|
||||
func (t *Tree) deleteCase6(n *Node) {
|
||||
sibling := n.sibling()
|
||||
sibling.color = nodeColor(n.Parent)
|
||||
n.Parent.color = black
|
||||
if n == n.Parent.Left && nodeColor(sibling.Right) == red {
|
||||
sibling.Right.color = black
|
||||
t.rotateLeft(n.Parent)
|
||||
} else if nodeColor(sibling.Left) == red {
|
||||
sibling.Left.color = black
|
||||
t.rotateRight(n.Parent)
|
||||
}
|
||||
}
|
||||
|
||||
func nodeColor(n *Node) bool {
|
||||
if n == nil {
|
||||
return black
|
||||
}
|
||||
return n.color
|
||||
}
|
||||
|
||||
// ToJSON outputs the JSON representation of the tree.
|
||||
func (t *Tree) ToJSON() ([]byte, error) {
|
||||
elements := make(map[string]interface{})
|
||||
it := t.Iterator()
|
||||
for it.Next() {
|
||||
elements[toString(it.Key())] = it.Value()
|
||||
}
|
||||
return json.Marshal(&elements)
|
||||
}
|
||||
|
||||
// FromJSON populates the tree from the input JSON representation.
|
||||
func (t *Tree) FromJSON(data []byte) error {
|
||||
elements := make(map[string]interface{})
|
||||
err := json.Unmarshal(data, &elements)
|
||||
if err == nil {
|
||||
t.Clear()
|
||||
for key, value := range elements {
|
||||
t.Put(key, value)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// ToString converts a value to string.
|
||||
func toString(value interface{}) string {
|
||||
switch value := value.(type) {
|
||||
case string:
|
||||
return value
|
||||
case int8:
|
||||
return strconv.FormatInt(int64(value), 10)
|
||||
case int16:
|
||||
return strconv.FormatInt(int64(value), 10)
|
||||
case int32:
|
||||
return strconv.FormatInt(int64(value), 10)
|
||||
case int64:
|
||||
return strconv.FormatInt(int64(value), 10)
|
||||
case uint8:
|
||||
return strconv.FormatUint(uint64(value), 10)
|
||||
case uint16:
|
||||
return strconv.FormatUint(uint64(value), 10)
|
||||
case uint32:
|
||||
return strconv.FormatUint(uint64(value), 10)
|
||||
case uint64:
|
||||
return strconv.FormatUint(uint64(value), 10)
|
||||
case float32:
|
||||
return strconv.FormatFloat(float64(value), 'g', -1, 64)
|
||||
case float64:
|
||||
return strconv.FormatFloat(float64(value), 'g', -1, 64)
|
||||
case bool:
|
||||
return strconv.FormatBool(value)
|
||||
default:
|
||||
return fmt.Sprintf("%+v", value)
|
||||
}
|
||||
}
|
|
@ -1,214 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type Comparator struct{}
|
||||
|
||||
// Init initiates a Comparator object
|
||||
func (c Comparator) Init() Comparator {
|
||||
return Comparator{}
|
||||
}
|
||||
|
||||
// Comparator compares 2 input a and b of generic type.
|
||||
// It returns an interger result
|
||||
// - 0: a == b
|
||||
// - negative: a < b
|
||||
// - positive: a > b
|
||||
// Will be panic if a or be is not of asserted type.
|
||||
// func (c Comparator) Compare(a, b interface{}) (retVal int) {
|
||||
func (c Comparator) Compare(a, b interface{}) (retVal int) {
|
||||
if reflect.TypeOf(a) != reflect.TypeOf(b) {
|
||||
log.Fatalf("Expected a and b of the same type. Got a type: %v, b type: %v", reflect.TypeOf(a).Kind(), reflect.TypeOf(b).Kind())
|
||||
}
|
||||
|
||||
typ := reflect.TypeOf(a)
|
||||
|
||||
switch typ.Name() {
|
||||
case "string":
|
||||
return compareString(a.(string), b.(string))
|
||||
case "uint":
|
||||
return compareUint(a.(uint), b.(uint))
|
||||
case "uint8": // including `Byte` type
|
||||
return compareUint8(a.(uint8), b.(uint8))
|
||||
case "uint16":
|
||||
return compareUint16(a.(uint16), b.(uint16))
|
||||
case "uint32": // including `Rune` type
|
||||
return compareUint32(a.(uint32), b.(uint32))
|
||||
case "uint64":
|
||||
return compareUint64(a.(uint64), b.(uint64))
|
||||
case "int":
|
||||
return compareInt(a.(int), b.(int))
|
||||
case "int8":
|
||||
return compareInt8(a.(int8), b.(int8))
|
||||
case "int16":
|
||||
return compareInt16(a.(int16), b.(int16))
|
||||
case "int32":
|
||||
return compareInt32(a.(int32), b.(int32))
|
||||
case "int64":
|
||||
return compareInt64(a.(int64), b.(int64))
|
||||
case "float32":
|
||||
return compareFloat32(a.(float32), b.(float32))
|
||||
case "float64":
|
||||
return compareFloat64(a.(float64), b.(float64))
|
||||
default:
|
||||
log.Fatalf("Unsupported a type(%v) or b type(%v).\n", reflect.TypeOf(a).Kind(), reflect.TypeOf(b).Kind())
|
||||
}
|
||||
|
||||
return retVal
|
||||
}
|
||||
|
||||
func compareString(a, b string) (retVal int) {
|
||||
min := len(b)
|
||||
if len(a) < len(b) {
|
||||
min = len(a)
|
||||
}
|
||||
diff := 0
|
||||
for i := 0; i < min && diff == 0; i++ {
|
||||
diff = int(a[i]) - int(b[i])
|
||||
}
|
||||
if diff == 0 {
|
||||
diff = len(a) - len(b)
|
||||
}
|
||||
if diff < 0 {
|
||||
return -1
|
||||
}
|
||||
if diff > 0 {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func compareUint(a, b uint) (retVal int) {
|
||||
switch {
|
||||
case a > b:
|
||||
return 1
|
||||
case a < b:
|
||||
return -1
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func compareUint8(a, b uint8) (retVal int) {
|
||||
switch {
|
||||
case a > b:
|
||||
return 1
|
||||
case a < b:
|
||||
return -1
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func compareUint16(a, b uint16) (retVal int) {
|
||||
switch {
|
||||
case a > b:
|
||||
return 1
|
||||
case a < b:
|
||||
return -1
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func compareUint32(a, b uint32) (retVal int) {
|
||||
switch {
|
||||
case a > b:
|
||||
return 1
|
||||
case a < b:
|
||||
return -1
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func compareUint64(a, b uint64) (retVal int) {
|
||||
switch {
|
||||
case a > b:
|
||||
return 1
|
||||
case a < b:
|
||||
return -1
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func compareInt(a, b int) (retVal int) {
|
||||
switch {
|
||||
case a > b:
|
||||
return 1
|
||||
case a < b:
|
||||
return -1
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func compareInt8(a, b int8) (retVal int) {
|
||||
switch {
|
||||
case a > b:
|
||||
return 1
|
||||
case a < b:
|
||||
return -1
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func compareInt16(a, b int16) (retVal int) {
|
||||
switch {
|
||||
case a > b:
|
||||
return 1
|
||||
case a < b:
|
||||
return -1
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func compareInt32(a, b int32) (retVal int) {
|
||||
switch {
|
||||
case a > b:
|
||||
return 1
|
||||
case a < b:
|
||||
return -1
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func compareInt64(a, b int64) (retVal int) {
|
||||
switch {
|
||||
case a > b:
|
||||
return 1
|
||||
case a < b:
|
||||
return -1
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func compareFloat32(a, b float32) (retVal int) {
|
||||
switch {
|
||||
case a > b:
|
||||
return 1
|
||||
case a < b:
|
||||
return -1
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func compareFloat64(a, b float64) (retVal int) {
|
||||
switch {
|
||||
case a > b:
|
||||
return 1
|
||||
case a < b:
|
||||
return -1
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
|
@ -1,6 +1,247 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/sugarme/gotch/nn"
|
||||
ts "github.com/sugarme/gotch/tensor"
|
||||
)
|
||||
|
||||
type block struct {
|
||||
blockType string
|
||||
// parameters
|
||||
blockType *string // optional
|
||||
parameters map[string]string
|
||||
}
|
||||
|
||||
func (b block) get(key string) (retVal string) {
|
||||
val, ok := b.parameters[key]
|
||||
if !ok {
|
||||
log.Fatalf("Cannot find %v in net parameters.\n", key)
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
type Darknet struct {
|
||||
blocks []block
|
||||
parameters map[string]string
|
||||
}
|
||||
|
||||
func (d Darknet) get(key string) (retVal string) {
|
||||
val, ok := d.parameters[key]
|
||||
if !ok {
|
||||
log.Fatalf("Cannot find %v in net parameters.\n", key)
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
type accumulator struct {
|
||||
parameters map[string]string
|
||||
net Darknet
|
||||
blockType *string // optional
|
||||
}
|
||||
|
||||
func newAccumulator() (retVal accumulator) {
|
||||
|
||||
return accumulator{
|
||||
blockType: nil,
|
||||
parameters: make(map[string]string, 0),
|
||||
net: Darknet{
|
||||
blocks: make([]block, 0),
|
||||
parameters: make(map[string]string, 0),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (acc *accumulator) finishBlock() {
|
||||
if acc.blockType != nil {
|
||||
if *acc.blockType == "net" {
|
||||
acc.net.parameters = acc.parameters
|
||||
} else {
|
||||
block := block{
|
||||
blockType: acc.blockType,
|
||||
parameters: acc.parameters,
|
||||
}
|
||||
acc.net.blocks = append(acc.net.blocks, block)
|
||||
}
|
||||
|
||||
// clear parameters
|
||||
acc.parameters = make(map[string]string, 0)
|
||||
}
|
||||
|
||||
acc.blockType = nil
|
||||
}
|
||||
|
||||
func ParseConfig(path string) (retVal Darknet) {
|
||||
|
||||
acc := newAccumulator()
|
||||
|
||||
var lines []string
|
||||
|
||||
// Read file line by line
|
||||
// Ref. https://stackoverflow.com/questions/8757389
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
lines = append(lines, line)
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, line := range lines {
|
||||
|
||||
if line == "" || strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
}
|
||||
line = strings.TrimSpace(line)
|
||||
|
||||
if strings.HasPrefix(line, "[") {
|
||||
// make sure line ends with "]"
|
||||
if !strings.HasSuffix(line, "]") {
|
||||
log.Fatalf("Line doesn't end with ']'\n")
|
||||
}
|
||||
|
||||
line = strings.TrimPrefix(line, "[")
|
||||
line = strings.TrimSuffix(line, "]")
|
||||
|
||||
acc.finishBlock()
|
||||
acc.blockType = &line
|
||||
} else {
|
||||
var keyValue []string
|
||||
keyValue = strings.Split(line, "=")
|
||||
if len(keyValue) != 2 {
|
||||
log.Fatalf("Missing equal for line: %v\n", line)
|
||||
}
|
||||
|
||||
// // Ensure key does not exist
|
||||
// if _, ok := acc.parameters[keyValue[0]]; ok {
|
||||
// log.Fatalf("Multiple values for key - %v\n", line)
|
||||
// }
|
||||
|
||||
acc.parameters[keyValue[0]] = keyValue[1]
|
||||
|
||||
}
|
||||
} // end of for
|
||||
|
||||
acc.finishBlock()
|
||||
|
||||
return acc.net
|
||||
}
|
||||
|
||||
type (
|
||||
Layer = ts.ModuleT
|
||||
Route = []uint
|
||||
Shortcut = uint
|
||||
Yolo struct {
|
||||
V1 int64
|
||||
V2 []int64
|
||||
}
|
||||
)
|
||||
|
||||
func conv(vs nn.Path, index uint, p int64, b block) (retVal1 int64, retVal2 interface{}) {
|
||||
|
||||
activation := b.get("activation")
|
||||
|
||||
filters, err := strconv.ParseInt(b.get("filters"), 10, 64)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
pad, err := strconv.ParseInt(b.get("pad"), 10, 64)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
size, err := strconv.ParseInt(b.get("size"), 10, 64)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
stride, err := strconv.ParseInt(b.get("stride"), 10, 64)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if pad != 0 {
|
||||
pad = (size - 1) / 2
|
||||
} else {
|
||||
pad = 0
|
||||
}
|
||||
|
||||
var (
|
||||
bn *nn.BatchNorm
|
||||
bias bool
|
||||
)
|
||||
if pStr, ok := b.parameters["batch_normalize"]; ok {
|
||||
p, err := strconv.ParseInt(pStr, 10, 64)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if p != 0 {
|
||||
sub := vs.Sub(fmt.Sprintf("batch_norm_%v", index))
|
||||
bnVal := nn.BatchNorm2D(sub, filters, nn.DefaultBatchNormConfig())
|
||||
bn = &bnVal
|
||||
bias = false
|
||||
}
|
||||
} else {
|
||||
bn = nil
|
||||
bias = true
|
||||
}
|
||||
|
||||
convConfig := nn.DefaultConv2DConfig()
|
||||
convConfig.Stride = []int64{stride, stride}
|
||||
convConfig.Padding = []int64{pad, pad}
|
||||
convConfig.Bias = bias
|
||||
|
||||
conv := nn.NewConv2D(vs.Sub(fmt.Sprintf("conv_%v", index)), p, filters, size, convConfig)
|
||||
|
||||
var leaky bool
|
||||
switch activation {
|
||||
case "leaky":
|
||||
leaky = true
|
||||
case "linear":
|
||||
leaky = false
|
||||
default:
|
||||
log.Fatalf("Unsupported activation(%v)\n", activation)
|
||||
}
|
||||
|
||||
fn := nn.NewFuncT(func(xs ts.Tensor, train bool) (res ts.Tensor) {
|
||||
tmp1 := xs.Apply(conv)
|
||||
|
||||
var tmp2 ts.Tensor
|
||||
|
||||
if bn != nil {
|
||||
tmp2 = tmp1.ApplyT(*bn, train)
|
||||
tmp1.MustDrop()
|
||||
} else {
|
||||
tmp2 = tmp1
|
||||
}
|
||||
|
||||
if leaky {
|
||||
tmp2Mul := tmp2.MustMul1(ts.FloatScalar(0.1), false)
|
||||
res = tmp2.MustMax1(tmp2Mul)
|
||||
tmp2Mul.MustDrop()
|
||||
tmp2.MustDrop()
|
||||
} else {
|
||||
res = tmp2
|
||||
}
|
||||
|
||||
return res
|
||||
})
|
||||
|
||||
return filters, fn
|
||||
}
|
||||
|
|
|
@ -1,151 +0,0 @@
|
|||
package main
|
||||
|
||||
// Iterator holding the iterator's state
|
||||
type Iterator struct {
|
||||
tree *Tree
|
||||
node *Node
|
||||
position position
|
||||
}
|
||||
|
||||
type position byte
|
||||
|
||||
const (
|
||||
begin, between, end position = 0, 1, 2
|
||||
)
|
||||
|
||||
// Iterator returns a stateful iterator whose elements are key/value pairs.
|
||||
func (tree *Tree) Iterator() Iterator {
|
||||
return Iterator{tree: tree, node: nil, position: begin}
|
||||
}
|
||||
|
||||
// IteratorAt returns a stateful iterator whose elements are key/value pairs that is initialised at a particular node.
|
||||
func (tree *Tree) IteratorAt(node *Node) Iterator {
|
||||
return Iterator{tree: tree, node: node, position: between}
|
||||
}
|
||||
|
||||
// Next moves the iterator to the next element and returns true if there was a next element in the container.
|
||||
// If Next() returns true, then next element's key and value can be retrieved by Key() and Value().
|
||||
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Next() bool {
|
||||
if iterator.position == end {
|
||||
goto end
|
||||
}
|
||||
if iterator.position == begin {
|
||||
left := iterator.tree.Left()
|
||||
if left == nil {
|
||||
goto end
|
||||
}
|
||||
iterator.node = left
|
||||
goto between
|
||||
}
|
||||
if iterator.node.Right != nil {
|
||||
iterator.node = iterator.node.Right
|
||||
for iterator.node.Left != nil {
|
||||
iterator.node = iterator.node.Left
|
||||
}
|
||||
goto between
|
||||
}
|
||||
if iterator.node.Parent != nil {
|
||||
node := iterator.node
|
||||
for iterator.node.Parent != nil {
|
||||
iterator.node = iterator.node.Parent
|
||||
if iterator.tree.Comparator.Compare(node.Key, iterator.node.Key) <= 0 {
|
||||
goto between
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
iterator.node = nil
|
||||
iterator.position = end
|
||||
return false
|
||||
|
||||
between:
|
||||
iterator.position = between
|
||||
return true
|
||||
}
|
||||
|
||||
// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
|
||||
// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Prev() bool {
|
||||
if iterator.position == begin {
|
||||
goto begin
|
||||
}
|
||||
if iterator.position == end {
|
||||
right := iterator.tree.Right()
|
||||
if right == nil {
|
||||
goto begin
|
||||
}
|
||||
iterator.node = right
|
||||
goto between
|
||||
}
|
||||
if iterator.node.Left != nil {
|
||||
iterator.node = iterator.node.Left
|
||||
for iterator.node.Right != nil {
|
||||
iterator.node = iterator.node.Right
|
||||
}
|
||||
goto between
|
||||
}
|
||||
if iterator.node.Parent != nil {
|
||||
node := iterator.node
|
||||
for iterator.node.Parent != nil {
|
||||
iterator.node = iterator.node.Parent
|
||||
if iterator.tree.Comparator.Compare(node.Key, iterator.node.Key) >= 0 {
|
||||
goto between
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
begin:
|
||||
iterator.node = nil
|
||||
iterator.position = begin
|
||||
return false
|
||||
|
||||
between:
|
||||
iterator.position = between
|
||||
return true
|
||||
}
|
||||
|
||||
// Value returns the current element's value.
|
||||
// Does not modify the state of the iterator.
|
||||
func (iterator *Iterator) Value() interface{} {
|
||||
return iterator.node.Value
|
||||
}
|
||||
|
||||
// Key returns the current element's key.
|
||||
// Does not modify the state of the iterator.
|
||||
func (iterator *Iterator) Key() interface{} {
|
||||
return iterator.node.Key
|
||||
}
|
||||
|
||||
// Begin resets the iterator to its initial state (one-before-first)
|
||||
// Call Next() to fetch the first element if any.
|
||||
func (iterator *Iterator) Begin() {
|
||||
iterator.node = nil
|
||||
iterator.position = begin
|
||||
}
|
||||
|
||||
// End moves the iterator past the last element (one-past-the-end).
|
||||
// Call Prev() to fetch the last element if any.
|
||||
func (iterator *Iterator) End() {
|
||||
iterator.node = nil
|
||||
iterator.position = end
|
||||
}
|
||||
|
||||
// First moves the iterator to the first element and returns true if there was a first element in the container.
|
||||
// If First() returns true, then first element's key and value can be retrieved by Key() and Value().
|
||||
// Modifies the state of the iterator
|
||||
func (iterator *Iterator) First() bool {
|
||||
iterator.Begin()
|
||||
return iterator.Next()
|
||||
}
|
||||
|
||||
// Last moves the iterator to the last element and returns true if there was a last element in the container.
|
||||
// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().
|
||||
// Modifies the state of the iterator.
|
||||
func (iterator *Iterator) Last() bool {
|
||||
iterator.End()
|
||||
return iterator.Prev()
|
||||
}
|
|
@ -2,23 +2,26 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
// "flag"
|
||||
"log"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
const configName = "yolo-v3.cfg"
|
||||
|
||||
func init() {
|
||||
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
c := Comparator{}
|
||||
tree := NewTree(c)
|
||||
configPath, err := filepath.Abs(configName)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
tree.MustPut("key1", "Val1")
|
||||
tree.MustPut("key2", "Val2")
|
||||
tree.MustPut("key3", "Val3")
|
||||
tree.MustPut("key4", "Val4")
|
||||
tree.MustPut("key5", "Val5")
|
||||
tree.MustPut("key6", "Val6")
|
||||
tree.MustPut("key7", "Val7")
|
||||
tree.MustPut("key8", "Val8")
|
||||
var darknet Darknet = ParseConfig(configPath)
|
||||
|
||||
fmt.Println(tree.String())
|
||||
|
||||
fmt.Println(tree.Ceil("key7"))
|
||||
fmt.Printf("darknet number of parameters: %v\n", len(darknet.parameters))
|
||||
fmt.Printf("darknet number of blocks: %v\n", len(darknet.blocks))
|
||||
}
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
type sortable struct {
|
||||
values []interface{}
|
||||
comparator Comparator
|
||||
}
|
||||
|
||||
// Implement `Interface` interface of Go package `sort` for sortable struct:
|
||||
// =========================================================================
|
||||
|
||||
func (s sortable) Len() (retVal int) {
|
||||
return len(s.values)
|
||||
}
|
||||
|
||||
func (s sortable) Swap(idx1, idx2 int) {
|
||||
s.values[idx1], s.values[idx2] = s.values[idx2], s.values[idx1]
|
||||
}
|
||||
|
||||
func (s sortable) Less(idx1, idx2 int) (retVal bool) {
|
||||
return s.comparator.Compare(s.values[idx1], s.values[idx2]) < 0
|
||||
}
|
||||
|
||||
// Sort sorts values in-place.
|
||||
func Sort(values []interface{}, comparator Comparator) {
|
||||
sort.Sort(sortable{values, comparator})
|
||||
}
|
790
example/yolo/yolo-v3.cfg
Normal file
790
example/yolo/yolo-v3.cfg
Normal file
|
@ -0,0 +1,790 @@
|
|||
[net]
|
||||
# Testing
|
||||
batch=1
|
||||
subdivisions=1
|
||||
# Training
|
||||
# batch=64
|
||||
# subdivisions=16
|
||||
width= 416
|
||||
|
||||
height = 416
|
||||
channels=3
|
||||
momentum=0.9
|
||||
decay=0.0005
|
||||
angle=0
|
||||
saturation = 1.5
|
||||
exposure = 1.5
|
||||
hue=.1
|
||||
|
||||
learning_rate=0.001
|
||||
burn_in=1000
|
||||
max_batches = 500200
|
||||
policy=steps
|
||||
steps=400000,450000
|
||||
scales=.1,.1
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=32
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
# Downsample
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=64
|
||||
size=3
|
||||
stride=2
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=32
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=64
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
# Downsample
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=128
|
||||
size=3
|
||||
stride=2
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=64
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=128
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=64
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=128
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
# Downsample
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=3
|
||||
stride=2
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=128
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=128
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=128
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=128
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=128
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=128
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=128
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=128
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
# Downsample
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=512
|
||||
size=3
|
||||
stride=2
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=512
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=512
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=512
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=512
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=512
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=512
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=512
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=512
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
# Downsample
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=1024
|
||||
size=3
|
||||
stride=2
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=512
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=1024
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=512
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=1024
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=512
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=1024
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=512
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=1024
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[shortcut]
|
||||
from=-3
|
||||
activation=linear
|
||||
|
||||
######################
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=512
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
filters=1024
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=512
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
filters=1024
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=512
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
filters=1024
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
filters=255
|
||||
activation=linear
|
||||
|
||||
|
||||
[yolo]
|
||||
mask = 6,7,8
|
||||
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
|
||||
classes=80
|
||||
num=9
|
||||
jitter=.3
|
||||
ignore_thresh = .5
|
||||
truth_thresh = 1
|
||||
random=1
|
||||
|
||||
|
||||
[route]
|
||||
layers = -4
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[upsample]
|
||||
stride=2
|
||||
|
||||
[route]
|
||||
layers = -1, 61
|
||||
|
||||
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
filters=512
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
filters=512
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=256
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
filters=512
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
filters=255
|
||||
activation=linear
|
||||
|
||||
|
||||
[yolo]
|
||||
mask = 3,4,5
|
||||
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
|
||||
classes=80
|
||||
num=9
|
||||
jitter=.3
|
||||
ignore_thresh = .5
|
||||
truth_thresh = 1
|
||||
random=1
|
||||
|
||||
|
||||
|
||||
[route]
|
||||
layers = -4
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=128
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[upsample]
|
||||
stride=2
|
||||
|
||||
[route]
|
||||
layers = -1, 36
|
||||
|
||||
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=128
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
filters=256
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=128
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
filters=256
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
filters=128
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
batch_normalize=1
|
||||
size=3
|
||||
stride=1
|
||||
pad=1
|
||||
filters=256
|
||||
activation=leaky
|
||||
|
||||
[convolutional]
|
||||
size=1
|
||||
stride=1
|
||||
pad=1
|
||||
filters=255
|
||||
activation=linear
|
||||
|
||||
|
||||
[yolo]
|
||||
mask = 0,1,2
|
||||
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
|
||||
classes=80
|
||||
num=9
|
||||
jitter=.3
|
||||
ignore_thresh = .5
|
||||
truth_thresh = 1
|
||||
random=1
|
||||
|
Loading…
Reference in New Issue
Block a user