From b5c0d96af18c9ea341ade0b714a1965c6776fa42 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Wed, 11 Nov 2015 13:00:37 +0900 Subject: [PATCH 1/4] reformultate accuracy with multi_output in mind --- src/metric.jl | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/metric.jl b/src/metric.jl index 297aee384079..12860a5ae0d9 100644 --- a/src/metric.jl +++ b/src/metric.jl @@ -50,11 +50,27 @@ end function _update_single_output(metric :: Accuracy, label :: NDArray, pred :: NDArray) @nd_as_jl ro=(label,pred) begin - n_sample = size(pred)[end] - metric.n_sample += n_sample - for i = 1:n_sample - klass = indmax(pred[:,i]) - metric.acc_sum += (klass-1) == label[i] + if ndims(label) > 1 # Multidimensional case + # Construct cartesian index + initial = tuple([1 for _ in 1:ndims(label)-1]...) + final = tuple([size(label, i) for i in 1:ndims(label)-1]...) + crange = CartesianRange(CartesianIndex(initial), CartesianIndex(final)) + + for sample in 1:size(label, ndims(label)) + for i in crange + ps = sub(pred, i.I..., :, sample) + klass = indmax(ps) + metric.acc_sum += (klass-1) == label[i.I..., sample] + metric.n_sample += 1 + end + end + else # 1-dimensional case + for sample in 1:size(label, 1) + ps = sub(pred, :, sample) + klass = indmax(ps) + metric.acc_sum += (klass-1) == label[sample] + metric.n_sample += 1 + end end end end From 8322b6337f32dbcfe597f6ba95e0d369490eeb3d Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Wed, 11 Nov 2015 14:19:13 +0900 Subject: [PATCH 2/4] Calculate accuracy based on size of pred. The label array is reshaped and misses the information about the size of the first few dimensions. --- src/metric.jl | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/metric.jl b/src/metric.jl index 12860a5ae0d9..aed5ca0fede6 100644 --- a/src/metric.jl +++ b/src/metric.jl @@ -50,17 +50,18 @@ end function _update_single_output(metric :: Accuracy, label :: NDArray, pred :: NDArray) @nd_as_jl ro=(label,pred) begin - if ndims(label) > 1 # Multidimensional case + if ndims(pred) > 2 # Multidimensional case # Construct cartesian index - initial = tuple([1 for _ in 1:ndims(label)-1]...) - final = tuple([size(label, i) for i in 1:ndims(label)-1]...) - crange = CartesianRange(CartesianIndex(initial), CartesianIndex(final)) + initial = tuple(fill(1, ndims(pred)-2)...) + dims = size(pred, (1:ndims(pred)-2)...) + crange = CartesianRange(CartesianIndex(initial), CartesianIndex(dims)) for sample in 1:size(label, ndims(label)) for i in crange + l_i = sub2ind(dims, i.I...) ps = sub(pred, i.I..., :, sample) klass = indmax(ps) - metric.acc_sum += (klass-1) == label[i.I..., sample] + metric.acc_sum += (klass-1) == label[l_i, sample] metric.n_sample += 1 end end From c30097172a54fffa8d21185bd2c7b7d3ce8bf477 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Wed, 11 Nov 2015 14:37:02 +0900 Subject: [PATCH 3/4] remove sub from accuracy --- src/metric.jl | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/metric.jl b/src/metric.jl index aed5ca0fede6..8d5838aff4ba 100644 --- a/src/metric.jl +++ b/src/metric.jl @@ -48,27 +48,44 @@ type Accuracy <: AbstractEvalMetric Accuracy() = new(0.0, 0) end +""" +Implementation taken from findmax in Julia base. +Searches for the maximum value in p_dim of a. +I and n are values for the other dimensions. +""" +function _indmax(a, I, p_dim, n) + m = a[I..., 1, n] + mi = 1 + for i in 2:size(a, p_dim) + ai = a[I..., i, n] + if ai > m || m!=m + m = ai + mi = i + end + end + return mi +end + function _update_single_output(metric :: Accuracy, label :: NDArray, pred :: NDArray) @nd_as_jl ro=(label,pred) begin if ndims(pred) > 2 # Multidimensional case # Construct cartesian index - initial = tuple(fill(1, ndims(pred)-2)...) - dims = size(pred, (1:ndims(pred)-2)...) + p_dim = ndims(pred)-1 + initial = tuple(fill(1,p_dim-1)...) + dims = size(pred, (1:p_dim-1)...) crange = CartesianRange(CartesianIndex(initial), CartesianIndex(dims)) for sample in 1:size(label, ndims(label)) for i in crange l_i = sub2ind(dims, i.I...) - ps = sub(pred, i.I..., :, sample) - klass = indmax(ps) + klass = _indmax(pred, i.I, p_dim, sample) metric.acc_sum += (klass-1) == label[l_i, sample] metric.n_sample += 1 end end else # 1-dimensional case for sample in 1:size(label, 1) - ps = sub(pred, :, sample) - klass = indmax(ps) + klass = indmax(pred[:, sample]) metric.acc_sum += (klass-1) == label[sample] metric.n_sample += 1 end From d51d2af73a23ebbed7488a479a9be44261e31972 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Wed, 11 Nov 2015 14:44:23 +0900 Subject: [PATCH 4/4] add comments for accuracy and rebuild docs --- docs/api/io.rst | 4 ++-- docs/api/metric.rst | 3 +++ docs/api/symbolic-node.rst | 23 +++++++++++++++++++++++ src/metric.jl | 3 +++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/docs/api/io.rst b/docs/api/io.rst index e9d9c04e9f3c..6c9d71836108 100644 --- a/docs/api/io.rst +++ b/docs/api/io.rst @@ -317,7 +317,7 @@ libmxnet data providers :param prefetch_buffer: Backend Param: Number of prefetched parameters - :type prefetch_buffer: , optional, default=4 + :type prefetch_buffer: long (non-negative), optional, default=4 :param rand_crop: Augmentation Param: Whether to random crop on the image @@ -460,7 +460,7 @@ libmxnet data providers :param prefetch_buffer: Backend Param: Number of prefetched parameters - :type prefetch_buffer: , optional, default=4 + :type prefetch_buffer: long (non-negative), optional, default=4 :return: the constructed :class:`MXDataProvider`. diff --git a/docs/api/metric.rst b/docs/api/metric.rst index db18ae731a59..5f13bd7006c3 100644 --- a/docs/api/metric.rst +++ b/docs/api/metric.rst @@ -42,5 +42,8 @@ set. Multiclass classification accuracy. + Calculates the mean accuracy per sample for softmax in one dimension. + For a multi-dimensional softmax the mean accuracy over all dimensions is calculated. + diff --git a/docs/api/symbolic-node.rst b/docs/api/symbolic-node.rst index f811d41aaad5..6106b54e6a8f 100644 --- a/docs/api/symbolic-node.rst +++ b/docs/api/symbolic-node.rst @@ -501,6 +501,29 @@ Public APIs +.. function:: SwapAxis(...) + + Apply swapaxis to input. + + :param data: Input data to the SwapAxisOp. + :type data: SymbolicNode + + + :param dim1: the first axis to be swapped. + :type dim1: int (non-negative), optional, default=0 + + + :param dim2: the second axis to be swapped. + :type dim2: int (non-negative), optional, default=0 + + :param Base.Symbol name: The name of the :class:`SymbolicNode`. (e.g. `:my_symbol`), optional. + + :return: the constructed :class:`SymbolicNode`. + + + + + .. function:: exp(...) Take exp of the src diff --git a/src/metric.jl b/src/metric.jl index 8d5838aff4ba..3f35e7455ac5 100644 --- a/src/metric.jl +++ b/src/metric.jl @@ -40,6 +40,9 @@ abstract AbstractEvalMetric .. class:: Accuracy Multiclass classification accuracy. + + Calculates the mean accuracy per sample for softmax in one dimension. + For a multi-dimensional softmax the mean accuracy over all dimensions is calculated. =# type Accuracy <: AbstractEvalMetric acc_sum :: Float64