This project is a POC; it embed an old version of onnx-go and a tweaked version of Gorgonia in the vendor directories. The effort is now ported to the project onnx-go
I wrote two article about the genesis of the project:
Onnx To Gorgonia Unmarshaler (Test)
License: BSD 3-Clause "New" or "Revised" License
This project is a POC; it embed an old version of onnx-go and a tweaked version of Gorgonia in the vendor directories. The effort is now ported to the project onnx-go
I wrote two article about the genesis of the project:
@owulveryck what is the licence of the project. Could gorgonx distribute onnx tests datas?
I have made a sample command (with hardcoded elements). Its purpose is to:
The input tensor is ok (I have a test within the MNIST that generates a picture from the output and I can see that it is OK as it displays a 0).
The ExprGraph seems OK (see the generated graph).
The problem is when I execute the graph, it computes the values and the output value is not OK:
go run main.go
2018/09/01 10:45:48 + false(%2a, %7): R[-342.19385 860.9805 302.0319 -106.48801 ... 61.497894 587.05164 -666.66016 -341.96298]
I have try some introspection (with the help of log
, debug
and q.Q()
and I have noticed that at least the last operator (which is an addition) is not working.
It is supposed to add Parameter194
to the output of the Convolution Operator
.
This is the output of the Plus operator
0.307s n.Name()=+ false(%2a, %7)
n.Value()=&tensor.Dense{
AP: tensor.AP{
shape: {1, 10},
strides: {10, 1},
fin: true,
o: 0x0,
Δ: 0x0,
},
array: tensor.array{
Header: storage.Header{Ptr:0xc0001b4030, L:10, C:10},
t: tensor.Dtype{
Type: &reflect.rtype{
size: 0x4,
ptrdata: 0x0,
hash: 0xb0c23ed3,
tflag: 0x7,
align: 0x4,
fieldAlign: 0x4,
kind: 0x8d,
alg: &reflect.typeAlg{hash:func(unsafe.Pointer, uintptr) uintptr {...}, equal:func(unsafe.Pointer, unsafe.Pointer) bool {...}},
gcdata: &uint8(0x1),
str: 22186,
ptrToThis: 167328,
},
},
v: []float32{-342.19384765625, 860.9805297851562, 302.0318908691406, -106.48800659179688, -162.96603393554688, 328.5005798339844, 61.497894287109375, 587.0516357421875, -666.66015625, -341.9629821777344},
},
flag: 0x0,
e: gorgonia.StandardEngine{},
oe: gorgonia.StandardEngine{},
old: tensor.AP{},
transposeWith: nil,
viewOf: 0x0,
mask: nil,
maskIsSoft: false,
}
The first input value computed value from the previous operator (the value is the same as the output):
0.367s n.Name()=A × B(%29, %9)
n.Value()=&tensor.Dense{
AP: tensor.AP{
shape: {1, 10},
strides: {10, 1},
fin: true,
o: 0x0,
Δ: 0x0,
},
array: tensor.array{
Header: storage.Header{Ptr:0xc0001be000, L:10, C:10},
t: tensor.Dtype{
Type: &reflect.rtype{
size: 0x4,
ptrdata: 0x0,
hash: 0xb0c23ed3,
tflag: 0x7,
align: 0x4,
fieldAlign: 0x4,
kind: 0x8d,
alg: &reflect.typeAlg{hash:func(unsafe.Pointer, uintptr) uintptr {...}, equal:func(unsafe.Pointer, unsafe.Pointer) bool {...}},
gcdata: &uint8(0x1),
str: 22186,
ptrToThis: 167008,
},
},
v: []float32{-342.19384765625, 860.9805297851562, 302.0318908691406, -106.48800659179688, -162.96603393554688, 328.5005798339844, 61.497894287109375, 587.0516357421875, -666.66015625, -341.9629821777344},
},
flag: 0x0,
e: gorgonia.StandardEngine{},
oe: gorgonia.StandardEngine{},
old: tensor.AP{},
transposeWith: nil,
viewOf: 0x0,
mask: nil,
maskIsSoft: false,
}
The second input parameter (constant):
0.041s n.Name()=Parameter194
n.Value()=&tensor.Dense{
AP: tensor.AP{
shape: {1, 10},
strides: {10, 1},
fin: true,
o: 0x0,
Δ: 0x0,
},
array: tensor.array{
Header: storage.Header{Ptr:0xc0001be060, L:10, C:10},
t: tensor.Dtype{
Type: &reflect.rtype{
size: 0x4,
ptrdata: 0x0,
hash: 0xb0c23ed3,
tflag: 0x7,
align: 0x4,
fieldAlign: 0x4,
kind: 0x8d,
alg: &reflect.typeAlg{hash:func(unsafe.Pointer, uintptr) uintptr {...}, equal:func(unsafe.Pointer, unsafe.Pointer) bool {...}},
gcdata: &uint8(0x1),
str: 22186,
ptrToThis: 167008,
},
},
v: []float32{-0.04485602676868439, 0.007791661191731691, 0.06810081750154495, 0.02999374084174633, -0.1264096349477768, 0.14021874964237213, -0.055284902453422546, -0.04938381537795067, 0.08432205021381378, -0.05454041436314583},
},
flag: 0x0,
e: gorgonia.StandardEngine{},
oe: gorgonia.StandardEngine{},
old: tensor.AP{},
transposeWith: nil,
viewOf: 0x0,
mask: nil,
maskIsSoft: false,
}
The integration tests (issued from ONNX) are melted with the unit tests.
Thanks to the tool for code generation, I think they should be isolated from the gorgonnx
package and generated thanks to a // go generate
comment.
This would allow a better maintainability of the repository and would ease the addition and tests of new operators.
Any opinion @blackrez ?
I am trying to make the test of the Maxpool
with padding to turn green (Line 169 of the file maxpool_autogenerated_test.go
).
The test consists of an input tensor with shape (1, 3, 28, 28)
of float32
;
The kernel shape is (3,3)
and the strides are set to their default values (1).
The padding given to the model is []int{2,2,2,2}
, which has to be converted into a two dimensional []int
for the Maxpool operator of Gorgonia. (the doc from onnx is here)
The expected shape of the output tensor is (1,3,30,30)
.
The problem is that no padding allows me to get this shape (I have tried manually to set the shape in the maxpool_wip.go
file like this:
Here is the test I run from the batchnorm
branch of this repo
$ cd operator
$ go test -run=TestMaxpool_2d_pads
--- FAIL: TestMaxpool_2d_pads (0.00s)
maxpool_autogenerated_test.go:222: Info: operator &operators.Maxpool{name:"Maxpool", Pads:[]int{4, 4}, AutoPad:"", StorageOrder:0, KernelShape:(3, 3), Strides:[]int{1, 1}}
maxpool_autogenerated_test.go:269:
Error Trace: maxpool_autogenerated_test.go:269
Error: Not equal:
expected: (1, 3, 30, 30)
actual : (1, 3, 22, 22)
Diff:
--- Expected
+++ Actual
@@ -3,4 +3,4 @@
(int) 3,
- (int) 30,
- (int) 30
+ (int) 22,
+ (int) 22
}
Test: TestMaxpool_2d_pads
Messages: Tensors should be the same
maxpool_autogenerated_test.go:270:
Error Trace: maxpool_autogenerated_test.go:270
Error: Max difference between -3.4028235e+38 and 1.7640524 allowed is 1e-05, but difference was -3.4028234663852886e+38
Test: TestMaxpool_2d_pads
Messages: Tensors should be the same
FAIL
exit status 1
FAIL github.com/owulveryck/gorgonnx/operators 0.017s
Conv.pads will be set to {0, 0} if length of pads isn't equal to 4.
A lot of models are using the BatchNorm operator.
The ONNX Documentations is here. The reference implementation in Gorgonia (documented here) do not seem to use the extra inputs:
It may require a bit of investigation about the operator by itself to see how easy it is to bypass those parameters though.
go test -run=mnist
--- FAIL: Example_mnist (0.02s)
got:
[55.41009 984.514 -1191.4886 -652.1293 802.4857 497.57553 -303.6763 952.77106 -233.73296 -672.92255]
want:
[5041.8887 -3568.878 -187.82423 -1685.797 -1183.3232 -614.42926 892.6643 -373.65845 -290.2623 -111.176216]
FAIL
exit status 1
FAIL github.com/owulveryck/gorgonnx 0.034s
The convolution operator now seems to run as expected (according its unit test).
I have two options for debugging:
go test -run=ReshapeOp
--- FAIL: TestReshapeOp_extended_dims (0.00s)
reshape_extended_dims_test.go:94: PC: 2: PC 2. Failed to execute instruction Reshape(0, 0, 0, 0) [CPU0] CPU2 false false false: Failed to carry op.Do(): sanity check failed: Shape mismatch. Expected (0, 0, 0, 0). Got 24
--- FAIL: TestReshapeOp_negative_dim (0.00s)
reshape_negative_dim_test.go:94: PC: 2: PC 2. Failed to execute instruction Reshape(0, 0, 0) [CPU0] CPU2 false false false: Failed to carry op.Do(): sanity check failed: Shape mismatch. Expected (0, 0, 0). Got 24
--- FAIL: TestReshapeOp_one_dim (0.00s)
reshape_one_dim_test.go:94: PC: 2: PC 2. Failed to execute instruction Reshape(0) [CPU0] CPU2 false false false: Failed to carry op.Do(): sanity check failed: Shape mismatch. Expected (0). Got 24
--- FAIL: TestReshapeOp_reduced_dims (0.00s)
reshape_reduced_dims_test.go:94: PC: 2: PC 2. Failed to execute instruction Reshape(0, 0) [CPU0] CPU2 false false false: Failed to carry op.Do(): sanity check failed: Shape mismatch. Expected (0, 0). Got 24
--- FAIL: TestReshapeOp_reordered_dims (0.00s)
reshape_reordered_dims_test.go:94: PC: 2: PC 2. Failed to execute instruction Reshape(0, 0, 0) [CPU0] CPU2 false false false: Failed to carry op.Do(): sanity check failed: Shape mismatch. Expected (0, 0, 0). Got 24
FAIL
exit status 1
FAIL github.com/owulveryck/gorgonnx 0.018s
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.