【Go・Deep Learning その②】 ゼロから作るdeep learning 3を復習 スパイラル分類🌪🌪🌪
スパイラルモデルの作成🌪🌪🌪
普通にこちらを参考にコピペしました。🙇♂️
普通に言語が違うとコピペも一苦労。
やはりNumpyは便利
コード
package dataset
import (
"math/rand"
"github.com/DolkMd/go-dezero/domain/core"
dz "github.com/DolkMd/go-dezero/domain/core/dezero"
"github.com/DolkMd/go-dezero/domain/core/dezero/fn"
)
type spiralOpt struct{ Train *bool }
type SpiralOpt func(*spiralOpt)
func Train(train bool) SpiralOpt {
return func(so *spiralOpt) {
so.Train = &train
}
}
func GetSpiral(options ...SpiralOpt) (x, t core.Matrix) {
option := spiralOpt{}
for _, opt := range options {
opt(&option)
}
seed := 2020
if option.Train != nil && *option.Train {
seed = 1984
}
rand.Seed(int64(seed))
numData, numClass, inputDim := 100.0, 3.0, 2.0
dataSize := numClass * numData
x = core.New(core.Shape{R: int(dataSize), C: int(inputDim)})
t = core.New(core.Shape{R: 1, C: int(dataSize)})
for i := 0.0; i < numClass; i++ {
for j := 0.0; j < numData; j++ {
rate := j / numData
radius := 1.0 * rate
theta := fn.AddFloat(fn.MulFloat(
dz.NewVariable(core.NewRandN(core.Shape{1, 1})),
0.2,
), float64(i*4.0+4.0*rate))
ix := int(numData*i + j)
t.Set(0, ix, i)
x.Set(ix, 0, fn.MulFloat(fn.Sin(theta), radius).Data().At(0, 0))
x.Set(ix, 1, fn.MulFloat(fn.Cos(theta), radius).Data().At(0, 0))
}
}
x.EachR(func(i int, v []float64) {
ix := rand.Intn(x.Shape().R)
x.Swap(i, 0, ix, 0)
x.Swap(i, 1, ix, 1)
t.Swap(0, i, 0, ix)
})
return
}
画像
学習用コード
簡単な解説✒️
MLP(多重パーセプトロン)を用いて多分類を行っています。
損失関数はSoftmaxCrossEntropyで、オプティマイザはSDGです。
このコードで大事な部分は、バッチサイズを定義して、大きさを限定して学習を進めていくということです。
参考になりそうな記事
コード
x, t := dataset.GetSpiral(dataset.Train(true))
maxEpoch := 350
batchSize := 30
hiddenSize := 10
lr := 1.0
model := mdl.NewMLP([]int{hiddenSize, 3})
op := optimizer.NewSGD(optimizer.Lr(lr)).Setup(model)
graph := infragraph.New()
ps := []appif.GraphParts{}
for i := 0; i < 3; i++ {
xs := []float64{}
ys := []float64{}
for j := 0; j < x.Shape().R; j++ {
if int(t.At(0, j)) == i {
xs = append(xs, x.At(j, 0))
ys = append(ys, x.At(j, 1))
}
}
colorOpt := appif.GraphColor(255, 255, 0, 255)
if i == 1 {
colorOpt = appif.GraphColor(0, 255, 255, 255)
}
if i == 2 {
colorOpt = appif.GraphColor(255, 0, 255, 255)
}
p, err := graph.Points(xs, ys, colorOpt)
if err != nil {
panic(err)
}
ps = append(ps, p)
}
graph.SaveGraph("./graph/spiral.png", ps)
xs, ys := []float64{}, []float64{}
dataSize := x.Len()
maxIter := math.Ceil(float64(dataSize) / float64(batchSize))
for epoch := 0; epoch < int(maxEpoch); epoch++ {
index := core.RandomPermutation(dataSize)
sumLoss := float64(0)
for i := 0; i < int(maxIter); i++ {
batchIndex := index[i*batchSize : (i+1)*batchSize]
batchX := dz.NewVariable(x.Cat(batchIndex))
batchT := dz.NewVariable(t.Cat(batchIndex))
y := model.Apply(batchX).First()
loss := fn.SoftmaxCrossEntropy(y, batchT)
model.ClearGrads()
loss.Backward(dz.RetainGradGrad(true))
op.Update()
sumLoss += loss.Data().At(0, 0) * float64(batchT.Data().Len())
}
avgLoss := sumLoss / float64(dataSize)
fmt.Printf("epoch %d, loss %.2f\n", epoch+1, avgLoss)
xs = append(xs, float64(epoch))
ys = append(ys, avgLoss)
}
p, _ := graph.Line(xs, ys)
graph.SaveGraph("./test_result.png", []appif.GraphParts{p})
学習結果
ソースコード
まとめ✅
結論的には、SoftmaxCrossEntropyの関数・微分の実装がかなり時間を有しました。⏰⏰⏰⏰
やはりNumpyを参考にそのまま書くのは難易度が高いです。(一度上手くいかないとどこが原因なのか探すのが大変です)😂😂😂😂😂😂😂😂😂😂😂😂😂
バッチ処理などの処理周りは本を読むとすごく簡単に理解できます👍。
ゼロから作るDeep Learning ❸/ ゼロから作るDeep Learning ❶を読むことをお勧めします!!!!👍👍👍👍👍👍👍👍👍