<p>So, In order to learn the golang I'm porting an neural network project that I have.</p>
<p>I'm storing the network as an 3D matrix ([][][]float64). Ex:</p>
<pre><code>[
[[] []] // layer 0
[[0 0 0] [0 0 0] [0 0 0]] // layer 1
[[0 0 0 0] [0 0 0 0]] // layer 2
[[0 0 0]] // layer 3
]
</code></pre>
<p>I need to write a function that receives one network, mutate it's values and return A NEW mutated network without modifying the old one.</p>
<p>Here is how I did it:</p>
<pre><code>func Mutate(net [][][]float64) [][][]float64 {
for l:=0;l<len(net);l++{// fore layer...
for n:=0;n<len(net[l]);n++{// fore neuron...
for a:=0;a<len(net[l][n]);a++ {// fore element in neuron array...
net[l][n][a] = 1// set new value
}
}
}
return net
}
</code></pre>
<p>Here is the commented code for creating and mutating the network
<a href="http://pastebin.com/sJsQQN1C" rel="nofollow">http://pastebin.com/sJsQQN1C</a></p>
<p>And here is the test main function:</p>
<pre><code>func main() {
net := neuralArray.GenerateEmptyNet([]int{2,3,2,1})
fmt.Println("created net: " ,net)
net2 := neuralArray.Mutate(net)
fmt.Println("old net:" ,net)
fmt.Println("new net:", net2)
}
</code></pre>
<p>The result:</p>
<pre><code>go run src/main/main2.go
created net: [[[] []] [[0 0 0] [0 0 0] [0 0 0]] [[0 0 0 0] [0 0 0 0]] [[0 0 0]]]
old net: [[[] []] [[1 1 1] [1 1 1] [1 1 1]] [[1 1 1 1] [1 1 1 1]] [[1 1 1]]]
new net: [[[] []] [[1 1 1] [1 1 1] [1 1 1]] [[1 1 1 1] [1 1 1 1]] [[1 1 1]]]
</code></pre>
<p>As you see, the old got mutated too.
What is causing this behavior? I heard that passing a value as parameter rather than pointer creates a separated clone. But I'm clearly missing something here.</p>
<p>Thanks for your time!</p>
<hr/>**评论:**<br/><br/>Sythe2o0: <pre><p>Go does pass value copies, but slices are just pointers to some area of memory, so you end up copying that pointer. </p>
<p>See this <a href="http://stackoverflow.com/questions/39993688/are-golang-slices-pass-by-value" rel="nofollow">stack overflow</a> post.</p></pre>Ablaek: <pre><p>Hm, so my best bet it to change to arrays, or to copy() the slices and build a new one.</p>
<p>I'm gonna redo the code with arrays. Thanks!</p>
<p>EDIT:</p>
<p>actually I just created a new slice, and used it as return value instead....</p></pre>gdey: <pre><p>A slice is really a struct that has a pointer to a backing array and two other fields that record the length and capacity of the backing error. So when you pass a slice, you are just passing a copy of this struct. So, both struct point to the original backing array. </p>
<p>Here is a great article on how slices work.
<a href="https://blog.golang.org/go-slices-usage-and-internals" rel="nofollow">https://blog.golang.org/go-slices-usage-and-internals</a></p></pre>chewxy: <pre><p>You can use the <code>tensor</code> library:</p>
<pre><code>a := tensor.New(tensor.Float64, tensor.WithShape(2,3,4))
b := a.Clone().(*tensor.Dense)
b.Memset(1.0)
return b
</code></pre>
<p>Best part is... you can just swap out <code>tensor.Float64</code> for other types like <code>tensor.Float32</code> and it'll still work the same (for the most part.. you still have to memset the correct values).</p>
<p>More documentation can be found <a href="https://github.com/chewxy/gorgonia/blob/master/tensor/README.md" rel="nofollow">here</a></p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传