1# Licensed to the Apache Software Foundation (ASF) under one
2# or more contributor license agreements.  See the NOTICE file
3# distributed with this work for additional information
4# regarding copyright ownership.  The ASF licenses this file
5# to you under the Apache License, Version 2.0 (the
6# "License"); you may not use this file except in compliance
7# with the License.  You may obtain a copy of the License at
8#
9#   http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing,
12# software distributed under the License is distributed on an
13# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14# KIND, either express or implied.  See the License for the
15# specific language governing permissions and limitations
16# under the License.
17
18library(mxnet)
19
20data <- mx.symbol.Variable('data')
21label <- mx.symbol.Variable('label')
22conv1 <- mx.symbol.Convolution(data = data, kernel = c(5, 5), num_filter = 32)
23pool1 <- mx.symbol.Pooling(data = conv1, pool_type = "max", kernel = c(2, 2), stride = c(1, 1))
24relu1 <- mx.symbol.Activation(data = pool1, act_type = "relu")
25
26conv2 <- mx.symbol.Convolution(data = relu1, kernel = c(5, 5), num_filter = 32)
27pool2 <- mx.symbol.Pooling(data = conv2, pool_type = "avg", kernel = c(2, 2), stride = c(1, 1))
28relu2 <- mx.symbol.Activation(data = pool2, act_type = "relu")
29
30flatten <- mx.symbol.Flatten(data = relu2)
31fc1 <- mx.symbol.FullyConnected(data = flatten, num_hidden = 120)
32fc21 <- mx.symbol.FullyConnected(data = fc1, num_hidden = 10)
33fc22 <- mx.symbol.FullyConnected(data = fc1, num_hidden = 10)
34fc23 <- mx.symbol.FullyConnected(data = fc1, num_hidden = 10)
35fc24 <- mx.symbol.FullyConnected(data = fc1, num_hidden = 10)
36fc2 <- mx.symbol.Concat(c(fc21, fc22, fc23, fc24), dim = 0, num.args = 4)
37label <- mx.symbol.transpose(data = label)
38label <- mx.symbol.Reshape(data = label, target_shape = c(0))
39captcha_net <- mx.symbol.SoftmaxOutput(data = fc2, label = label, name = "softmax")
40
41mx.metric.acc2 <- mx.metric.custom("accuracy", function(label, pred) {
42    ypred <- max.col(t(data.matrix(pred))) - 1
43    ypred <- matrix(ypred, nrow = nrow(label), ncol = ncol(label), byrow = TRUE)
44    return(sum(colSums(data.matrix(label) == ypred) == 4) / ncol(label))
45  })
46
47data.shape <- c(80, 30, 3)
48
49batch_size <- 40
50
51train <- mx.io.ImageRecordIter(
52  path.imgrec     = "captcha_train.rec",
53  path.imglist    = "captcha_train.lst",
54  batch.size      = batch_size,
55  label.width     = 4,
56  data.shape      = data.shape,
57  mean.img        = "mean.bin"
58)
59
60val <- mx.io.ImageRecordIter(
61  path.imgrec     = "captcha_test.rec",
62  path.imglist    = "captcha_test.lst",
63  batch.size      = batch_size,
64  label.width     = 4,
65  data.shape      = data.shape,
66  mean.img        = "mean.bin"
67)
68
69mx.set.seed(42)
70
71model <- mx.model.FeedForward.create(
72  X                  = train,
73  eval.data          = val,
74  ctx                = mx.gpu(),
75  symbol             = captcha_net,
76  eval.metric        = mx.metric.acc2,
77  num.round          = 10,
78  learning.rate      = 0.0001,
79  momentum           = 0.9,
80  wd                 = 0.00001,
81  batch.end.callback = mx.callback.log.train.metric(50),
82  initializer        = mx.init.Xavier(factor_type = "in", magnitude = 2.34),
83  optimizer          = "sgd",
84  clip_gradient = 10
85)
86