WIP(example/yolo)

This commit is contained in:
sugarme 2020-07-13 18:23:50 +10:00
parent 565be523db
commit a146032afa
8 changed files with 1049 additions and 1006 deletions

View File

@ -1 +0,0 @@
package main

View File

@ -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)
}
}

View File

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

View File

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

View File

@ -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()
}

View File

@ -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))
}

View File

@ -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
View 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