deeplearning4j / deeplearning4j/deeplearning4j-examples
Exceptions in MultiClassLogit example with fix proposals and warning in IteratorDataSetIterator.
- Dominant language
- Java
- Stars
- 2.5k
- Forks
- 1.8k
- PR merge metrics
- No merged PRs in 30d
Description
[ INFO ]
Deeplearning4j version: 1.0.0-beta5
Platform information: Windows 10
CUDA version: No
NVIDIA driver version: No
Issue #1:
File: .../src/main/java/org/deeplearning4j/examples/dataexamples/MultiClassLogit.java
[ EXCEPTION ]
Exception in thread "main" java.lang.IllegalStateException: Indices are out of range: Cannot get interval index Interval(b=0,e=2,s=1) on array with size(0)=1. Array shape: [1], indices: [Interval(b=0,e=2,s=1)]
at org.nd4j.linalg.api.ndarray.BaseNDArray.get(BaseNDArray.java:4253)
at org.nd4j.linalg.dataset.DataSet.getRange(DataSet.java:234)
at org.deeplearning4j.examples._mytests_.IteratorDataSetIterator.next(IteratorDataSetIterator.java:92)
at org.deeplearning4j.examples._mytests_.IteratorDataSetIterator.next(IteratorDataSetIterator.java:68)
at org.deeplearning4j.examples._mytests_.IteratorDataSetIterator.next(IteratorDataSetIterator.java:1)
at org.deeplearning4j.examples._mytests_.MultiClassLogit.getIrisDataSet(MultiClassLogit.java:89)
at org.deeplearning4j.examples._mytests_.MultiClassLogit.main(MultiClassLogit.java:60)
[ CODE ]
`irisDataSet = iter.next();`
at org.deeplearning4j.examples._mytests_.MultiClassLogit.getIrisDataSet(MultiClassLogit.java:89)
`int nExamples = next.numExamples(); // => 4 instead of 1`
at org.deeplearning4j.examples._mytests_.IteratorDataSetIterator.next(IteratorDataSetIterator.java:85)
`inputColumns = (int) temp.getFeatures().size(1); // => rank 1 instead of 2`
at org.deeplearning4j.examples._mytests_.IteratorDataSetIterator.next(IteratorDataSetIterator.java:105)
[FIX]
Features array in DataSet should have rank at least 2. Shape (with additional dimension) should be explicitly specified for input data (i.e. one-dimensional double array).
`
return new DataSet(
Nd4j.create(Arrays.copyOfRange(parsedRows, 0, columns - 1), new long[] { 1, columns - 1 }),
Nd4j.create(Arrays.copyOfRange(parsedRows, columns - 1, columns), new long[] { 1, 1 }));
`
but it reveals the next issue...
Issue #2:
File: .../src/main/java/org/deeplearning4j/examples/dataexamples/MultiClassLogit.java
[ EXCEPTION ]
Error at [D:/jenkins/ws/dl4j-deeplearning4j-1.0.0-beta5-windows-x86_64-cpu/libnd4j/include/ops/declarable/generic/transforms/concat.cpp:78:0]:
CONCAT op: all of input arrays must have same type !
Exception in thread "main" java.lang.RuntimeException: Op [concat] execution failed
at org.nd4j.linalg.cpu.nativecpu.ops.NativeOpExecutioner.exec(NativeOpExecutioner.java:1710)
at org.nd4j.linalg.factory.Nd4j.exec(Nd4j.java:6606)
at org.nd4j.linalg.cpu.nativecpu.CpuNDArrayFactory.concat(CpuNDArrayFactory.java:557)
at org.nd4j.linalg.factory.Nd4j.concat(Nd4j.java:4917)
at org.nd4j.linalg.factory.BaseNDArrayFactory.hstack(BaseNDArrayFactory.java:963)
at org.nd4j.linalg.factory.Nd4j.hstack(Nd4j.java:4673)
at org.deeplearning4j.examples._mytests_.MultiClassLogit.prependConstant(MultiClassLogit.java:168)
at org.deeplearning4j.examples._mytests_.MultiClassLogit.trainModel(MultiClassLogit.java:125)
at org.deeplearning4j.examples._mytests_.MultiClassLogit.main(MultiClassLogit.java:73)
Caused by: java.lang.RuntimeException: Op validation failed
at org.nd4j.linalg.cpu.nativecpu.ops.NativeOpExecutioner.exec(NativeOpExecutioner.java:2006)
at org.nd4j.linalg.cpu.nativecpu.ops.NativeOpExecutioner.exec(NativeOpExecutioner.java:1700)
... 8 more
[ CODE ]
`return Nd4j.hstack(Nd4j.ones(dataset.getFeatures().size(0), 1), dataset.getFeatures());`
at org.deeplearning4j.examples._mytests_.MultiClassLogit.prependConstant(MultiClassLogit.java:168)
`return getExecutioner().exec(op);`
at org.nd4j.linalg.factory.Nd4j.exec(Nd4j.java:6606)
`val result = exec(op, context);`
at org.nd4j.linalg.cpu.nativecpu.ops.NativeOpExecutioner.exec(NativeOpExecutioner.java:1700)
`throw new RuntimeException("Op [" + name + "] execution failed", e);`
at org.nd4j.linalg.cpu.nativecpu.ops.NativeOpExecutioner.exec(NativeOpExecutioner.java:1710)
[ FIX ]
Default data type for Nd4j arrays is FLOAT (e.g. for Nd4j.rand/.zeros/.ones etc.). In MultiClassLogit example String stream is converted to double array using lambda expression (mapRowToDataSet). It seems that incompatibility between DOUBLE and FLOAT types of Nd4j arrays causes problems with some operations on a native code level. Unfortunately, standard Java library offers streams (using wrapper types) only for 3 out of 8 primitive data types (yes: int/long/double, no: short/byte/char/boolean/float). I have no idea why. "mapToFloat" would be quite useful in this case, in order to get float array directly from String stream. There is not always need to use additional 4 bytes to represent a single number. The float type is very often more than enough.
`return new DataSet(
Nd4j.create(Arrays.copyOfRange(parsedRows, 0, columns - 1), new long[] { 1, columns - 1 }, DataType.FLOAT),
Nd4j.create(Arrays.copyOfRange(parsedRows, columns - 1, columns), new long[] { 1, 1 }, DataType.FLOAT));`
and finally, there is no next Runtime Exception but...
Issue #3:
File: .../src/main/java/org/deeplearning4j/datasets/iterator/IteratorDataSetIterator.java
[ WARNING ]
Breakpoint lines:
DataSetIterator iter = new IteratorDataSetIterator(data.iterator(), 150);
irisDataSet = iter.next();
[ CODE ]
constructor...
` public IteratorDataSetIterator(Iterator iterator, int batchSize) {
this.iterator = iterator;
this.batchSize = batchSize;
this.queued = new LinkedList<>();
}`
next()...
`public DataSet next() {
return next(batchSize);
}`
next(int)...
`public DataSet next(int num) {
if (!hasNext())
throw new NoSuchElementException();
List list = new ArrayList<>();
int countSoFar = 0;
while ((!queued.isEmpty() || iterator.hasNext()) && countSoFar < batchSize) {
DataSet next;
if (!queued.isEmpty()) {
next = queued.removeFirst();
} else {
next = iterator.next();
}
int nExamples = next.numExamples();
if (countSoFar + nExamples <= batchSize) {
// Add the entire DataSet as-is
list.add(next);
} else {
// Otherwise, split it
DataSet toKeep = (DataSet) next.getRange(0, batchSize - countSoFar);
DataSet toCache = (DataSet) next.getRange(batchSize - countSoFar, nExamples);
list.add(toKeep);
queued.add(toCache);
}
countSoFar += nExamples;
}
}
`
[ REMARKS ]
When the next() method is executed overloaded method next(int) is invoked with "batchSize" field value passed by the "num" parameter, but then "num" is never used anymore.
Contributor guide
Assessment
This issue has not been assessed yet.