chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ /* ******************************************************************************
|
||||
~ *
|
||||
~ *
|
||||
~ * This program and the accompanying materials are made available under the
|
||||
~ * terms of the Apache License, Version 2.0 which is available at
|
||||
~ * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
~ *
|
||||
~ * See the NOTICE file distributed with this work for additional
|
||||
~ * information regarding copyright ownership.
|
||||
~ * Unless required by applicable law or agreed to in writing, software
|
||||
~ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
~ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
~ * License for the specific language governing permissions and limitations
|
||||
~ * under the License.
|
||||
~ *
|
||||
~ * SPDX-License-Identifier: Apache-2.0
|
||||
~ ******************************************************************************/
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.eclipse.deeplearning4j</groupId>
|
||||
<artifactId>deeplearning4j-data</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>deeplearning4j-utility-iterators</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>deeplearning4j-utility-iterators</name>
|
||||
|
||||
<properties>
|
||||
<module.name>deeplearning4j.utility.iterators</module.name>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.moditect</groupId>
|
||||
<artifactId>moditect-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.deeplearning4j</groupId>
|
||||
<artifactId>nd4j-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
||||
+278
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.NonNull;
|
||||
import org.nd4j.linalg.api.ndarray.INDArray;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
import org.nd4j.linalg.factory.Nd4j;
|
||||
import org.nd4j.common.primitives.Pair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
public abstract class AbstractDataSetIterator<T> implements DataSetIterator {
|
||||
private DataSetPreProcessor preProcessor;
|
||||
private transient Iterable<Pair<T, T>> iterable;
|
||||
private transient Iterator<Pair<T, T>> iterator;
|
||||
|
||||
private final int batchSize;
|
||||
|
||||
// FIXME: capacity 4 is triage here, proper investigation requires
|
||||
private final LinkedBlockingQueue<DataSet> queue = new LinkedBlockingQueue<>(4);
|
||||
private List<String> labels;
|
||||
private int numFeatures = -1;
|
||||
private int numLabels = -1;
|
||||
|
||||
protected AbstractDataSetIterator(@NonNull Iterable<Pair<T, T>> iterable, int batchSize) {
|
||||
if (batchSize < 1)
|
||||
throw new IllegalStateException("batchSize can't be < 1");
|
||||
|
||||
this.iterable = iterable;
|
||||
this.iterator = this.iterable.iterator();
|
||||
this.batchSize = batchSize;
|
||||
|
||||
fillQueue();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Like the standard next method but allows a
|
||||
* customizable number of examples returned
|
||||
*
|
||||
* @param num the number of examples
|
||||
* @return the next data applyTransformToDestination
|
||||
*/
|
||||
@Override
|
||||
public DataSet next(int num) {
|
||||
throw new IllegalStateException("next(int) isn't supported for this DataSetIterator");
|
||||
}
|
||||
|
||||
/**
|
||||
* Input columns for the dataset
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int inputColumns() {
|
||||
return numFeatures;
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of labels for the dataset
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int totalOutcomes() {
|
||||
return numLabels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return iterable != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the iterator back to the beginning
|
||||
*/
|
||||
@Override
|
||||
public void reset() {
|
||||
queue.clear();
|
||||
if (iterable != null)
|
||||
iterator = iterable.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch size
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int batch() {
|
||||
return batchSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a pre processor
|
||||
*
|
||||
* @param preProcessor a pre processor to set
|
||||
*/
|
||||
@Override
|
||||
public void setPreProcessor(DataSetPreProcessor preProcessor) {
|
||||
this.preProcessor = preProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get dataset iterator record reader labels
|
||||
*/
|
||||
@Override
|
||||
public List<String> getLabels() {
|
||||
return labels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the iteration has more elements.
|
||||
* (In other words, returns {@code true} if {@link #next} would
|
||||
* return an element rather than throwing an exception.)
|
||||
*
|
||||
* @return {@code true} if the iteration has more elements
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
fillQueue();
|
||||
return !queue.isEmpty();
|
||||
}
|
||||
|
||||
protected void fillQueue() {
|
||||
if (queue.isEmpty()) {
|
||||
List<INDArray> ndLabels = null;
|
||||
List<INDArray> ndFeatures = null;
|
||||
float[][] fLabels = null;
|
||||
float[][] fFeatures = null;
|
||||
double[][] dLabels = null;
|
||||
double[][] dFeatures = null;
|
||||
|
||||
int sampleCount = 0;
|
||||
|
||||
for (int cnt = 0; cnt < batchSize; cnt++) {
|
||||
if (iterator.hasNext()) {
|
||||
Pair<T, T> pair = iterator.next();
|
||||
if (numFeatures < 1) {
|
||||
if (pair.getFirst() instanceof INDArray) {
|
||||
numFeatures = (int) ((INDArray) pair.getFirst()).length();
|
||||
numLabels = (int) ((INDArray) pair.getSecond()).length();
|
||||
} else if (pair.getFirst() instanceof float[]) {
|
||||
numFeatures = ((float[]) pair.getFirst()).length;
|
||||
numLabels = ((float[]) pair.getSecond()).length;
|
||||
} else if (pair.getFirst() instanceof double[]) {
|
||||
numFeatures = ((double[]) pair.getFirst()).length;
|
||||
numLabels = ((double[]) pair.getSecond()).length;
|
||||
}
|
||||
}
|
||||
|
||||
if (pair.getFirst() instanceof INDArray) {
|
||||
if (ndLabels == null) {
|
||||
ndLabels = new ArrayList<>();
|
||||
ndFeatures = new ArrayList<>();
|
||||
}
|
||||
ndFeatures.add(((INDArray) pair.getFirst()));
|
||||
ndLabels.add(((INDArray) pair.getSecond()));
|
||||
} else if (pair.getFirst() instanceof float[]) {
|
||||
if (fLabels == null) {
|
||||
fLabels = new float[batchSize][];
|
||||
fFeatures = new float[batchSize][];
|
||||
}
|
||||
fFeatures[sampleCount] = (float[]) pair.getFirst();
|
||||
fLabels[sampleCount] = (float[]) pair.getSecond();
|
||||
} else if (pair.getFirst() instanceof double[]) {
|
||||
if (dLabels == null) {
|
||||
dLabels = new double[batchSize][];
|
||||
dFeatures = new double[batchSize][];
|
||||
}
|
||||
dFeatures[sampleCount] = (double[]) pair.getFirst();
|
||||
dLabels[sampleCount] = (double[]) pair.getSecond();
|
||||
}
|
||||
|
||||
sampleCount += 1;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
if (sampleCount == batchSize) {
|
||||
INDArray labels = null;
|
||||
INDArray features = null;
|
||||
if (ndLabels != null) {
|
||||
labels = Nd4j.vstack(ndLabels);
|
||||
features = Nd4j.vstack(ndFeatures);
|
||||
} else if (fLabels != null) {
|
||||
labels = Nd4j.create(fLabels);
|
||||
features = Nd4j.create(fFeatures);
|
||||
} else if (dLabels != null) {
|
||||
labels = Nd4j.create(dLabels);
|
||||
features = Nd4j.create(dFeatures);
|
||||
}
|
||||
|
||||
DataSet dataSet = new DataSet(features, labels);
|
||||
try {
|
||||
queue.add(dataSet);
|
||||
} catch (Exception e) {
|
||||
// live with it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next element in the iteration.
|
||||
*
|
||||
* @return the next element in the iteration
|
||||
* @throws NoSuchElementException if the iteration has no more elements
|
||||
*/
|
||||
@Override
|
||||
public DataSet next() throws NoSuchElementException {
|
||||
if (queue.isEmpty())
|
||||
throw new NoSuchElementException();
|
||||
|
||||
DataSet dataSet = queue.poll();
|
||||
if (preProcessor != null)
|
||||
preProcessor.preProcess(dataSet);
|
||||
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes from the underlying collection the last element returned
|
||||
* by this iterator (optional operation). This method can be called
|
||||
* only once per call to {@link #next}. The behavior of an iterator
|
||||
* is unspecified if the underlying collection is modified while the
|
||||
* iteration is in progress in any way other than by calling this
|
||||
* method.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the {@code remove}
|
||||
* operation is not supported by this iterator
|
||||
* @throws IllegalStateException if the {@code next} method has not
|
||||
* yet been called, or the {@code remove} method has already
|
||||
* been called after the last call to the {@code next}
|
||||
* method
|
||||
* @implSpec The default implementation throws an instance of
|
||||
* {@link UnsupportedOperationException} and performs no other action.
|
||||
*/
|
||||
@Override
|
||||
public void remove() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSetPreProcessor getPreProcessor() {
|
||||
return preProcessor;
|
||||
}
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
import org.nd4j.linalg.dataset.callbacks.DataSetCallback;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
@Slf4j
|
||||
@Deprecated
|
||||
public class AsyncDataSetIterator extends org.nd4j.linalg.dataset.AsyncDataSetIterator {
|
||||
|
||||
/**
|
||||
* Create an Async iterator with the default queue size of 8
|
||||
* @param baseIterator Underlying iterator to wrap and fetch asynchronously from
|
||||
*/
|
||||
public AsyncDataSetIterator(DataSetIterator baseIterator) {
|
||||
super(baseIterator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an Async iterator with the default queue size of 8
|
||||
* @param iterator Underlying iterator to wrap and fetch asynchronously from
|
||||
* @param queue Queue size - number of iterators to
|
||||
*/
|
||||
public AsyncDataSetIterator(DataSetIterator iterator, int queueSize, BlockingQueue<DataSet> queue) {
|
||||
super(iterator, queueSize, queue);
|
||||
}
|
||||
|
||||
public AsyncDataSetIterator(DataSetIterator baseIterator, int queueSize) {
|
||||
super(baseIterator, queueSize);
|
||||
}
|
||||
|
||||
public AsyncDataSetIterator(DataSetIterator baseIterator, int queueSize, boolean useWorkspace) {
|
||||
super(baseIterator, queueSize, useWorkspace);
|
||||
}
|
||||
|
||||
public AsyncDataSetIterator(DataSetIterator baseIterator, int queueSize, boolean useWorkspace, Integer deviceId) {
|
||||
super(baseIterator, queueSize, useWorkspace, deviceId);
|
||||
}
|
||||
|
||||
public AsyncDataSetIterator(DataSetIterator baseIterator, int queueSize, boolean useWorkspace, DataSetCallback callback) {
|
||||
super(baseIterator, queueSize, useWorkspace, callback);
|
||||
}
|
||||
|
||||
public AsyncDataSetIterator(DataSetIterator iterator, int queueSize, BlockingQueue<DataSet> queue, boolean useWorkspace) {
|
||||
super(iterator, queueSize, queue, useWorkspace);
|
||||
}
|
||||
|
||||
public AsyncDataSetIterator(DataSetIterator iterator, int queueSize, BlockingQueue<DataSet> queue, boolean useWorkspace, DataSetCallback callback) {
|
||||
super(iterator, queueSize, queue, useWorkspace, callback);
|
||||
}
|
||||
|
||||
public AsyncDataSetIterator(DataSetIterator iterator, int queueSize, BlockingQueue<DataSet> queue,
|
||||
boolean useWorkspace, DataSetCallback callback, Integer deviceId) {
|
||||
super(iterator, queueSize, queue, useWorkspace, callback, deviceId);
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSet;
|
||||
import org.nd4j.linalg.dataset.api.iterator.MultiDataSetIterator;
|
||||
import org.nd4j.linalg.dataset.callbacks.DataSetCallback;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
@Slf4j
|
||||
@Deprecated
|
||||
public class AsyncMultiDataSetIterator extends org.nd4j.linalg.dataset.AsyncMultiDataSetIterator {
|
||||
|
||||
public AsyncMultiDataSetIterator(MultiDataSetIterator baseIterator) {
|
||||
super(baseIterator);
|
||||
}
|
||||
|
||||
public AsyncMultiDataSetIterator(MultiDataSetIterator iterator, int queueSize, BlockingQueue<MultiDataSet> queue) {
|
||||
super(iterator, queueSize, queue);
|
||||
}
|
||||
|
||||
public AsyncMultiDataSetIterator(MultiDataSetIterator baseIterator, int queueSize) {
|
||||
super(baseIterator, queueSize);
|
||||
}
|
||||
|
||||
public AsyncMultiDataSetIterator(MultiDataSetIterator baseIterator, int queueSize, boolean useWorkspace) {
|
||||
super(baseIterator, queueSize, useWorkspace);
|
||||
}
|
||||
|
||||
public AsyncMultiDataSetIterator(MultiDataSetIterator baseIterator, int queueSize, boolean useWorkspace,
|
||||
Integer deviceId) {
|
||||
super(baseIterator, queueSize, useWorkspace, deviceId);
|
||||
}
|
||||
|
||||
public AsyncMultiDataSetIterator(MultiDataSetIterator iterator, int queueSize, BlockingQueue<MultiDataSet> queue,
|
||||
boolean useWorkspace) {
|
||||
super(iterator, queueSize, queue, useWorkspace);
|
||||
}
|
||||
|
||||
public AsyncMultiDataSetIterator(MultiDataSetIterator iterator, int queueSize, BlockingQueue<MultiDataSet> queue,
|
||||
boolean useWorkspace, DataSetCallback callback) {
|
||||
super(iterator, queueSize, queue, useWorkspace, callback);
|
||||
}
|
||||
|
||||
public AsyncMultiDataSetIterator(MultiDataSetIterator iterator, int queueSize, BlockingQueue<MultiDataSet> queue,
|
||||
boolean useWorkspace, DataSetCallback callback, Integer deviceId) {
|
||||
super(iterator, queueSize, queue, useWorkspace, callback, deviceId);
|
||||
}
|
||||
}
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
|
||||
import lombok.NonNull;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AsyncShieldDataSetIterator implements DataSetIterator {
|
||||
private DataSetIterator backingIterator;
|
||||
|
||||
/**
|
||||
* @param iterator Iterator to wrop, to disable asynchronous prefetching for
|
||||
*/
|
||||
public AsyncShieldDataSetIterator(@NonNull DataSetIterator iterator) {
|
||||
this.backingIterator = iterator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like the standard next method but allows a
|
||||
* customizable number of examples returned
|
||||
*
|
||||
* @param num the number of examples
|
||||
* @return the next data applyTransformToDestination
|
||||
*/
|
||||
@Override
|
||||
public DataSet next(int num) {
|
||||
return backingIterator.next(num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Input columns for the dataset
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int inputColumns() {
|
||||
return backingIterator.inputColumns();
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of labels for the dataset
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int totalOutcomes() {
|
||||
return backingIterator.totalOutcomes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is resetting supported by this DataSetIterator? Many DataSetIterators do support resetting,
|
||||
* but some don't
|
||||
*
|
||||
* @return true if reset method is supported; false otherwise
|
||||
*/
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return backingIterator.resetSupported();
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this DataSetIterator support asynchronous prefetching of multiple DataSet objects?
|
||||
*
|
||||
* PLEASE NOTE: This iterator ALWAYS returns FALSE
|
||||
*
|
||||
* @return true if asynchronous prefetching from this iterator is OK; false if asynchronous prefetching should not
|
||||
* be used with this iterator
|
||||
*/
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the iterator back to the beginning
|
||||
*/
|
||||
@Override
|
||||
public void reset() {
|
||||
backingIterator.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch size
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int batch() {
|
||||
return backingIterator.batch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a pre processor
|
||||
*
|
||||
* @param preProcessor a pre processor to set
|
||||
*/
|
||||
@Override
|
||||
public void setPreProcessor(DataSetPreProcessor preProcessor) {
|
||||
backingIterator.setPreProcessor(preProcessor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns preprocessors, if defined
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public DataSetPreProcessor getPreProcessor() {
|
||||
return backingIterator.getPreProcessor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get dataset iterator record reader labels
|
||||
*/
|
||||
@Override
|
||||
public List<String> getLabels() {
|
||||
return backingIterator.getLabels();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the iteration has more elements.
|
||||
* (In other words, returns {@code true} if {@link #next} would
|
||||
* return an element rather than throwing an exception.)
|
||||
*
|
||||
* @return {@code true} if the iteration has more elements
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return backingIterator.hasNext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next element in the iteration.
|
||||
*
|
||||
* @return the next element in the iteration
|
||||
*/
|
||||
@Override
|
||||
public DataSet next() {
|
||||
return backingIterator.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes from the underlying collection the last element returned
|
||||
* by this iterator (optional operation). This method can be called
|
||||
* only once per call to {@link #next}. The behavior of an iterator
|
||||
* is unspecified if the underlying collection is modified while the
|
||||
* iteration is in progress in any way other than by calling this
|
||||
* method.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the {@code remove}
|
||||
* operation is not supported by this iterator
|
||||
* @throws IllegalStateException if the {@code next} method has not
|
||||
* yet been called, or the {@code remove} method has already
|
||||
* been called after the last call to the {@code next}
|
||||
* method
|
||||
* @implSpec The default implementation throws an instance of
|
||||
* {@link UnsupportedOperationException} and performs no other action.
|
||||
*/
|
||||
@Override
|
||||
public void remove() {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.NonNull;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSet;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.MultiDataSetIterator;
|
||||
|
||||
public class AsyncShieldMultiDataSetIterator implements MultiDataSetIterator {
|
||||
private MultiDataSetIterator backingIterator;
|
||||
|
||||
public AsyncShieldMultiDataSetIterator(@NonNull MultiDataSetIterator iterator) {
|
||||
this.backingIterator = iterator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the next 'num' examples. Similar to the next method, but returns a specified number of examples
|
||||
*
|
||||
* @param num Number of examples to fetch
|
||||
*/
|
||||
@Override
|
||||
public MultiDataSet next(int num) {
|
||||
return backingIterator.next(num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the preprocessor to be applied to each MultiDataSet, before each MultiDataSet is returned.
|
||||
*
|
||||
* @param preProcessor MultiDataSetPreProcessor. May be null.
|
||||
*/
|
||||
@Override
|
||||
public void setPreProcessor(MultiDataSetPreProcessor preProcessor) {
|
||||
backingIterator.setPreProcessor(preProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSetPreProcessor getPreProcessor() {
|
||||
return backingIterator.getPreProcessor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is resetting supported by this DataSetIterator? Many DataSetIterators do support resetting,
|
||||
* but some don't
|
||||
*
|
||||
* @return true if reset method is supported; false otherwise
|
||||
*/
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return backingIterator.resetSupported();
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Does this DataSetIterator support asynchronous prefetching of multiple DataSet objects?
|
||||
*
|
||||
* PLEASE NOTE: This iterator ALWAYS returns FALSE
|
||||
*
|
||||
* @return true if asynchronous prefetching from this iterator is OK; false if asynchronous prefetching should not
|
||||
* be used with this iterator
|
||||
*/
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the iterator back to the beginning
|
||||
*/
|
||||
@Override
|
||||
public void reset() {
|
||||
backingIterator.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the iteration has more elements.
|
||||
* (In other words, returns {@code true} if {@link #next} would
|
||||
* return an element rather than throwing an exception.)
|
||||
*
|
||||
* @return {@code true} if the iteration has more elements
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return backingIterator.hasNext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next element in the iteration.
|
||||
*
|
||||
* @return the next element in the iteration
|
||||
*/
|
||||
@Override
|
||||
public MultiDataSet next() {
|
||||
return backingIterator.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes from the underlying collection the last element returned
|
||||
* by this iterator (optional operation). This method can be called
|
||||
* only once per call to {@link #next}. The behavior of an iterator
|
||||
* is unspecified if the underlying collection is modified while the
|
||||
* iteration is in progress in any way other than by calling this
|
||||
* method.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the {@code remove}
|
||||
* operation is not supported by this iterator
|
||||
* @throws IllegalStateException if the {@code next} method has not
|
||||
* yet been called, or the {@code remove} method has already
|
||||
* been called after the last call to the {@code next}
|
||||
* method
|
||||
* @implSpec The default implementation throws an instance of
|
||||
* {@link UnsupportedOperationException} and performs no other action.
|
||||
*/
|
||||
@Override
|
||||
public void remove() {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
import org.nd4j.linalg.dataset.api.iterator.fetcher.BaseDataFetcher;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BaseDatasetIterator implements DataSetIterator {
|
||||
|
||||
protected int batch, numExamples;
|
||||
protected BaseDataFetcher fetcher;
|
||||
@Getter
|
||||
protected DataSetPreProcessor preProcessor;
|
||||
|
||||
|
||||
public BaseDatasetIterator(int batch, int numExamples, BaseDataFetcher fetcher) {
|
||||
if(batch <= 0){
|
||||
throw new IllegalArgumentException("Invalid minibatch size: must be > 0 (got: " + batch + ")");
|
||||
}
|
||||
this.batch = batch;
|
||||
if (numExamples < 0)
|
||||
numExamples = fetcher.totalExamples();
|
||||
|
||||
this.numExamples = numExamples;
|
||||
this.fetcher = fetcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return fetcher.hasMore() && fetcher.cursor() < numExamples;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next() {
|
||||
fetcher.fetch(batch);
|
||||
DataSet result = fetcher.next();
|
||||
if (preProcessor != null) {
|
||||
preProcessor.preProcess(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next(int num) {
|
||||
fetcher.fetch(num);
|
||||
DataSet next = fetcher.next();
|
||||
if (preProcessor != null)
|
||||
preProcessor.preProcess(next);
|
||||
return next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int inputColumns() {
|
||||
return fetcher.inputColumns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int totalOutcomes() {
|
||||
return fetcher.totalOutcomes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
fetcher.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batch() {
|
||||
return batch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(DataSetPreProcessor preProcessor) {
|
||||
this.preProcessor = preProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLabels() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.NonNull;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSet;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSetPreProcessor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CombinedMultiDataSetPreProcessor implements MultiDataSetPreProcessor {
|
||||
|
||||
private List<MultiDataSetPreProcessor> preProcessors;
|
||||
|
||||
private CombinedMultiDataSetPreProcessor() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preProcess(MultiDataSet multiDataSet) {
|
||||
for (MultiDataSetPreProcessor preProcessor : preProcessors) {
|
||||
preProcessor.preProcess(multiDataSet);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private List<MultiDataSetPreProcessor> preProcessors = new ArrayList<>();
|
||||
|
||||
public Builder() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param preProcessor to be added to list of preprocessors to be applied
|
||||
*/
|
||||
public Builder addPreProcessor(@NonNull MultiDataSetPreProcessor preProcessor) {
|
||||
preProcessors.add(preProcessor);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the specified preprocessor at the specified position to the list of preprocessors to be applied
|
||||
* @param idx the position to apply the specified preprocessor at
|
||||
* @param preProcessor to be added to list of preprocessors to be applied
|
||||
*/
|
||||
public Builder addPreProcessor(int idx, @NonNull MultiDataSetPreProcessor preProcessor) {
|
||||
preProcessors.add(idx, preProcessor);
|
||||
return this;
|
||||
}
|
||||
|
||||
public CombinedMultiDataSetPreProcessor build() {
|
||||
CombinedMultiDataSetPreProcessor preProcessor = new CombinedMultiDataSetPreProcessor();
|
||||
preProcessor.preProcessors = this.preProcessors;
|
||||
return preProcessor;
|
||||
}
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.NonNull;
|
||||
import org.nd4j.linalg.dataset.api.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CombinedPreProcessor implements DataSetPreProcessor {
|
||||
private List<DataSetPreProcessor> preProcessors;
|
||||
|
||||
private CombinedPreProcessor() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre process a dataset sequentially
|
||||
*
|
||||
* @param toPreProcess the data set to pre process
|
||||
*/
|
||||
@Override
|
||||
public void preProcess(DataSet toPreProcess) {
|
||||
for (DataSetPreProcessor preProcessor : preProcessors) {
|
||||
preProcessor.preProcess(toPreProcess);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private List<DataSetPreProcessor> preProcessors = new ArrayList<>();
|
||||
|
||||
public Builder() {
|
||||
|
||||
}
|
||||
|
||||
public Builder addPreProcessor(@NonNull DataSetPreProcessor preProcessor) {
|
||||
preProcessors.add(preProcessor);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addPreProcessor(int idx, @NonNull DataSetPreProcessor preProcessor) {
|
||||
preProcessors.add(idx, preProcessor);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public CombinedPreProcessor build() {
|
||||
CombinedPreProcessor preProcessor = new CombinedPreProcessor();
|
||||
preProcessor.preProcessors = this.preProcessors;
|
||||
return preProcessor;
|
||||
}
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Deprecated
|
||||
public interface DataSetFetcher extends Serializable {
|
||||
|
||||
/**
|
||||
* Whether the dataset has more to load
|
||||
* @return whether the data applyTransformToDestination has more to load
|
||||
*/
|
||||
boolean hasMore();
|
||||
|
||||
/**
|
||||
* Returns the next data applyTransformToDestination
|
||||
* @return the next dataset
|
||||
*/
|
||||
DataSet next();
|
||||
|
||||
/**
|
||||
* Fetches the next dataset. You need to call this
|
||||
* to get a new dataset, otherwise {@link #next()}
|
||||
* just returns the last data applyTransformToDestination fetch
|
||||
* @param numExamples the number of examples to fetch
|
||||
*/
|
||||
void fetch(int numExamples);
|
||||
|
||||
/**
|
||||
* The number of labels for a dataset
|
||||
* @return the number of labels for a dataset
|
||||
*/
|
||||
int totalOutcomes();
|
||||
|
||||
/**
|
||||
* The length of a feature vector for an individual example
|
||||
* @return the length of a feature vector for an individual example
|
||||
*/
|
||||
int inputColumns();
|
||||
|
||||
/**
|
||||
* The total number of examples
|
||||
* @return the total number of examples
|
||||
*/
|
||||
int totalExamples();
|
||||
|
||||
/**
|
||||
* Returns the fetcher back to the beginning of the dataset
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* Direct access to a number represenative of iterating through a dataset
|
||||
* @return a cursor similar to an index
|
||||
*/
|
||||
int cursor();
|
||||
}
|
||||
+344
@@ -0,0 +1,344 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import lombok.val;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
import org.nd4j.linalg.exception.ND4JIllegalStateException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
@Slf4j
|
||||
public class DataSetIteratorSplitter {
|
||||
protected DataSetIterator backedIterator;
|
||||
protected final long totalExamples;
|
||||
protected final double ratio;
|
||||
protected final double[] ratios;
|
||||
protected final long numTrain;
|
||||
protected final long numTest;
|
||||
protected final long numArbitrarySets;
|
||||
protected final int[] splits;
|
||||
|
||||
|
||||
protected AtomicLong counter = new AtomicLong(0);
|
||||
|
||||
protected AtomicBoolean resetPending = new AtomicBoolean(false);
|
||||
protected DataSet firstTrain = null;
|
||||
|
||||
|
||||
/**
|
||||
* The only constructor
|
||||
*
|
||||
* @param baseIterator - iterator to be wrapped and split
|
||||
* @param totalBatches - total batches in baseIterator
|
||||
* @param ratio - train/test split ratio
|
||||
*/
|
||||
public DataSetIteratorSplitter(@NonNull DataSetIterator baseIterator, long totalBatches, double ratio) {
|
||||
if (!(ratio > 0.0 && ratio < 1.0))
|
||||
throw new ND4JIllegalStateException("Ratio value should be in range of 0.0 > X < 1.0");
|
||||
|
||||
if (totalBatches < 0)
|
||||
throw new ND4JIllegalStateException("totalExamples number should be positive value");
|
||||
|
||||
if (!baseIterator.resetSupported())
|
||||
throw new ND4JIllegalStateException("Underlying iterator doesn't support reset, so it can't be used for runtime-split");
|
||||
|
||||
|
||||
this.backedIterator = baseIterator;
|
||||
this.totalExamples = totalBatches;
|
||||
this.ratio = ratio;
|
||||
ratios = new double[]{ratio, 1 - ratio};
|
||||
this.numTrain = (long) (totalExamples * ratio);
|
||||
this.numTest = totalExamples - numTrain;
|
||||
this.numArbitrarySets = 2;
|
||||
this.splits = new int[this.ratios.length];
|
||||
for (int i = 0; i < this.splits.length; ++i) {
|
||||
this.splits[i] = (int)(totalExamples * ratios[i]);
|
||||
}
|
||||
|
||||
|
||||
log.warn("IteratorSplitter is used: please ensure you don't use randomization/shuffle in underlying iterator!");
|
||||
}
|
||||
|
||||
public DataSetIteratorSplitter(@NonNull DataSetIterator baseIterator, long totalBatches, double[] ratios) {
|
||||
for (double ratio : ratios) {
|
||||
if (!(ratio > 0.0 && ratio < 1.0))
|
||||
throw new ND4JIllegalStateException("Ratio value should be in range of 0.0 > X < 1.0");
|
||||
}
|
||||
|
||||
if (totalBatches < 0)
|
||||
throw new ND4JIllegalStateException("totalExamples number should be positive value");
|
||||
|
||||
if (!baseIterator.resetSupported())
|
||||
throw new ND4JIllegalStateException("Underlying iterator doesn't support reset, so it can't be used for runtime-split");
|
||||
|
||||
|
||||
this.backedIterator = baseIterator;
|
||||
this.totalExamples = totalBatches;
|
||||
this.ratio = 0.0;
|
||||
this.ratios = ratios;
|
||||
this.numTrain = 0; //(long) (totalExamples * ratio);
|
||||
this.numTest = 0; //totalExamples - numTrain;
|
||||
this.numArbitrarySets = ratios.length;
|
||||
|
||||
this.splits = new int[this.ratios.length];
|
||||
for (int i = 0; i < this.splits.length; ++i) {
|
||||
this.splits[i] = (int)(totalExamples * ratios[i]);
|
||||
}
|
||||
|
||||
log.warn("IteratorSplitter is used: please ensure you don't use randomization/shuffle in underlying iterator!");
|
||||
}
|
||||
|
||||
public DataSetIteratorSplitter(@NonNull DataSetIterator baseIterator, int[] splits) {
|
||||
int totalBatches = 0;
|
||||
for (val v:splits)
|
||||
totalBatches += v;
|
||||
|
||||
if (totalBatches < 0)
|
||||
throw new ND4JIllegalStateException("totalExamples number should be positive value");
|
||||
|
||||
if (!baseIterator.resetSupported())
|
||||
throw new ND4JIllegalStateException("Underlying iterator doesn't support reset, so it can't be used for runtime-split");
|
||||
|
||||
|
||||
this.backedIterator = baseIterator;
|
||||
this.totalExamples = totalBatches;
|
||||
this.ratio = 0.0;
|
||||
this.ratios = null;
|
||||
|
||||
this.numTrain = 0;
|
||||
this.numTest = 0;
|
||||
this.splits = splits;
|
||||
this.numArbitrarySets = splits.length;
|
||||
|
||||
log.warn("IteratorSplitter is used: please ensure you don't use randomization/shuffle in underlying iterator!");
|
||||
}
|
||||
|
||||
public List<DataSetIterator> getIterators() {
|
||||
List<DataSetIterator> retVal = new ArrayList<>();
|
||||
int partN = 0;
|
||||
int bottom = 0;
|
||||
for (final int split : splits) {
|
||||
ScrollableDataSetIterator partIterator =
|
||||
new ScrollableDataSetIterator(partN++,
|
||||
backedIterator,
|
||||
counter,
|
||||
resetPending,
|
||||
firstTrain,
|
||||
new int[]{bottom,split});
|
||||
bottom += split;
|
||||
retVal.add(partIterator);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns train iterator instance
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public DataSetIterator getTrainIterator() {
|
||||
return new DataSetIterator() {
|
||||
@Override
|
||||
public DataSet next(int i) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLabels() {
|
||||
return backedIterator.getLabels();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int inputColumns() {
|
||||
return backedIterator.inputColumns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int totalOutcomes() {
|
||||
return backedIterator.totalOutcomes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return backedIterator.resetSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return backedIterator.asyncSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
resetPending.set(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batch() {
|
||||
return backedIterator.batch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(DataSetPreProcessor dataSetPreProcessor) {
|
||||
backedIterator.setPreProcessor(dataSetPreProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSetPreProcessor getPreProcessor() {
|
||||
return backedIterator.getPreProcessor();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (resetPending.get()) {
|
||||
if (resetSupported()) {
|
||||
backedIterator.reset();
|
||||
counter.set(0);
|
||||
resetPending.set(false);
|
||||
} else
|
||||
throw new UnsupportedOperationException("Reset isn't supported by underlying iterator");
|
||||
}
|
||||
|
||||
val state = backedIterator.hasNext();
|
||||
if (state && counter.get() < numTrain)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next() {
|
||||
counter.incrementAndGet();
|
||||
val p = backedIterator.next();
|
||||
|
||||
if (counter.get() == 1 && firstTrain == null) {
|
||||
// first epoch ever, we'll save first dataset and will use it to check for equality later
|
||||
firstTrain = p.copy();
|
||||
firstTrain.detach();
|
||||
} else if (counter.get() == 1) {
|
||||
// epoch > 1, comparing first dataset to previously stored dataset. they should be equal
|
||||
int cnt = 0;
|
||||
if (!p.getFeatures().equalsWithEps(firstTrain.getFeatures(), 1e-5))
|
||||
throw new ND4JIllegalStateException("First examples do not match. Randomization was used?");
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns test iterator instance
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public DataSetIterator getTestIterator() {
|
||||
return new DataSetIterator() {
|
||||
@Override
|
||||
public DataSet next(int i) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLabels() {
|
||||
return backedIterator.getLabels();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int inputColumns() {
|
||||
return backedIterator.inputColumns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int totalOutcomes() {
|
||||
return backedIterator.totalOutcomes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return backedIterator.resetSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return backedIterator.asyncSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
resetPending.set(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batch() {
|
||||
return backedIterator.batch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(DataSetPreProcessor dataSetPreProcessor) {
|
||||
backedIterator.setPreProcessor(dataSetPreProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSetPreProcessor getPreProcessor() {
|
||||
return backedIterator.getPreProcessor();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
val state = backedIterator.hasNext();
|
||||
if (state && counter.get() < numTrain + numTest)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next() {
|
||||
counter.incrementAndGet();
|
||||
return backedIterator.next();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.NonNull;
|
||||
import org.nd4j.common.primitives.Pair;
|
||||
|
||||
public class DoublesDataSetIterator extends AbstractDataSetIterator<double[]> {
|
||||
|
||||
/**
|
||||
* @param iterable Iterable to source data from
|
||||
* @param batchSize Batch size for generated DataSet objects
|
||||
*/
|
||||
public DoublesDataSetIterator(@NonNull Iterable<Pair<double[], double[]>> iterable, int batchSize) {
|
||||
super(iterable, batchSize);
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import lombok.val;
|
||||
import org.nd4j.linalg.dataset.api.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.iterator.BlockDataSetIterator;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@Slf4j
|
||||
public class DummyBlockDataSetIterator implements BlockDataSetIterator {
|
||||
protected final DataSetIterator iterator;
|
||||
|
||||
public DummyBlockDataSetIterator(@NonNull DataSetIterator iterator) {
|
||||
this.iterator = iterator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAnything() {
|
||||
return iterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet[] next(int maxDatasets) {
|
||||
val list = new ArrayList<DataSet>(maxDatasets);
|
||||
int cnt = 0;
|
||||
while (iterator.hasNext() && cnt < maxDatasets) {
|
||||
list.add(iterator.next());
|
||||
cnt++;
|
||||
}
|
||||
|
||||
return list.toArray(new DataSet[list.size()]);
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import lombok.val;
|
||||
import org.nd4j.linalg.dataset.api.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSet;
|
||||
import org.nd4j.linalg.dataset.api.iterator.BlockDataSetIterator;
|
||||
import org.nd4j.linalg.dataset.api.iterator.BlockMultiDataSetIterator;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
import org.nd4j.linalg.dataset.api.iterator.MultiDataSetIterator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@Slf4j
|
||||
public class DummyBlockMultiDataSetIterator implements BlockMultiDataSetIterator {
|
||||
protected final MultiDataSetIterator iterator;
|
||||
|
||||
public DummyBlockMultiDataSetIterator(@NonNull MultiDataSetIterator iterator) {
|
||||
this.iterator = iterator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAnything() {
|
||||
return iterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSet[] next(int maxDatasets) {
|
||||
val list = new ArrayList<MultiDataSet>(maxDatasets);
|
||||
int cnt = 0;
|
||||
while (iterator.hasNext() && cnt < maxDatasets) {
|
||||
list.add(iterator.next());
|
||||
cnt++;
|
||||
}
|
||||
|
||||
return list.toArray(new MultiDataSet[list.size()]);
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import org.nd4j.linalg.dataset.api.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
|
||||
public class DummyPreProcessor implements DataSetPreProcessor {
|
||||
/**
|
||||
* Pre process a dataset
|
||||
*
|
||||
* @param toPreProcess the data set to pre process
|
||||
*/
|
||||
@Override
|
||||
public void preProcess(DataSet toPreProcess) {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EarlyTerminationDataSetIterator implements DataSetIterator {
|
||||
|
||||
private DataSetIterator underlyingIterator;
|
||||
private int terminationPoint;
|
||||
private int minibatchCount = 0;
|
||||
|
||||
/**
|
||||
* Constructor takes the iterator to wrap and the number of minibatches after which the call to hasNext()
|
||||
* will return false
|
||||
* @param underlyingIterator, iterator to wrap
|
||||
* @param terminationPoint, minibatches after which hasNext() will return false
|
||||
*/
|
||||
public EarlyTerminationDataSetIterator(DataSetIterator underlyingIterator, int terminationPoint) {
|
||||
if (terminationPoint <= 0)
|
||||
throw new IllegalArgumentException(
|
||||
"Termination point (the number of calls to .next() or .next(num)) has to be > 0");
|
||||
this.underlyingIterator = underlyingIterator;
|
||||
this.terminationPoint = terminationPoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next(int num) {
|
||||
if (minibatchCount < terminationPoint) {
|
||||
minibatchCount++;
|
||||
return underlyingIterator.next(num);
|
||||
} else {
|
||||
throw new RuntimeException("Calls to next have exceeded termination point.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int inputColumns() {
|
||||
return underlyingIterator.inputColumns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int totalOutcomes() {
|
||||
return underlyingIterator.totalOutcomes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return underlyingIterator.resetSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return underlyingIterator.asyncSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
minibatchCount = 0;
|
||||
underlyingIterator.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batch() {
|
||||
return underlyingIterator.batch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(DataSetPreProcessor preProcessor) {
|
||||
underlyingIterator.setPreProcessor(preProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSetPreProcessor getPreProcessor() {
|
||||
return underlyingIterator.getPreProcessor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLabels() {
|
||||
return underlyingIterator.getLabels();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return underlyingIterator.hasNext() && minibatchCount < terminationPoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next() {
|
||||
if (minibatchCount < terminationPoint) {
|
||||
minibatchCount++;
|
||||
return underlyingIterator.next();
|
||||
} else {
|
||||
throw new RuntimeException("Calls to next have exceeded the allotted number of minibatches.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
underlyingIterator.remove();
|
||||
}
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSet;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.MultiDataSetIterator;
|
||||
|
||||
public class EarlyTerminationMultiDataSetIterator implements MultiDataSetIterator {
|
||||
|
||||
private MultiDataSetIterator underlyingIterator;
|
||||
private int terminationPoint;
|
||||
private int minibatchCount = 0;
|
||||
|
||||
/**
|
||||
* Constructor takes the iterator to wrap and the number of minibatches after which the call to hasNext()
|
||||
* will return false
|
||||
* @param underlyingIterator, iterator to wrap
|
||||
* @param terminationPoint, minibatches after which hasNext() will return false
|
||||
*/
|
||||
public EarlyTerminationMultiDataSetIterator(MultiDataSetIterator underlyingIterator, int terminationPoint) {
|
||||
if (terminationPoint <= 0)
|
||||
throw new IllegalArgumentException(
|
||||
"Termination point (the number of calls to .next() or .next(num)) has to be > 0");
|
||||
this.underlyingIterator = underlyingIterator;
|
||||
this.terminationPoint = terminationPoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSet next(int num) {
|
||||
if (minibatchCount < terminationPoint) {
|
||||
minibatchCount++;
|
||||
return underlyingIterator.next(num);
|
||||
} else {
|
||||
throw new RuntimeException("Calls to next have exceeded termination point.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(MultiDataSetPreProcessor preProcessor) {
|
||||
underlyingIterator.setPreProcessor(preProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSetPreProcessor getPreProcessor() {
|
||||
return underlyingIterator.getPreProcessor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return underlyingIterator.resetSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return underlyingIterator.asyncSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
minibatchCount = 0;
|
||||
underlyingIterator.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return underlyingIterator.hasNext() && minibatchCount < terminationPoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSet next() {
|
||||
if (minibatchCount < terminationPoint) {
|
||||
minibatchCount++;
|
||||
return underlyingIterator.next();
|
||||
} else {
|
||||
throw new RuntimeException("Calls to next have exceeded the allotted number of minibatches.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
underlyingIterator.remove();
|
||||
}
|
||||
}
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class ExistingDataSetIterator implements DataSetIterator {
|
||||
@Getter
|
||||
private DataSetPreProcessor preProcessor;
|
||||
|
||||
private transient Iterable<DataSet> iterable;
|
||||
private transient Iterator<DataSet> iterator;
|
||||
private int totalExamples = 0;
|
||||
private int numFeatures = 0;
|
||||
private int numLabels = 0;
|
||||
private List<String> labels;
|
||||
|
||||
/**
|
||||
* Note that when using this constructor, resetting is not supported
|
||||
* @param iterator Iterator to wrap
|
||||
*/
|
||||
public ExistingDataSetIterator(@NonNull Iterator<DataSet> iterator) {
|
||||
this.iterator = iterator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note that when using this constructor, resetting is not supported
|
||||
* @param iterator Iterator to wrap
|
||||
* @param labels String labels. May be null.
|
||||
*/
|
||||
public ExistingDataSetIterator(@NonNull Iterator<DataSet> iterator, @NonNull List<String> labels) {
|
||||
this(iterator);
|
||||
this.labels = labels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the specified iterable. Supports resetting
|
||||
* @param iterable Iterable to wrap
|
||||
*/
|
||||
public ExistingDataSetIterator(@NonNull Iterable<DataSet> iterable) {
|
||||
this.iterable = iterable;
|
||||
this.iterator = iterable.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the specified iterable. Supports resetting
|
||||
* @param iterable Iterable to wrap
|
||||
* @param labels Labels list. May be null
|
||||
*/
|
||||
public ExistingDataSetIterator(@NonNull Iterable<DataSet> iterable, @NonNull List<String> labels) {
|
||||
this(iterable);
|
||||
this.labels = labels;
|
||||
}
|
||||
|
||||
|
||||
public ExistingDataSetIterator(@NonNull Iterable<DataSet> iterable, int totalExamples, int numFeatures,
|
||||
int numLabels) {
|
||||
this(iterable);
|
||||
|
||||
this.totalExamples = totalExamples;
|
||||
this.numFeatures = numFeatures;
|
||||
this.numLabels = numLabels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next(int num) {
|
||||
// TODO: this might be changed
|
||||
throw new UnsupportedOperationException("next(int) isn't supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int inputColumns() {
|
||||
return numFeatures;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int totalOutcomes() {
|
||||
if (labels != null)
|
||||
return labels.size();
|
||||
|
||||
return numLabels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return iterable != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
//No need to asynchronously prefetch here: already in memory
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
if (iterable != null)
|
||||
this.iterator = iterable.iterator();
|
||||
else
|
||||
throw new IllegalStateException(
|
||||
"To use reset() method you need to provide Iterable<DataSet>, not Iterator");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batch() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(DataSetPreProcessor preProcessor) {
|
||||
this.preProcessor = preProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLabels() {
|
||||
return labels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (iterator != null)
|
||||
return iterator.hasNext();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next() {
|
||||
if (preProcessor != null) {
|
||||
DataSet ds = iterator.next();
|
||||
if (!ds.isPreProcessed()) {
|
||||
preProcessor.preProcess(ds);
|
||||
ds.markAsPreProcessed();
|
||||
}
|
||||
return ds;
|
||||
} else
|
||||
return iterator.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.deeplearning4j.datasets.iterator.callbacks.FileCallback;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Slf4j
|
||||
public class FileSplitDataSetIterator implements DataSetIterator {
|
||||
private DataSetPreProcessor preProcessor;
|
||||
|
||||
private List<File> files;
|
||||
private int numFiles;
|
||||
private AtomicInteger counter = new AtomicInteger(0);
|
||||
private FileCallback callback;
|
||||
|
||||
/**
|
||||
* @param files List of files to iterate over
|
||||
* @param callback Callback for loading the files
|
||||
*/
|
||||
public FileSplitDataSetIterator(@NonNull List<File> files, @NonNull FileCallback callback) {
|
||||
this.files = files;
|
||||
this.numFiles = files.size();
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DataSet next(int num) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int inputColumns() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int totalOutcomes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
counter.set(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batch() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(DataSetPreProcessor preProcessor) {
|
||||
this.preProcessor = preProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSetPreProcessor getPreProcessor() {
|
||||
return preProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLabels() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return counter.get() < numFiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next() {
|
||||
// long time1 = System.nanoTime();
|
||||
DataSet ds = callback.call(files.get(counter.getAndIncrement()));
|
||||
|
||||
if (preProcessor != null && ds != null)
|
||||
preProcessor.preProcess(ds);
|
||||
|
||||
// long time2 = System.nanoTime();
|
||||
|
||||
// if (counter.get() % 5 == 0)
|
||||
// log.info("Device: [{}]; Time: [{}] ns;", Nd4j.getAffinityManager().getDeviceForCurrentThread(), time2 - time1);
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.NonNull;
|
||||
import org.nd4j.common.primitives.Pair;
|
||||
|
||||
public class FloatsDataSetIterator extends AbstractDataSetIterator<float[]> {
|
||||
|
||||
/**
|
||||
* @param iterable Iterable to source data from
|
||||
* @param batchSize Batch size for generated DataSet objects
|
||||
*/
|
||||
public FloatsDataSetIterator(@NonNull Iterable<Pair<float[], float[]>> iterable, int batchSize) {
|
||||
super(iterable, batchSize);
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.NonNull;
|
||||
import org.nd4j.linalg.api.ndarray.INDArray;
|
||||
import org.nd4j.common.primitives.Pair;
|
||||
|
||||
public class INDArrayDataSetIterator extends AbstractDataSetIterator<INDArray> {
|
||||
|
||||
/**
|
||||
* @param iterable Iterable to source data from
|
||||
* @param batchSize Batch size for generated DataSet objects
|
||||
*/
|
||||
public INDArrayDataSetIterator(@NonNull Iterable<Pair<INDArray, INDArray>> iterable, int batchSize) {
|
||||
super(iterable, batchSize);
|
||||
}
|
||||
}
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
|
||||
import lombok.Getter;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class IteratorDataSetIterator implements DataSetIterator {
|
||||
|
||||
private final Iterator<DataSet> iterator;
|
||||
private final int batchSize;
|
||||
private final LinkedList<DataSet> queued; //Used when splitting larger examples than we want to return in a batch
|
||||
@Getter
|
||||
private DataSetPreProcessor preProcessor;
|
||||
|
||||
private int inputColumns = -1;
|
||||
private int totalOutcomes = -1;
|
||||
|
||||
private int cursor = 0;
|
||||
|
||||
public IteratorDataSetIterator(Iterator<DataSet> iterator, int batchSize) {
|
||||
this.iterator = iterator;
|
||||
this.batchSize = batchSize;
|
||||
this.queued = new LinkedList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return !queued.isEmpty() || iterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next() {
|
||||
return next(batchSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next(int num) {
|
||||
if (!hasNext())
|
||||
throw new NoSuchElementException();
|
||||
|
||||
List<DataSet> 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;
|
||||
}
|
||||
|
||||
if (inputColumns == -1) {
|
||||
//Set columns etc for later use
|
||||
DataSet temp = list.get(0);
|
||||
|
||||
inputColumns = (int) temp.getFeatures().size(1);
|
||||
totalOutcomes = temp.getLabels() == null ? 0 : (int) temp.getLabels().size(1); //May be null for layerwise pretraining
|
||||
}
|
||||
|
||||
DataSet out;
|
||||
if (list.size() == 1) {
|
||||
out = list.get(0);
|
||||
} else {
|
||||
out = DataSet.merge(list);
|
||||
}
|
||||
|
||||
if (preProcessor != null) {
|
||||
if (!out.isPreProcessed()) {
|
||||
preProcessor.preProcess(out);
|
||||
out.markAsPreProcessed();
|
||||
}
|
||||
}
|
||||
cursor += out.numExamples();
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int inputColumns() {
|
||||
if (inputColumns != -1)
|
||||
return inputColumns;
|
||||
prefetchBatchSetInputOutputValues();
|
||||
return inputColumns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int totalOutcomes() {
|
||||
if (totalOutcomes != -1)
|
||||
return totalOutcomes;
|
||||
prefetchBatchSetInputOutputValues();
|
||||
return totalOutcomes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
throw new UnsupportedOperationException("Reset not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batch() {
|
||||
return batchSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(DataSetPreProcessor preProcessor) {
|
||||
this.preProcessor = preProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLabels() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
private void prefetchBatchSetInputOutputValues() {
|
||||
if (!iterator.hasNext())
|
||||
return;
|
||||
DataSet next = iterator.next();
|
||||
inputColumns = (int) next.getFeatures().size(1);
|
||||
totalOutcomes = (int) next.getLabels().size(1);
|
||||
queued.add(next);
|
||||
}
|
||||
}
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
|
||||
import org.nd4j.linalg.api.ndarray.INDArray;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSet;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.MultiDataSetIterator;
|
||||
import org.nd4j.linalg.indexing.NDArrayIndex;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class IteratorMultiDataSetIterator implements MultiDataSetIterator {
|
||||
|
||||
private final Iterator<MultiDataSet> iterator;
|
||||
private final int batchSize;
|
||||
private final LinkedList<MultiDataSet> queued; //Used when splitting larger examples than we want to return in a batch
|
||||
private MultiDataSetPreProcessor preProcessor;
|
||||
|
||||
public IteratorMultiDataSetIterator(Iterator<MultiDataSet> iterator, int batchSize) {
|
||||
this.iterator = iterator;
|
||||
this.batchSize = batchSize;
|
||||
this.queued = new LinkedList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return !queued.isEmpty() || iterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSet next() {
|
||||
return next(batchSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSet next(int num) {
|
||||
if (!hasNext())
|
||||
throw new NoSuchElementException();
|
||||
|
||||
List<MultiDataSet> list = new ArrayList<>();
|
||||
int countSoFar = 0;
|
||||
while ((!queued.isEmpty() || iterator.hasNext()) && countSoFar < batchSize) {
|
||||
MultiDataSet next;
|
||||
if (!queued.isEmpty()) {
|
||||
next = queued.removeFirst();
|
||||
} else {
|
||||
next = iterator.next();
|
||||
}
|
||||
|
||||
long nExamples = next.getFeatures(0).size(0);
|
||||
if (countSoFar + nExamples <= batchSize) {
|
||||
//Add the entire MultiDataSet as-is
|
||||
list.add(next);
|
||||
} else {
|
||||
//Split the MultiDataSet
|
||||
|
||||
int nFeatures = next.numFeatureArrays();
|
||||
int nLabels = next.numLabelsArrays();
|
||||
|
||||
INDArray[] fToKeep = new INDArray[nFeatures];
|
||||
INDArray[] lToKeep = new INDArray[nLabels];
|
||||
INDArray[] fToCache = new INDArray[nFeatures];
|
||||
INDArray[] lToCache = new INDArray[nLabels];
|
||||
INDArray[] fMaskToKeep = (next.getFeaturesMaskArrays() != null ? new INDArray[nFeatures] : null);
|
||||
INDArray[] lMaskToKeep = (next.getLabelsMaskArrays() != null ? new INDArray[nLabels] : null);
|
||||
INDArray[] fMaskToCache = (next.getFeaturesMaskArrays() != null ? new INDArray[nFeatures] : null);
|
||||
INDArray[] lMaskToCache = (next.getLabelsMaskArrays() != null ? new INDArray[nLabels] : null);
|
||||
|
||||
for (int i = 0; i < nFeatures; i++) {
|
||||
INDArray fi = next.getFeatures(i);
|
||||
fToKeep[i] = getRange(fi, 0, batchSize - countSoFar);
|
||||
fToCache[i] = getRange(fi, batchSize - countSoFar, nExamples);
|
||||
|
||||
if (fMaskToKeep != null) {
|
||||
INDArray fmi = next.getFeaturesMaskArray(i);
|
||||
fMaskToKeep[i] = getRange(fmi, 0, batchSize - countSoFar);
|
||||
fMaskToCache[i] = getRange(fmi, batchSize - countSoFar, nExamples);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < nLabels; i++) {
|
||||
INDArray li = next.getLabels(i);
|
||||
lToKeep[i] = getRange(li, 0, batchSize - countSoFar);
|
||||
lToCache[i] = getRange(li, batchSize - countSoFar, nExamples);
|
||||
|
||||
if (lMaskToKeep != null) {
|
||||
INDArray lmi = next.getLabelsMaskArray(i);
|
||||
lMaskToKeep[i] = getRange(lmi, 0, batchSize - countSoFar);
|
||||
lMaskToCache[i] = getRange(lmi, batchSize - countSoFar, nExamples);
|
||||
}
|
||||
}
|
||||
|
||||
MultiDataSet toKeep =
|
||||
new org.nd4j.linalg.dataset.MultiDataSet(fToKeep, lToKeep, fMaskToKeep, lMaskToKeep);
|
||||
MultiDataSet toCache = new org.nd4j.linalg.dataset.MultiDataSet(fToCache, lToCache, fMaskToCache,
|
||||
lMaskToCache);
|
||||
list.add(toKeep);
|
||||
queued.add(toCache);
|
||||
}
|
||||
|
||||
countSoFar += nExamples;
|
||||
}
|
||||
|
||||
MultiDataSet out;
|
||||
if (list.size() == 1) {
|
||||
out = list.get(0);
|
||||
} else {
|
||||
out = org.nd4j.linalg.dataset.MultiDataSet.merge(list);
|
||||
}
|
||||
|
||||
if (preProcessor != null)
|
||||
preProcessor.preProcess(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
private static INDArray getRange(INDArray arr, long exampleFrom, long exampleToExclusive) {
|
||||
if (arr == null)
|
||||
return null;
|
||||
|
||||
int rank = arr.rank();
|
||||
switch (rank) {
|
||||
case 2:
|
||||
return arr.get(NDArrayIndex.interval(exampleFrom, exampleToExclusive), NDArrayIndex.all());
|
||||
case 3:
|
||||
return arr.get(NDArrayIndex.interval(exampleFrom, exampleToExclusive), NDArrayIndex.all(),
|
||||
NDArrayIndex.all());
|
||||
case 4:
|
||||
return arr.get(NDArrayIndex.interval(exampleFrom, exampleToExclusive), NDArrayIndex.all(),
|
||||
NDArrayIndex.all(), NDArrayIndex.all());
|
||||
default:
|
||||
throw new RuntimeException("Invalid rank: " + rank);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
//No need to asynchronously prefetch here: already in memory
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
throw new UnsupportedOperationException("Reset not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(MultiDataSetPreProcessor preProcessor) {
|
||||
this.preProcessor = preProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSetPreProcessor getPreProcessor() {
|
||||
return preProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
}
|
||||
+233
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import lombok.val;
|
||||
import org.nd4j.linalg.api.ndarray.INDArray;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSet;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
import org.nd4j.linalg.dataset.api.iterator.MultiDataSetIterator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
@Slf4j
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class JointMultiDataSetIterator implements MultiDataSetIterator {
|
||||
protected MultiDataSetPreProcessor preProcessor;
|
||||
protected Collection<DataSetIterator> iterators;
|
||||
protected int outcome = -1;
|
||||
|
||||
/**
|
||||
* @param iterators Underlying iterators to wrap
|
||||
*/
|
||||
public JointMultiDataSetIterator(DataSetIterator... iterators) {
|
||||
this.iterators = new ArrayList<DataSetIterator>();
|
||||
this.iterators.addAll(Arrays.asList(iterators));
|
||||
this.outcome = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param outcome Index to get the label from. If < 0, labels from all iterators will be used to create the
|
||||
* final MultiDataSet
|
||||
* @param iterators Underlying iterators to wrap
|
||||
*/
|
||||
public JointMultiDataSetIterator(int outcome, DataSetIterator... iterators){
|
||||
this(iterators);
|
||||
this.outcome = outcome;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the next 'num' examples. Similar to the next method, but returns a specified number of examples
|
||||
*
|
||||
* @param num Number of examples to fetch
|
||||
*/
|
||||
@Override
|
||||
public MultiDataSet next(int num) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the preprocessor to be applied to each MultiDataSet, before each MultiDataSet is returned.
|
||||
*
|
||||
* @param preProcessor MultiDataSetPreProcessor. May be null.
|
||||
*/
|
||||
@Override
|
||||
public void setPreProcessor(MultiDataSetPreProcessor preProcessor) {
|
||||
this.preProcessor = preProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link MultiDataSetPreProcessor}, if one has previously been set.
|
||||
* Returns null if no preprocessor has been set
|
||||
*
|
||||
* @return Preprocessor
|
||||
*/
|
||||
@Override
|
||||
public MultiDataSetPreProcessor getPreProcessor() {
|
||||
return preProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is resetting supported by this DataSetIterator? Many DataSetIterators do support resetting,
|
||||
* but some don't
|
||||
*
|
||||
* @return true if reset method is supported; false otherwise
|
||||
*/
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
boolean sup = true;
|
||||
|
||||
for (val i: iterators)
|
||||
if (!i.resetSupported()) {
|
||||
sup = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return sup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this MultiDataSetIterator support asynchronous prefetching of multiple MultiDataSet objects?
|
||||
* Most MultiDataSetIterators do, but in some cases it may not make sense to wrap this iterator in an
|
||||
* iterator that does asynchronous prefetching. For example, it would not make sense to use asynchronous
|
||||
* prefetching for the following types of iterators:
|
||||
* (a) Iterators that store their full contents in memory already
|
||||
* (b) Iterators that re-use features/labels arrays (as future next() calls will overwrite past contents)
|
||||
* (c) Iterators that already implement some level of asynchronous prefetching
|
||||
* (d) Iterators that may return different data depending on when the next() method is called
|
||||
*
|
||||
* @return true if asynchronous prefetching from this iterator is OK; false if asynchronous prefetching should not
|
||||
* be used with this iterator
|
||||
*/
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
boolean sup = true;
|
||||
|
||||
for (val i: iterators)
|
||||
if (!i.asyncSupported()) {
|
||||
sup = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return sup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the iterator back to the beginning
|
||||
*/
|
||||
@Override
|
||||
public void reset() {
|
||||
for (val i: iterators)
|
||||
i.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the iteration has more elements.
|
||||
* (In other words, returns {@code true} if {@link #next} would
|
||||
* return an element rather than throwing an exception.)
|
||||
*
|
||||
* @return {@code true} if the iteration has more elements
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
boolean has = true;
|
||||
|
||||
for (val i: iterators)
|
||||
if (!i.hasNext()) {
|
||||
has = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return has;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next element in the iteration.
|
||||
*
|
||||
* @return the next element in the iteration
|
||||
*/
|
||||
@Override
|
||||
public MultiDataSet next() {
|
||||
val features = new ArrayList<INDArray>();
|
||||
val labels = new ArrayList<INDArray>();
|
||||
val featuresMask = new ArrayList<INDArray>();
|
||||
val labelsMask = new ArrayList<INDArray>();
|
||||
|
||||
boolean hasFM = false;
|
||||
boolean hasLM = false;
|
||||
|
||||
int cnt = 0;
|
||||
for (val i: iterators) {
|
||||
val ds = i.next();
|
||||
|
||||
features.add(ds.getFeatures());
|
||||
featuresMask.add(ds.getFeaturesMaskArray());
|
||||
|
||||
if (outcome < 0 || cnt == outcome) {
|
||||
labels.add(ds.getLabels());
|
||||
labelsMask.add(ds.getLabelsMaskArray());
|
||||
}
|
||||
|
||||
if (ds.getFeaturesMaskArray() != null)
|
||||
hasFM = true;
|
||||
|
||||
if (ds.getLabelsMaskArray() != null)
|
||||
hasLM = true;
|
||||
|
||||
cnt++;
|
||||
}
|
||||
|
||||
INDArray[] fm = hasFM ? featuresMask.toArray(new INDArray[0]) : null;
|
||||
INDArray[] lm = hasLM ? labelsMask.toArray(new INDArray[0]) : null;
|
||||
|
||||
val mds = new org.nd4j.linalg.dataset.MultiDataSet(features.toArray(new INDArray[0]), labels.toArray(new INDArray[0]), fm, lm);
|
||||
|
||||
if (preProcessor != null)
|
||||
preProcessor.preProcess(mds);
|
||||
|
||||
return mds;
|
||||
}
|
||||
|
||||
/**
|
||||
* PLEASE NOTE: This method is NOT implemented
|
||||
*
|
||||
* @throws UnsupportedOperationException if the {@code remove}
|
||||
* operation is not supported by this iterator
|
||||
* @throws IllegalStateException if the {@code next} method has not
|
||||
* yet been called, or the {@code remove} method has already
|
||||
* been called after the last call to the {@code next}
|
||||
* method
|
||||
* @implSpec The default implementation throws an instance of
|
||||
* {@link UnsupportedOperationException} and performs no other action.
|
||||
*/
|
||||
@Override
|
||||
public void remove() {
|
||||
// noopp
|
||||
}
|
||||
}
|
||||
+292
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import lombok.val;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSet;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.MultiDataSetIterator;
|
||||
import org.nd4j.linalg.exception.ND4JIllegalStateException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
@Slf4j
|
||||
public class MultiDataSetIteratorSplitter {
|
||||
protected MultiDataSetIterator backedIterator;
|
||||
protected final long totalExamples;
|
||||
protected final double ratio;
|
||||
protected final long numTrain;
|
||||
protected final long numTest;
|
||||
protected final double[] ratios;
|
||||
protected final long numArbitrarySets;
|
||||
protected final int[] splits;
|
||||
|
||||
protected AtomicLong counter = new AtomicLong(0);
|
||||
|
||||
protected AtomicBoolean resetPending = new AtomicBoolean(false);
|
||||
protected org.nd4j.linalg.dataset.MultiDataSet firstTrain = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param baseIterator
|
||||
* @param totalBatches - total number of batches in underlying iterator. this value will be used to determine number of test/train batches
|
||||
* @param ratio - this value will be used as splitter. should be between in range of 0.0 > X < 1.0. I.e. if value 0.7 is provided, then 70% of total examples will be used for training, and 30% of total examples will be used for testing
|
||||
*/
|
||||
public MultiDataSetIteratorSplitter(@NonNull MultiDataSetIterator baseIterator, long totalBatches, double ratio) {
|
||||
if (!(ratio > 0.0 && ratio < 1.0))
|
||||
throw new ND4JIllegalStateException("Ratio value should be in range of 0.0 > X < 1.0");
|
||||
|
||||
if (totalBatches < 0)
|
||||
throw new ND4JIllegalStateException("totalExamples number should be positive value");
|
||||
|
||||
if (!baseIterator.resetSupported())
|
||||
throw new ND4JIllegalStateException("Underlying iterator doesn't support reset, so it can't be used for runtime-split");
|
||||
|
||||
|
||||
this.backedIterator = baseIterator;
|
||||
this.totalExamples = totalBatches;
|
||||
this.ratio = ratio;
|
||||
this.numTrain = (long) (totalExamples * ratio);
|
||||
this.numTest = totalExamples - numTrain;
|
||||
this.ratios = null;
|
||||
this.numArbitrarySets = 0;
|
||||
this.splits = null;
|
||||
|
||||
log.warn("IteratorSplitter is used: please ensure you don't use randomization/shuffle in underlying iterator!");
|
||||
}
|
||||
|
||||
public MultiDataSetIteratorSplitter(@NonNull MultiDataSetIterator baseIterator, long totalBatches, double[] ratios) {
|
||||
for (double ratio : ratios) {
|
||||
if (!(ratio > 0.0 && ratio < 1.0))
|
||||
throw new ND4JIllegalStateException("Ratio value should be in range of 0.0 > X < 1.0");
|
||||
}
|
||||
|
||||
if (totalBatches < 0)
|
||||
throw new ND4JIllegalStateException("totalExamples number should be positive value");
|
||||
|
||||
if (!baseIterator.resetSupported())
|
||||
throw new ND4JIllegalStateException("Underlying iterator doesn't support reset, so it can't be used for runtime-split");
|
||||
|
||||
|
||||
this.backedIterator = baseIterator;
|
||||
this.totalExamples = totalBatches;
|
||||
this.ratio = 0.0;
|
||||
this.numTrain = (long) (totalExamples * ratio);
|
||||
this.numTest = totalExamples - numTrain;
|
||||
this.ratios = null;
|
||||
this.numArbitrarySets = ratios.length;
|
||||
|
||||
this.splits = new int[this.ratios.length];
|
||||
for (int i = 0; i < this.splits.length; ++i) {
|
||||
this.splits[i] = (int)(totalExamples * ratios[i]);
|
||||
}
|
||||
|
||||
log.warn("IteratorSplitter is used: please ensure you don't use randomization/shuffle in underlying iterator!");
|
||||
}
|
||||
|
||||
public MultiDataSetIteratorSplitter(@NonNull MultiDataSetIterator baseIterator, int[] splits) {
|
||||
|
||||
int totalBatches = 0;
|
||||
for (val v:splits)
|
||||
totalBatches += v;
|
||||
|
||||
if (totalBatches < 0)
|
||||
throw new ND4JIllegalStateException("totalExamples number should be positive value");
|
||||
|
||||
if (!baseIterator.resetSupported())
|
||||
throw new ND4JIllegalStateException("Underlying iterator doesn't support reset, so it can't be used for runtime-split");
|
||||
|
||||
|
||||
this.backedIterator = baseIterator;
|
||||
this.totalExamples = totalBatches;
|
||||
this.ratio = 0.0;
|
||||
this.numTrain = (long) (totalExamples * ratio);
|
||||
this.numTest = totalExamples - numTrain;
|
||||
this.ratios = null;
|
||||
this.numArbitrarySets = splits.length;
|
||||
this.splits = splits;
|
||||
|
||||
log.warn("IteratorSplitter is used: please ensure you don't use randomization/shuffle in underlying iterator!");
|
||||
}
|
||||
|
||||
public List<MultiDataSetIterator> getIterators() {
|
||||
List<MultiDataSetIterator> retVal = new ArrayList<>();
|
||||
int partN = 0;
|
||||
int bottom = 0;
|
||||
for (final int split : splits) {
|
||||
ScrollableMultiDataSetIterator partIterator =
|
||||
new ScrollableMultiDataSetIterator(partN++, backedIterator, counter, firstTrain,
|
||||
new int[]{bottom,split});
|
||||
bottom += split;
|
||||
retVal.add(partIterator);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns train iterator instance
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public MultiDataSetIterator getTrainIterator() {
|
||||
return new MultiDataSetIterator() {
|
||||
@Override
|
||||
public MultiDataSet next(int num) {
|
||||
throw new UnsupportedOperationException("To be implemented yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(MultiDataSetPreProcessor preProcessor) {
|
||||
backedIterator.setPreProcessor(preProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSetPreProcessor getPreProcessor() {
|
||||
return backedIterator.getPreProcessor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return backedIterator.resetSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return backedIterator.asyncSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
resetPending.set(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (resetPending.get()) {
|
||||
if (resetSupported()) {
|
||||
backedIterator.reset();
|
||||
counter.set(0);
|
||||
resetPending.set(false);
|
||||
} else
|
||||
throw new UnsupportedOperationException("Reset isn't supported by underlying iterator");
|
||||
}
|
||||
|
||||
val state = backedIterator.hasNext();
|
||||
if (state && counter.get() < numTrain)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSet next() {
|
||||
counter.incrementAndGet();
|
||||
val p = backedIterator.next();
|
||||
|
||||
if (counter.get() == 1 && firstTrain == null) {
|
||||
// first epoch ever, we'll save first dataset and will use it to check for equality later
|
||||
firstTrain = (org.nd4j.linalg.dataset.MultiDataSet) p.copy();
|
||||
firstTrain.detach();
|
||||
} else if (counter.get() == 1) {
|
||||
// epoch > 1, comparing first dataset to previously stored dataset. they should be equal
|
||||
int cnt = 0;
|
||||
for (val c: p.getFeatures())
|
||||
if (!c.equalsWithEps(firstTrain.getFeatures()[cnt++], 1e-5))
|
||||
throw new ND4JIllegalStateException("First examples do not match. Randomization was used?");
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns test iterator instance
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public MultiDataSetIterator getTestIterator() {
|
||||
return new MultiDataSetIterator() {
|
||||
@Override
|
||||
public MultiDataSet next(int num) {
|
||||
throw new UnsupportedOperationException("To be implemented yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(MultiDataSetPreProcessor preProcessor) {
|
||||
backedIterator.setPreProcessor(preProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSetPreProcessor getPreProcessor() {
|
||||
return backedIterator.getPreProcessor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return backedIterator.resetSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return backedIterator.asyncSupported();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
resetPending.set(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
val state = backedIterator.hasNext();
|
||||
if (state && counter.get() < numTrain + numTest)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSet next() {
|
||||
counter.incrementAndGet();
|
||||
return backedIterator.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import org.nd4j.linalg.api.ndarray.INDArray;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSet;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
import org.nd4j.linalg.dataset.api.iterator.MultiDataSetIterator;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MultiDataSetWrapperIterator implements DataSetIterator {
|
||||
protected MultiDataSetIterator iterator;
|
||||
protected DataSetPreProcessor preProcessor;
|
||||
|
||||
/**
|
||||
* @param iterator Undelying iterator to wrap
|
||||
*/
|
||||
public MultiDataSetWrapperIterator(MultiDataSetIterator iterator) {
|
||||
this.iterator = iterator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next(int num) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int inputColumns() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int totalOutcomes() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return iterator.resetSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return iterator.asyncSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
iterator.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batch() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(DataSetPreProcessor preProcessor) {
|
||||
this.preProcessor = preProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSetPreProcessor getPreProcessor() {
|
||||
return preProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLabels() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return iterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next() {
|
||||
MultiDataSet mds = iterator.next();
|
||||
if (mds.getFeatures().length > 1 || mds.getLabels().length > 1)
|
||||
throw new UnsupportedOperationException(
|
||||
"This iterator is able to convert MultiDataSet with number of inputs/outputs of 1");
|
||||
|
||||
INDArray features = mds.getFeatures()[0];
|
||||
INDArray labels = mds.getLabels() != null ? mds.getLabels()[0] : features;
|
||||
INDArray fMask = mds.getFeaturesMaskArrays() != null ? mds.getFeaturesMaskArrays()[0] : null;
|
||||
INDArray lMask = mds.getLabelsMaskArrays() != null ? mds.getLabelsMaskArrays()[0] : null;
|
||||
|
||||
DataSet ds = new DataSet(features, labels, fMask, lMask);
|
||||
|
||||
if (preProcessor != null)
|
||||
preProcessor.preProcess(ds);
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
+262
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.Setter;
|
||||
import org.nd4j.shade.guava.annotations.VisibleForTesting;
|
||||
import org.nd4j.shade.guava.collect.Lists;
|
||||
import lombok.Getter;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
|
||||
@Deprecated
|
||||
public class MultipleEpochsIterator implements DataSetIterator {
|
||||
@VisibleForTesting
|
||||
@Getter
|
||||
@Setter
|
||||
protected int epochs = 0;
|
||||
protected int numEpochs;
|
||||
protected int batch = 0;
|
||||
protected int lastBatch = batch;
|
||||
protected DataSetIterator iter;
|
||||
protected DataSet ds;
|
||||
protected List<DataSet> batchedDS = Lists.newArrayList();
|
||||
protected static final Logger log = LoggerFactory.getLogger(MultipleEpochsIterator.class);
|
||||
@Getter
|
||||
protected DataSetPreProcessor preProcessor;
|
||||
protected boolean newEpoch = false;
|
||||
protected AtomicLong iterationsCounter = new AtomicLong(0);
|
||||
protected long totalIterations = Long.MAX_VALUE;
|
||||
|
||||
@Deprecated
|
||||
public MultipleEpochsIterator(int numEpochs, DataSetIterator iter) {
|
||||
this.numEpochs = numEpochs;
|
||||
this.iter = iter;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public MultipleEpochsIterator(int numEpochs, DataSetIterator iter, int queueSize) {
|
||||
this.numEpochs = numEpochs;
|
||||
this.iter = iter;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public MultipleEpochsIterator(DataSetIterator iter, int queueSize, long totalIterations) {
|
||||
this.numEpochs = Integer.MAX_VALUE;
|
||||
this.iter = iter;
|
||||
this.totalIterations = totalIterations;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public MultipleEpochsIterator(DataSetIterator iter, long totalIterations) {
|
||||
this.numEpochs = Integer.MAX_VALUE;
|
||||
this.iter = iter;
|
||||
this.totalIterations = totalIterations;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public MultipleEpochsIterator(int numEpochs, DataSet ds) {
|
||||
this.numEpochs = numEpochs;
|
||||
this.ds = ds;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Like the standard next method but allows a
|
||||
* customizable number of examples returned
|
||||
*
|
||||
* @param num the number of examples
|
||||
* @return the next data applyTransformToDestination
|
||||
*/
|
||||
@Override
|
||||
public DataSet next(int num) {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException("No next element");
|
||||
}
|
||||
DataSet next;
|
||||
batch++;
|
||||
iterationsCounter.incrementAndGet();
|
||||
if (iter == null) {
|
||||
// return full DataSet
|
||||
if (num == -1) {
|
||||
next = ds;
|
||||
if (epochs < numEpochs)
|
||||
trackEpochs();
|
||||
}
|
||||
// return DataSet broken into batches
|
||||
else {
|
||||
if (batchedDS.isEmpty() && num > 0)
|
||||
batchedDS = ds.batchBy(num);
|
||||
next = batchedDS.get(batch);
|
||||
if (batch + 1 == batchedDS.size()) {
|
||||
trackEpochs();
|
||||
if (epochs < numEpochs)
|
||||
batch = -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
next = (num == -1 ? iter.next() : iter.next(num));
|
||||
if (next == null) {
|
||||
throw new IllegalStateException("Iterator returned null DataSet");
|
||||
}
|
||||
if (!iter.hasNext()) {
|
||||
trackEpochs();
|
||||
// track number of epochs and won't reset if it's over
|
||||
if (epochs < numEpochs) {
|
||||
iter.reset();
|
||||
lastBatch = batch;
|
||||
batch = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (preProcessor != null)
|
||||
preProcessor.preProcess(next);
|
||||
return next;
|
||||
}
|
||||
|
||||
public void trackEpochs() {
|
||||
epochs++;
|
||||
newEpoch = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next() {
|
||||
return next(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Input columns for the dataset
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int inputColumns() {
|
||||
return iter.inputColumns();
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of labels for the dataset
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int totalOutcomes() {
|
||||
return iter.totalOutcomes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return iter.resetSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return iter.asyncSupported();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the iterator back to the beginning
|
||||
*/
|
||||
@Override
|
||||
public void reset() {
|
||||
if (!iter.resetSupported()) {
|
||||
throw new IllegalStateException(
|
||||
"Cannot reset MultipleEpochsIterator with base iter that does not support reset");
|
||||
}
|
||||
epochs = 0;
|
||||
lastBatch = batch;
|
||||
batch = 0;
|
||||
iterationsCounter.set(0);
|
||||
iter.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch size
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int batch() {
|
||||
return iter.batch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(DataSetPreProcessor preProcessor) {
|
||||
this.preProcessor = preProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLabels() {
|
||||
return iter.getLabels();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the iteration has more elements.
|
||||
* (In other words, returns {@code true} if {@link #next} would
|
||||
* return an element rather than throwing an exception.)
|
||||
*
|
||||
* @return {@code true} if the iteration has more elements
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (iterationsCounter.get() >= totalIterations)
|
||||
return false;
|
||||
|
||||
if (newEpoch) {
|
||||
log.info("Epoch " + epochs + ", number of batches completed " + lastBatch);
|
||||
newEpoch = false;
|
||||
}
|
||||
if (iter == null)
|
||||
return (epochs < numEpochs) && ((!batchedDS.isEmpty() && batchedDS.size() > batch) || batchedDS.isEmpty());
|
||||
else
|
||||
// either there are still epochs to complete or its the first epoch
|
||||
return (epochs < numEpochs) || (iter.hasNext() && (epochs == 0 || epochs == numEpochs));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes from the underlying collection the last element returned
|
||||
* by this iterator (optional operation). This method can be called
|
||||
* only once per call to {@link #next}. The behavior of an iterator
|
||||
* is unspecified if the underlying collection is modified while the
|
||||
* iteration is in progress in any way other than by calling this
|
||||
* method.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the {@code remove}
|
||||
* operation is not supported by this iterator
|
||||
* @throws IllegalStateException if the {@code next} method has not
|
||||
* yet been called, or the {@code remove} method has already
|
||||
* been called after the last call to the {@code next}
|
||||
* method
|
||||
*/
|
||||
@Override
|
||||
public void remove() {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import org.nd4j.linalg.factory.Nd4j;
|
||||
|
||||
public class RandomDataSetIterator extends MultiDataSetWrapperIterator {
|
||||
|
||||
public enum Values {RANDOM_UNIFORM, RANDOM_NORMAL, ONE_HOT, ZEROS, ONES, BINARY, INTEGER_0_10, INTEGER_0_100, INTEGER_0_1000,
|
||||
INTEGER_0_10000, INTEGER_0_100000;
|
||||
public RandomMultiDataSetIterator.Values toMdsValues(){
|
||||
return RandomMultiDataSetIterator.Values.valueOf(this.toString());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param numMiniBatches Number of minibatches per epoch
|
||||
* @param featuresShape Features shape
|
||||
* @param labelsShape Labels shape
|
||||
* @param featureValues Type of values for the features
|
||||
* @param labelValues Type of values for the labels
|
||||
*/
|
||||
public RandomDataSetIterator(int numMiniBatches, long[] featuresShape, long[] labelsShape, Values featureValues, Values labelValues){
|
||||
this(numMiniBatches, featuresShape, labelsShape, featureValues, labelValues, Nd4j.order(), Nd4j.order());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param numMiniBatches Number of minibatches per epoch
|
||||
* @param featuresShape Features shape
|
||||
* @param labelsShape Labels shape
|
||||
* @param featureValues Type of values for the features
|
||||
* @param labelValues Type of values for the labels
|
||||
* @param featuresOrder Array order ('c' or 'f') for the features array
|
||||
* @param labelsOrder Array order ('c' or 'f') for the labels array
|
||||
*/
|
||||
public RandomDataSetIterator(int numMiniBatches, long[] featuresShape, long[] labelsShape, Values featureValues, Values labelValues,
|
||||
char featuresOrder, char labelsOrder){
|
||||
super(new RandomMultiDataSetIterator.Builder(numMiniBatches)
|
||||
.addFeatures(featuresShape, featuresOrder, featureValues.toMdsValues())
|
||||
.addLabels(labelsShape, labelsOrder, labelValues.toMdsValues())
|
||||
.build());
|
||||
}
|
||||
|
||||
}
|
||||
+260
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
import org.nd4j.common.base.Preconditions;
|
||||
import org.nd4j.linalg.api.ndarray.INDArray;
|
||||
import org.nd4j.linalg.api.ops.random.impl.BernoulliDistribution;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSet;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.MultiDataSetIterator;
|
||||
import org.nd4j.linalg.factory.Nd4j;
|
||||
import org.nd4j.linalg.ops.transforms.Transforms;
|
||||
import org.nd4j.common.primitives.Triple;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class RandomMultiDataSetIterator implements MultiDataSetIterator {
|
||||
|
||||
public enum Values {RANDOM_UNIFORM, RANDOM_NORMAL, ONE_HOT, ZEROS, ONES, BINARY, INTEGER_0_10, INTEGER_0_100, INTEGER_0_1000,
|
||||
INTEGER_0_10000, INTEGER_0_100000}
|
||||
|
||||
private final int numMiniBatches;
|
||||
private final List<Triple<long[], Character, Values>> features;
|
||||
private final List<Triple<long[], Character, Values>> labels;
|
||||
@Getter @Setter
|
||||
private MultiDataSetPreProcessor preProcessor;
|
||||
|
||||
private int position;
|
||||
|
||||
/**
|
||||
* @param numMiniBatches Number of minibatches per epoch
|
||||
* @param features Each triple in the list specifies the shape, array order and type of values for the features arrays
|
||||
* @param labels Each triple in the list specifies the shape, array order and type of values for the labels arrays
|
||||
*/
|
||||
public RandomMultiDataSetIterator(int numMiniBatches, @NonNull List<Triple<long[], Character, Values>> features, @NonNull List<Triple<long[], Character, Values>> labels){
|
||||
Preconditions.checkArgument(numMiniBatches > 0, "Number of minibatches must be positive: got %s", numMiniBatches);
|
||||
Preconditions.checkArgument(features.size() > 0, "No features defined");
|
||||
Preconditions.checkArgument(labels.size() > 0, "No labels defined");
|
||||
|
||||
this.numMiniBatches = numMiniBatches;
|
||||
this.features = features;
|
||||
this.labels = labels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSet next(int i) {
|
||||
return next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
position = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return position < numMiniBatches;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSet next() {
|
||||
if(!hasNext())
|
||||
throw new NoSuchElementException("No next element");
|
||||
INDArray[] f = new INDArray[features.size()];
|
||||
INDArray[] l = new INDArray[labels.size()];
|
||||
|
||||
for( int i=0; i<f.length; i++ ){
|
||||
Triple<long[], Character, Values> t = features.get(i);
|
||||
f[i] = generate(t.getFirst(), t.getSecond(), t.getThird());
|
||||
}
|
||||
|
||||
for( int i=0; i<l.length; i++ ){
|
||||
Triple<long[], Character, Values> t = labels.get(i);
|
||||
l[i] = generate(t.getFirst(), t.getSecond(), t.getThird());
|
||||
}
|
||||
|
||||
position++;
|
||||
MultiDataSet mds = new org.nd4j.linalg.dataset.MultiDataSet(f,l);
|
||||
if(preProcessor != null)
|
||||
preProcessor.preProcess(mds);
|
||||
return mds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private int numMiniBatches;
|
||||
private List<Triple<long[], Character, Values>> features = new ArrayList<>();
|
||||
private List<Triple<long[], Character, Values>> labels = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* @param numMiniBatches Number of minibatches per epoch
|
||||
*/
|
||||
public Builder(int numMiniBatches){
|
||||
this.numMiniBatches = numMiniBatches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new features array to the iterator
|
||||
* @param shape Shape of the features
|
||||
* @param values Values to fill the array with
|
||||
*/
|
||||
public Builder addFeatures(long[] shape, Values values) {
|
||||
return addFeatures(shape, 'c', values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new features array to the iterator
|
||||
* @param shape Shape of the features
|
||||
* @param order Order ('c' or 'f') for the array
|
||||
* @param values Values to fill the array with
|
||||
*/
|
||||
public Builder addFeatures(long[] shape, char order, Values values){
|
||||
features.add(new Triple<>(shape, order, values));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new labels array to the iterator
|
||||
* @param shape Shape of the features
|
||||
* @param values Values to fill the array with
|
||||
*/
|
||||
public Builder addLabels(long[] shape, Values values) {
|
||||
return addLabels(shape, 'c', values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new labels array to the iterator
|
||||
* @param shape Shape of the features
|
||||
* @param order Order ('c' or 'f') for the array
|
||||
* @param values Values to fill the array with
|
||||
*/
|
||||
public Builder addLabels(long[] shape, char order, Values values){
|
||||
labels.add(new Triple<>(shape, order, values));
|
||||
return this;
|
||||
}
|
||||
|
||||
public RandomMultiDataSetIterator build(){
|
||||
return new RandomMultiDataSetIterator(numMiniBatches, features, labels);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random array with the specified shape
|
||||
* @param shape Shape of the array
|
||||
* @param values Values to fill the array with
|
||||
* @return Random array of specified shape + contents
|
||||
*/
|
||||
public static INDArray generate(long[] shape, Values values) {
|
||||
return generate(shape, Nd4j.order(), values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random array with the specified shape and order
|
||||
* @param shape Shape of the array
|
||||
* @param order Order of array ('c' or 'f')
|
||||
* @param values Values to fill the array with
|
||||
* @return Random array of specified shape + contents
|
||||
*/
|
||||
public static INDArray generate(long[] shape, char order, Values values){
|
||||
switch (values){
|
||||
case RANDOM_UNIFORM:
|
||||
return Nd4j.rand(Nd4j.createUninitialized(shape,order));
|
||||
case RANDOM_NORMAL:
|
||||
return Nd4j.randn(Nd4j.createUninitialized(shape,order));
|
||||
case ONE_HOT:
|
||||
Random r = new Random(Nd4j.getRandom().nextLong());
|
||||
INDArray out = Nd4j.create(shape,order);
|
||||
if(shape.length == 1){
|
||||
out.putScalar(r.nextInt((int) shape[0]), 1.0);
|
||||
} else if(shape.length == 2){
|
||||
for( int i=0; i<shape[0]; i++ ){
|
||||
out.putScalar(i, r.nextInt((int) shape[1]), 1.0);
|
||||
}
|
||||
} else if(shape.length == 3){
|
||||
for( int i=0; i<shape[0]; i++ ){
|
||||
for(int j=0; j<shape[2]; j++ ){
|
||||
out.putScalar(i, r.nextInt((int) shape[1]), j, 1.0);
|
||||
}
|
||||
}
|
||||
} else if(shape.length == 4){
|
||||
for( int i=0; i<shape[0]; i++ ){
|
||||
for(int j=0; j<shape[2]; j++ ){
|
||||
for(int k=0; k<shape[3]; k++ ) {
|
||||
out.putScalar(i, r.nextInt((int) shape[1]), j, k, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(shape.length == 5){
|
||||
for( int i=0; i<shape[0]; i++ ){
|
||||
for(int j=0; j<shape[2]; j++ ){
|
||||
for(int k=0; k<shape[3]; k++ ) {
|
||||
for( int l=0; l<shape[4]; l++ ) {
|
||||
out.putScalar(new int[]{i, r.nextInt((int) shape[1]), j, k, l}, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Not supported: rank 6+ arrays. Shape: " + Arrays.toString(shape));
|
||||
}
|
||||
return out;
|
||||
case ZEROS:
|
||||
return Nd4j.create(shape,order);
|
||||
case ONES:
|
||||
return Nd4j.createUninitialized(shape,order).assign(1.0);
|
||||
case BINARY:
|
||||
return Nd4j.getExecutioner().exec(new BernoulliDistribution(Nd4j.createUninitialized(shape, order), 0.5));
|
||||
case INTEGER_0_10:
|
||||
return Transforms.floor(Nd4j.rand(shape).muli(10), false);
|
||||
case INTEGER_0_100:
|
||||
return Transforms.floor(Nd4j.rand(shape).muli(100), false);
|
||||
case INTEGER_0_1000:
|
||||
return Transforms.floor(Nd4j.rand(shape).muli(1000), false);
|
||||
case INTEGER_0_10000:
|
||||
return Transforms.floor(Nd4j.rand(shape).muli(10000), false);
|
||||
case INTEGER_0_100000:
|
||||
return Transforms.floor(Nd4j.rand(shape).muli(100000), false);
|
||||
default:
|
||||
throw new RuntimeException("Unknown enum value: " + values);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
|
||||
import lombok.Getter;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wraps a data set iterator setting the first (feature matrix) as the labels.
|
||||
*
|
||||
* @author Adam Gibson
|
||||
*/
|
||||
public class ReconstructionDataSetIterator implements DataSetIterator {
|
||||
|
||||
private DataSetIterator iter;
|
||||
@Getter
|
||||
private DataSetPreProcessor preProcessor;
|
||||
|
||||
public ReconstructionDataSetIterator(DataSetIterator iter) {
|
||||
this.iter = iter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like the standard next method but allows a
|
||||
* customizable number of examples returned
|
||||
*
|
||||
* @param num the number of examples
|
||||
* @return the next data applyTransformToDestination
|
||||
*/
|
||||
@Override
|
||||
public DataSet next(int num) {
|
||||
DataSet ret = iter.next(num);
|
||||
ret.setLabels(ret.getFeatures());
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Input columns for the dataset
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int inputColumns() {
|
||||
return iter.inputColumns();
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of labels for the dataset
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int totalOutcomes() {
|
||||
return iter.totalOutcomes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return iter.resetSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return iter.asyncSupported();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the iterator back to the beginning
|
||||
*/
|
||||
@Override
|
||||
public void reset() {
|
||||
iter.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch size
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int batch() {
|
||||
return iter.batch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(DataSetPreProcessor preProcessor) {
|
||||
this.preProcessor = preProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLabels() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the iteration has more elements.
|
||||
* (In other words, returns {@code true} if {@link #next} would
|
||||
* return an element rather than throwing an exception.)
|
||||
*
|
||||
* @return {@code true} if the iteration has more elements
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return iter.hasNext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next element in the iteration.
|
||||
*
|
||||
* @return the next element in the iteration
|
||||
*/
|
||||
@Override
|
||||
public DataSet next() {
|
||||
DataSet next = iter.next();
|
||||
next.setLabels(next.getFeatures());
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes from the underlying collection the last element returned
|
||||
* by this iterator (optional operation). This method can be called
|
||||
* only once per call to {@link #next}. The behavior of an iterator
|
||||
* is unspecified if the underlying collection is modified while the
|
||||
* iteration is in progress in any way other than by calling this
|
||||
* method.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the {@code remove}
|
||||
* operation is not supported by this iterator
|
||||
* @throws IllegalStateException if the {@code next} method has not
|
||||
* yet been called, or the {@code remove} method has already
|
||||
* been called after the last call to the {@code next}
|
||||
* method
|
||||
*/
|
||||
@Override
|
||||
public void remove() {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Deprecated
|
||||
public class SamplingDataSetIterator extends org.nd4j.linalg.dataset.api.iterator.SamplingDataSetIterator {
|
||||
public SamplingDataSetIterator(DataSet sampleFrom, int batchSize, int totalNumberSamples) {
|
||||
super(sampleFrom, batchSize, totalNumberSamples);
|
||||
}
|
||||
}
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.val;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.MultiDataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
import org.nd4j.linalg.dataset.api.iterator.MultiDataSetIterator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
public class ScrollableDataSetIterator implements DataSetIterator {
|
||||
private int thisPart = 0;
|
||||
private int top = 0;
|
||||
private int bottom = 0;
|
||||
protected DataSetIterator backedIterator;
|
||||
protected AtomicLong counter = new AtomicLong(0);
|
||||
|
||||
protected AtomicBoolean resetPending = new AtomicBoolean(false);
|
||||
protected DataSet firstTrain = null;
|
||||
protected MultiDataSet firstMultiTrain = null;
|
||||
private double ratio;
|
||||
private long totalExamples;
|
||||
private long itemsPerPart;
|
||||
private long current;
|
||||
|
||||
|
||||
public ScrollableDataSetIterator(int num, DataSetIterator backedIterator, AtomicLong counter,
|
||||
AtomicBoolean resetPending, DataSet firstTrain, double ratio,
|
||||
int totalExamples) {
|
||||
this.thisPart = num;
|
||||
this.backedIterator = backedIterator;
|
||||
this.counter = counter;
|
||||
this.resetPending = resetPending;
|
||||
this.firstTrain = firstTrain;
|
||||
this.ratio = ratio;
|
||||
this.totalExamples = totalExamples;
|
||||
this.itemsPerPart = (long)(totalExamples * ratio);
|
||||
this.current = 0;
|
||||
}
|
||||
|
||||
public ScrollableDataSetIterator(int num, DataSetIterator backedIterator, AtomicLong counter,
|
||||
AtomicBoolean resetPending, DataSet firstTrain,
|
||||
int[] itemsPerPart) {
|
||||
this.thisPart = num;
|
||||
this.bottom = itemsPerPart[0];
|
||||
this.top = bottom + itemsPerPart[1];
|
||||
this.itemsPerPart = top;
|
||||
|
||||
this.backedIterator = backedIterator;
|
||||
this.counter = counter;
|
||||
//this.resetPending = resetPending;
|
||||
this.firstTrain = firstTrain;
|
||||
//this.totalExamples = totalExamples;
|
||||
this.current = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next(int i) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLabels() {
|
||||
return backedIterator.getLabels();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int inputColumns() {
|
||||
return backedIterator.inputColumns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int totalOutcomes() {
|
||||
return backedIterator.totalOutcomes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return backedIterator.resetSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return backedIterator.asyncSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
resetPending.set(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batch() {
|
||||
return backedIterator.batch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(DataSetPreProcessor dataSetPreProcessor) {
|
||||
backedIterator.setPreProcessor(dataSetPreProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSetPreProcessor getPreProcessor() {
|
||||
|
||||
return backedIterator.getPreProcessor();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (resetPending.get()) {
|
||||
if (resetSupported()) {
|
||||
backedIterator.reset();
|
||||
counter.set(0);
|
||||
current = 0;
|
||||
resetPending.set(false);
|
||||
} else
|
||||
throw new UnsupportedOperationException("Reset isn't supported by underlying iterator");
|
||||
}
|
||||
|
||||
boolean state = false;
|
||||
if (current >= top)
|
||||
return false;
|
||||
state = backedIterator.hasNext();
|
||||
if (!state)
|
||||
return false;
|
||||
if (state && counter.get() < itemsPerPart)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next() {
|
||||
counter.incrementAndGet();
|
||||
if ((current == 0) && (bottom != 0)) {
|
||||
backedIterator.reset();
|
||||
long cnt = current;
|
||||
for (; cnt < bottom; ++cnt) {
|
||||
if (backedIterator.hasNext())
|
||||
backedIterator.next();
|
||||
}
|
||||
current = cnt+1;
|
||||
}
|
||||
else current++;
|
||||
val p = backedIterator.next();
|
||||
return p;
|
||||
}
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.val;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
import org.nd4j.linalg.dataset.api.iterator.MultiDataSetIterator;
|
||||
|
||||
import javax.naming.OperationNotSupportedException;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
public class ScrollableMultiDataSetIterator implements MultiDataSetIterator {
|
||||
private int thisPart = 0;
|
||||
private int top = 0;
|
||||
private int bottom = 0;
|
||||
protected MultiDataSetIterator backedIterator;
|
||||
protected AtomicLong counter = new AtomicLong(0);
|
||||
|
||||
protected AtomicBoolean resetPending = new AtomicBoolean(false);
|
||||
protected DataSet firstTrain = null;
|
||||
protected MultiDataSet firstMultiTrain = null;
|
||||
private double ratio;
|
||||
private long totalExamples;
|
||||
private long itemsPerPart;
|
||||
private long current;
|
||||
|
||||
public ScrollableMultiDataSetIterator(int num, MultiDataSetIterator backedIterator, AtomicLong counter,
|
||||
MultiDataSet firstTrain, int[] itemsPerPart) {
|
||||
this.thisPart = num;
|
||||
this.bottom = itemsPerPart[0];
|
||||
this.top = bottom + itemsPerPart[1];
|
||||
this.itemsPerPart = top;
|
||||
|
||||
this.counter = counter;
|
||||
//this.resetPending = resetPending;
|
||||
this.firstTrain = null;
|
||||
this.firstMultiTrain = firstTrain;
|
||||
//this.totalExamples = totalExamples;
|
||||
this.current = 0;
|
||||
this.backedIterator = backedIterator;
|
||||
this.resetPending = resetPending;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return backedIterator.resetSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return backedIterator.asyncSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
resetPending.set(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(MultiDataSetPreProcessor dataSetPreProcessor) {
|
||||
backedIterator.setPreProcessor(dataSetPreProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSetPreProcessor getPreProcessor() {
|
||||
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (resetPending.get()) {
|
||||
if (resetSupported()) {
|
||||
backedIterator.reset();
|
||||
counter.set(0);
|
||||
current = 0;
|
||||
resetPending.set(false);
|
||||
} else
|
||||
throw new UnsupportedOperationException("Reset isn't supported by underlying iterator");
|
||||
}
|
||||
|
||||
boolean state = false;
|
||||
if (current >= top)
|
||||
return false;
|
||||
state = backedIterator.hasNext();
|
||||
if (!state)
|
||||
return false;
|
||||
if (state && counter.get() < itemsPerPart)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSet next() {
|
||||
counter.incrementAndGet();
|
||||
if ((current == 0) && (bottom != 0)) {
|
||||
backedIterator.reset();
|
||||
long cnt = current;
|
||||
for (; cnt < bottom; ++cnt) {
|
||||
if (backedIterator.hasNext())
|
||||
backedIterator.next();
|
||||
}
|
||||
current = cnt+1;
|
||||
}
|
||||
else current++;
|
||||
val p = backedIterator.next();
|
||||
return p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
//
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSet next(int i) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator;
|
||||
|
||||
import lombok.NonNull;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
import org.nd4j.linalg.factory.Nd4j;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class WorkspacesShieldDataSetIterator implements DataSetIterator {
|
||||
protected DataSetIterator iterator;
|
||||
|
||||
/**
|
||||
* @param iterator The underlying iterator to detach values from
|
||||
*/
|
||||
public WorkspacesShieldDataSetIterator(@NonNull DataSetIterator iterator) {
|
||||
this.iterator = iterator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next(int num) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int inputColumns() {
|
||||
return iterator.inputColumns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int totalOutcomes() {
|
||||
return iterator.totalOutcomes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return iterator.resetSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return iterator.asyncSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
iterator.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batch() {
|
||||
return iterator.batch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(DataSetPreProcessor preProcessor) {
|
||||
iterator.setPreProcessor(preProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSetPreProcessor getPreProcessor() {
|
||||
return iterator.getPreProcessor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLabels() {
|
||||
return iterator.getLabels();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return iterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next() {
|
||||
DataSet ds = iterator.next();
|
||||
|
||||
if (ds.getFeatures().isAttached()) {
|
||||
if (Nd4j.getMemoryManager().getCurrentWorkspace() == null) {
|
||||
ds.detach();
|
||||
} else {
|
||||
ds.migrate();
|
||||
}
|
||||
}
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator.callbacks;
|
||||
|
||||
|
||||
import org.nd4j.linalg.dataset.api.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSet;
|
||||
|
||||
@Deprecated
|
||||
public interface DataSetCallback extends org.nd4j.linalg.dataset.callbacks.DataSetCallback {
|
||||
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator.callbacks;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@Slf4j
|
||||
public class DataSetDeserializer implements FileCallback {
|
||||
@Override
|
||||
public <T> T call(File file) {
|
||||
DataSet dataSet = new DataSet();
|
||||
dataSet.load(file);
|
||||
return (T) dataSet;
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator.callbacks;
|
||||
|
||||
import org.nd4j.linalg.api.concurrency.AffinityManager;
|
||||
import org.nd4j.linalg.dataset.api.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSet;
|
||||
import org.nd4j.linalg.factory.Nd4j;
|
||||
|
||||
@Deprecated
|
||||
public class DefaultCallback extends org.nd4j.linalg.dataset.callbacks.DefaultCallback {
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator.callbacks;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public interface FileCallback {
|
||||
|
||||
<T> T call(File file);
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator.callbacks;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nd4j.linalg.api.memory.MemoryWorkspace;
|
||||
import org.nd4j.linalg.api.memory.conf.WorkspaceConfiguration;
|
||||
import org.nd4j.linalg.api.memory.enums.AllocationPolicy;
|
||||
import org.nd4j.linalg.api.memory.enums.LearningPolicy;
|
||||
import org.nd4j.linalg.api.memory.enums.ResetPolicy;
|
||||
import org.nd4j.linalg.api.memory.enums.SpillPolicy;
|
||||
import org.nd4j.linalg.dataset.api.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSet;
|
||||
import org.nd4j.linalg.factory.Nd4j;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
@Slf4j
|
||||
public class InterleavedDataSetCallback implements DataSetCallback {
|
||||
private List<MemoryWorkspace> workspaces = new ArrayList<>();
|
||||
private int bufferSize;
|
||||
private int numWorkspaces;
|
||||
|
||||
private boolean isInitialized = false;
|
||||
|
||||
private AtomicLong counterInput = new AtomicLong(0);
|
||||
|
||||
public InterleavedDataSetCallback(int bufferSize) {
|
||||
this.bufferSize = bufferSize;
|
||||
}
|
||||
|
||||
protected void initializeWorkspaces(long size) {
|
||||
WorkspaceConfiguration configuration = WorkspaceConfiguration.builder().initialSize(size)
|
||||
.overallocationLimit(bufferSize).policyReset(ResetPolicy.ENDOFBUFFER_REACHED)
|
||||
.policyAllocation(AllocationPolicy.OVERALLOCATE).policySpill(SpillPolicy.EXTERNAL)
|
||||
.policyLearning(LearningPolicy.NONE).build();
|
||||
|
||||
int numDevices = Nd4j.getAffinityManager().getNumberOfDevices();
|
||||
int cDevice = Nd4j.getAffinityManager().getDeviceForCurrentThread();
|
||||
for (int i = 0; i < numDevices; i++) {
|
||||
Nd4j.getAffinityManager().unsafeSetDevice(i);
|
||||
workspaces.add(Nd4j.getWorkspaceManager().createNewWorkspace(configuration, "IDSC-" + i, i));
|
||||
}
|
||||
|
||||
Nd4j.getAffinityManager().unsafeSetDevice(cDevice);
|
||||
numWorkspaces = numDevices;
|
||||
isInitialized = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(DataSet dataSet) {
|
||||
if (!isInitialized)
|
||||
initializeWorkspaces(dataSet.getMemoryFootprint());
|
||||
|
||||
Nd4j.getExecutioner().commit();
|
||||
|
||||
int currIdx = (int) (counterInput.getAndIncrement() % numWorkspaces);
|
||||
MemoryWorkspace currWs = Nd4j.getMemoryManager().getCurrentWorkspace();
|
||||
Nd4j.getMemoryManager().setCurrentWorkspace(workspaces.get(currIdx));
|
||||
|
||||
dataSet.migrate();
|
||||
|
||||
Nd4j.getMemoryManager().setCurrentWorkspace(currWs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(MultiDataSet multiDataSet) {
|
||||
if (!isInitialized)
|
||||
initializeWorkspaces(multiDataSet.getMemoryFootprint());
|
||||
|
||||
Nd4j.getExecutioner().commit();
|
||||
|
||||
int currIdx = (int) (counterInput.getAndIncrement() % numWorkspaces);
|
||||
MemoryWorkspace currWs = Nd4j.getMemoryManager().getCurrentWorkspace();
|
||||
Nd4j.getMemoryManager().setCurrentWorkspace(workspaces.get(currIdx));
|
||||
|
||||
multiDataSet.migrate();
|
||||
|
||||
Nd4j.getMemoryManager().setCurrentWorkspace(currWs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
counterInput.set(0);
|
||||
}
|
||||
}
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator.file;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.nd4j.linalg.api.memory.MemoryWorkspace;
|
||||
import org.nd4j.common.collection.CompactHeapStringList;
|
||||
import org.nd4j.linalg.factory.Nd4j;
|
||||
import org.nd4j.common.util.MathUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
public abstract class BaseFileIterator<T, P> implements Iterator<T> {
|
||||
|
||||
protected final List<String> list;
|
||||
protected final int batchSize;
|
||||
protected final Random rng;
|
||||
|
||||
protected int[] order;
|
||||
protected int position;
|
||||
|
||||
private T partialStored;
|
||||
@Getter
|
||||
@Setter
|
||||
protected P preProcessor;
|
||||
|
||||
|
||||
protected BaseFileIterator(@NonNull File rootDir, int batchSize, String... validExtensions) {
|
||||
this(new File[]{rootDir}, true, new Random(), batchSize, validExtensions);
|
||||
}
|
||||
|
||||
protected BaseFileIterator(@NonNull File[] rootDirs, boolean recursive, Random rng, int batchSize, String... validExtensions) {
|
||||
this.batchSize = batchSize;
|
||||
this.rng = rng;
|
||||
|
||||
list = new CompactHeapStringList();
|
||||
for(File rootDir : rootDirs) {
|
||||
Collection<File> c = FileUtils.listFiles(rootDir, validExtensions, recursive);
|
||||
if (c.isEmpty()) {
|
||||
throw new IllegalStateException("Root directory is empty (no files found) " + (validExtensions != null ? " (or all files rejected by extension filter)" : ""));
|
||||
}
|
||||
for (File f : c) {
|
||||
list.add(f.getPath());
|
||||
}
|
||||
}
|
||||
|
||||
if (rng != null) {
|
||||
order = new int[list.size()];
|
||||
for (int i = 0; i < order.length; i++) {
|
||||
order[i] = i;
|
||||
}
|
||||
MathUtils.shuffleArray(order, rng);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return partialStored != null || position < list.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException("No next element");
|
||||
}
|
||||
|
||||
T next;
|
||||
if (partialStored != null) {
|
||||
next = partialStored;
|
||||
partialStored = null;
|
||||
} else {
|
||||
int nextIdx = (order != null ? order[position++] : position++);
|
||||
next = load(new File(list.get(nextIdx)));
|
||||
}
|
||||
if (batchSize <= 0) {
|
||||
//Don't recombine, return as-is
|
||||
return next;
|
||||
}
|
||||
|
||||
if (sizeOf(next) == batchSize) {
|
||||
return next;
|
||||
}
|
||||
|
||||
int exampleCount = 0;
|
||||
List<T> toMerge = new ArrayList<>();
|
||||
toMerge.add(next);
|
||||
exampleCount += sizeOf(next);
|
||||
|
||||
while (exampleCount < batchSize && hasNext()) {
|
||||
int nextIdx = (order != null ? order[position++] : position++);
|
||||
next = load(new File(list.get(nextIdx)));
|
||||
exampleCount += sizeOf(next);
|
||||
toMerge.add(next);
|
||||
}
|
||||
|
||||
T ret = mergeAndStoreRemainder(toMerge);
|
||||
applyPreprocessor(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
protected T mergeAndStoreRemainder(List<T> toMerge) {
|
||||
//Could be smaller or larger
|
||||
List<T> correctNum = new ArrayList<>();
|
||||
List<T> remainder = new ArrayList<>();
|
||||
int soFar = 0;
|
||||
for (T t : toMerge) {
|
||||
long size = sizeOf(t);
|
||||
|
||||
if (soFar + size <= batchSize) {
|
||||
correctNum.add(t);
|
||||
soFar += size;
|
||||
} else if (soFar < batchSize) {
|
||||
//Split and add some
|
||||
List<T> split = split(t);
|
||||
if (rng != null) {
|
||||
Collections.shuffle(split, rng);
|
||||
}
|
||||
for (T t2 : split) {
|
||||
if (soFar < batchSize) {
|
||||
correctNum.add(t2);
|
||||
soFar += sizeOf(t2);
|
||||
} else {
|
||||
remainder.add(t2);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//Don't need any of this
|
||||
remainder.add(t);
|
||||
}
|
||||
}
|
||||
|
||||
T ret = merge(correctNum);
|
||||
if (remainder.isEmpty()) {
|
||||
this.partialStored = null;
|
||||
} else {
|
||||
try (MemoryWorkspace ws = Nd4j.getMemoryManager().scopeOutOfWorkspaces()) {
|
||||
this.partialStored = merge(remainder);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public void reset() {
|
||||
position = 0;
|
||||
if (rng != null) {
|
||||
MathUtils.shuffleArray(order, rng);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean resetSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean asyncSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
protected abstract T load(File f);
|
||||
|
||||
protected abstract long sizeOf(T of);
|
||||
|
||||
protected abstract List<T> split(T toSplit);
|
||||
|
||||
protected abstract T merge(List<T> toMerge);
|
||||
|
||||
protected abstract void applyPreprocessor(T toPreProcess);
|
||||
}
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator.file;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class FileDataSetIterator extends BaseFileIterator<DataSet, DataSetPreProcessor> implements DataSetIterator {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private List<String> labels;
|
||||
|
||||
/**
|
||||
* Create a FileDataSetIterator with the following default settings:<br>
|
||||
* - Recursive: files in subdirectories are included<br>
|
||||
* - Randomization: order of examples is randomized with a random RNG seed<br>
|
||||
* - Batch size: default (as in the stored DataSets - no splitting/combining)<br>
|
||||
* - File extensions: no filtering - all files in directory are assumed to be a DataSet<br>
|
||||
*
|
||||
* @param rootDir Root directory containing the DataSet objects
|
||||
*/
|
||||
public FileDataSetIterator(File rootDir) {
|
||||
this(rootDir, true, new Random(), -1, (String[]) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a FileDataSetIterator with the following default settings:<br>
|
||||
* - Recursive: files in subdirectories are included<br>
|
||||
* - Randomization: order of examples is randomized with a random RNG seed<br>
|
||||
* - Batch size: default (as in the stored DataSets - no splitting/combining)<br>
|
||||
* - File extensions: no filtering - all files in directory are assumed to be a DataSet<br>
|
||||
*
|
||||
* @param rootDirs Root directories containing the DataSet objects. DataSets from all of these directories will
|
||||
* be included in the iterator output
|
||||
*/
|
||||
public FileDataSetIterator(File... rootDirs) {
|
||||
this(rootDirs, true, new Random(), -1, (String[]) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a FileDataSetIterator with the specified batch size, and the following default settings:<br>
|
||||
* - Recursive: files in subdirectories are included<br>
|
||||
* - Randomization: order of examples is randomized with a random RNG seed<br>
|
||||
* - File extensions: no filtering - all files in directory are assumed to be a DataSet<br>
|
||||
*
|
||||
* @param rootDir Root directory containing the saved DataSet objects
|
||||
* @param batchSize Batch size. If > 0, DataSets will be split/recombined as required. If <= 0, DataSets will
|
||||
* simply be loaded and returned unmodified
|
||||
*/
|
||||
public FileDataSetIterator(File rootDir, int batchSize) {
|
||||
this(rootDir, batchSize, (String[]) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a FileDataSetIterator with filtering based on file extensions, and the following default settings:<br>
|
||||
* - Recursive: files in subdirectories are included<br>
|
||||
* - Randomization: order of examples is randomized with a random RNG seed<br>
|
||||
* - Batch size: default (as in the stored DataSets - no splitting/combining)<br>
|
||||
*
|
||||
* @param rootDir Root directory containing the saved DataSet objects
|
||||
* @param validExtensions May be null. If non-null, only files with one of the specified extensions will be used
|
||||
*/
|
||||
public FileDataSetIterator(File rootDir, String... validExtensions) {
|
||||
super(rootDir, -1, validExtensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a FileDataSetIterator with the specified batch size, filtering based on file extensions, and the
|
||||
* following default settings:<br>
|
||||
* - Recursive: files in subdirectories are included<br>
|
||||
* - Randomization: order of examples is randomized with a random RNG seed<br>
|
||||
*
|
||||
* @param rootDir Root directory containing the saved DataSet objects
|
||||
* @param batchSize Batch size. If > 0, DataSets will be split/recombined as required. If <= 0, DataSets will
|
||||
* simply be loaded and returned unmodified
|
||||
* @param validExtensions May be null. If non-null, only files with one of the specified extensions will be used
|
||||
*/
|
||||
public FileDataSetIterator(File rootDir, int batchSize, String... validExtensions) {
|
||||
super(rootDir, batchSize, validExtensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a FileDataSetIterator with all settings specified
|
||||
*
|
||||
* @param rootDir Root directory containing the saved DataSet objects
|
||||
* @param recursive If true: include files in subdirectories
|
||||
* @param rng May be null. If non-null, use this to randomize order
|
||||
* @param batchSize Batch size. If > 0, DataSets will be split/recombined as required. If <= 0, DataSets will
|
||||
* simply be loaded and returned unmodified
|
||||
* @param validExtensions May be null. If non-null, only files with one of the specified extensions will be used
|
||||
*/
|
||||
public FileDataSetIterator(File rootDir, boolean recursive, Random rng, int batchSize, String... validExtensions) {
|
||||
this(new File[]{rootDir}, recursive, rng, batchSize, validExtensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a FileDataSetIterator with all settings specified
|
||||
*
|
||||
* @param rootDirs Root directories containing the DataSet objects. DataSets from all of these directories will
|
||||
* be included in the iterator output
|
||||
* @param recursive If true: include files in subdirectories
|
||||
* @param rng May be null. If non-null, use this to randomize order
|
||||
* @param batchSize Batch size. If > 0, DataSets will be split/recombined as required. If <= 0, DataSets will
|
||||
* simply be loaded and returned unmodified
|
||||
* @param validExtensions May be null. If non-null, only files with one of the specified extensions will be used
|
||||
*/
|
||||
public FileDataSetIterator(File[] rootDirs, boolean recursive, Random rng, int batchSize, String... validExtensions) {
|
||||
super(rootDirs, recursive, rng, batchSize, validExtensions);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataSet load(File f) {
|
||||
DataSet ds = new DataSet();
|
||||
ds.load(f);
|
||||
return ds;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long sizeOf(DataSet of) {
|
||||
return of.numExamples();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<DataSet> split(DataSet toSplit) {
|
||||
return toSplit.asList();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataSet merge(List<DataSet> toMerge) {
|
||||
return DataSet.merge(toMerge);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyPreprocessor(DataSet toPreProcess) {
|
||||
if (preProcessor != null) {
|
||||
preProcessor.preProcess(toPreProcess);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next(int num) {
|
||||
throw new UnsupportedOperationException("Not supported for this iterator");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int inputColumns() {
|
||||
throw new UnsupportedOperationException("Not supported for this iterator");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int totalOutcomes() {
|
||||
throw new UnsupportedOperationException("Not supported for this iterator");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batch() {
|
||||
return batchSize;
|
||||
}
|
||||
}
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator.file;
|
||||
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSet;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.MultiDataSetIterator;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class FileMultiDataSetIterator extends BaseFileIterator<MultiDataSet, MultiDataSetPreProcessor> implements MultiDataSetIterator {
|
||||
|
||||
|
||||
/**
|
||||
* Create a FileMultiDataSetIterator with the following default settings:<br>
|
||||
* - Recursive: files in subdirectories are included<br>
|
||||
* - Randomization: order of examples is randomized with a random RNG seed<br>
|
||||
* - Batch size: default (as in the stored DataSets - no splitting/combining)<br>
|
||||
* - File extensions: no filtering - all files in directory are assumed to be a DataSet<br>
|
||||
*
|
||||
* @param rootDir Root directory containing the DataSet objects
|
||||
*/
|
||||
public FileMultiDataSetIterator(File rootDir) {
|
||||
this(rootDir, true, new Random(), -1, (String[]) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a FileMultiDataSetIterator with the following default settings:<br>
|
||||
* - Recursive: files in subdirectories are included<br>
|
||||
* - Randomization: order of examples is randomized with a random RNG seed<br>
|
||||
* - Batch size: default (as in the stored DataSets - no splitting/combining)<br>
|
||||
* - File extensions: no filtering - all files in directory are assumed to be a DataSet<br>
|
||||
*
|
||||
* @param rootDirs Root directories containing the MultiDataSet objects. MultiDataSets from all of these
|
||||
* directories will be included in the iterator output
|
||||
*/
|
||||
public FileMultiDataSetIterator(File... rootDirs) {
|
||||
this(rootDirs, true, new Random(), -1, (String[]) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a FileMultiDataSetIterator with the specified batch size, and the following default settings:<br>
|
||||
* - Recursive: files in subdirectories are included<br>
|
||||
* - Randomization: order of examples is randomized with a random RNG seed<br>
|
||||
* - File extensions: no filtering - all files in directory are assumed to be a DataSet<br>
|
||||
*
|
||||
* @param rootDir Root directory containing the saved DataSet objects
|
||||
* @param batchSize Batch size. If > 0, DataSets will be split/recombined as required. If <= 0, DataSets will
|
||||
* simply be loaded and returned unmodified
|
||||
*/
|
||||
public FileMultiDataSetIterator(File rootDir, int batchSize) {
|
||||
this(rootDir, batchSize, (String[]) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a FileMultiDataSetIterator with filtering based on file extensions, and the following default settings:<br>
|
||||
* - Recursive: files in subdirectories are included<br>
|
||||
* - Randomization: order of examples is randomized with a random RNG seed<br>
|
||||
* - Batch size: default (as in the stored DataSets - no splitting/combining)<br>
|
||||
*
|
||||
* @param rootDir Root directory containing the saved DataSet objects
|
||||
* @param validExtensions May be null. If non-null, only files with one of the specified extensions will be used
|
||||
*/
|
||||
public FileMultiDataSetIterator(File rootDir, String... validExtensions) {
|
||||
super(rootDir, -1, validExtensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a FileMultiDataSetIterator with the specified batch size, filtering based on file extensions, and the
|
||||
* following default settings:<br>
|
||||
* - Recursive: files in subdirectories are included<br>
|
||||
* - Randomization: order of examples is randomized with a random RNG seed<br>
|
||||
*
|
||||
* @param rootDir Root directory containing the saved DataSet objects
|
||||
* @param batchSize Batch size. If > 0, DataSets will be split/recombined as required. If <= 0, DataSets will
|
||||
* simply be loaded and returned unmodified
|
||||
* @param validExtensions May be null. If non-null, only files with one of the specified extensions will be used
|
||||
*/
|
||||
public FileMultiDataSetIterator(File rootDir, int batchSize, String... validExtensions) {
|
||||
super(rootDir, batchSize, validExtensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a FileMultiDataSetIterator with all settings specified
|
||||
*
|
||||
* @param rootDir Root directory containing the saved DataSet objects
|
||||
* @param recursive If true: include files in subdirectories
|
||||
* @param rng May be null. If non-null, use this to randomize order
|
||||
* @param batchSize Batch size. If > 0, DataSets will be split/recombined as required. If <= 0, DataSets will
|
||||
* simply be loaded and returned unmodified
|
||||
* @param validExtensions May be null. If non-null, only files with one of the specified extensions will be used
|
||||
*/
|
||||
public FileMultiDataSetIterator(File rootDir, boolean recursive, Random rng, int batchSize, String... validExtensions) {
|
||||
this(new File[]{rootDir}, recursive, rng, batchSize, validExtensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a FileMultiDataSetIterator with all settings specified
|
||||
*
|
||||
* @param rootDirs Root directories containing the MultiDataSet objects. MultiDataSets from all of these
|
||||
* directories will be included in the iterator output
|
||||
* @param recursive If true: include files in subdirectories
|
||||
* @param rng May be null. If non-null, use this to randomize order
|
||||
* @param batchSize Batch size. If > 0, DataSets will be split/recombined as required. If <= 0, DataSets will
|
||||
* simply be loaded and returned unmodified
|
||||
* @param validExtensions May be null. If non-null, only files with one of the specified extensions will be used
|
||||
*/
|
||||
public FileMultiDataSetIterator(File[] rootDirs, boolean recursive, Random rng, int batchSize, String... validExtensions) {
|
||||
super(rootDirs, recursive, rng, batchSize, validExtensions);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MultiDataSet load(File f) {
|
||||
MultiDataSet mds = new org.nd4j.linalg.dataset.MultiDataSet();
|
||||
try {
|
||||
mds.load(f);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Error loading MultiDataSet from file: " + f, e);
|
||||
}
|
||||
return mds;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long sizeOf(MultiDataSet of) {
|
||||
return of.getFeatures(0).size(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<MultiDataSet> split(MultiDataSet toSplit) {
|
||||
return toSplit.asList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSet merge(List<MultiDataSet> toMerge) {
|
||||
return org.nd4j.linalg.dataset.MultiDataSet.merge(toMerge);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyPreprocessor(MultiDataSet toPreProcess) {
|
||||
if (preProcessor != null) {
|
||||
preProcessor.preProcess(toPreProcess);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSet next(int num) {
|
||||
throw new UnsupportedOperationException("Not supported for this iterator");
|
||||
}
|
||||
}
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator.loader;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.nd4j.common.loader.Loader;
|
||||
import org.nd4j.common.loader.Source;
|
||||
import org.nd4j.common.loader.SourceFactory;
|
||||
import org.nd4j.common.loader.LocalFileSourceFactory;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
import org.nd4j.common.util.MathUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
@Data
|
||||
public class DataSetLoaderIterator implements DataSetIterator {
|
||||
|
||||
protected final List<String> paths;
|
||||
protected final Iterator<String> iter;
|
||||
protected final SourceFactory sourceFactory;
|
||||
protected final Loader<DataSet> loader;
|
||||
protected final Random rng;
|
||||
protected final int[] order;
|
||||
protected int position;
|
||||
|
||||
@Getter @Setter
|
||||
protected DataSetPreProcessor preProcessor;
|
||||
|
||||
/**
|
||||
* NOTE: When using this constructor (with {@code Iterator<String>}) the DataSetIterator cannot be reset.
|
||||
* Use the other construtor that takes {@code Collection<String>}
|
||||
*
|
||||
* @param paths Paths to iterate over
|
||||
* @param loader Loader to use when loading DataSets
|
||||
* @param sourceFactory The factory to use to convert the paths into streams via {@link Source}
|
||||
*/
|
||||
public DataSetLoaderIterator(Iterator<String> paths, Loader<DataSet> loader, SourceFactory sourceFactory){
|
||||
this.paths = null;
|
||||
this.iter = paths;
|
||||
this.loader = loader;
|
||||
this.sourceFactory = sourceFactory;
|
||||
this.rng = null;
|
||||
this.order = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate of the specified collection of strings without randomization
|
||||
*
|
||||
* @param paths Paths to iterate over
|
||||
* @param loader Loader to use when loading DataSets
|
||||
* @param sourceFactory The factory to use to convert the paths into streams via {@link Source}
|
||||
*/
|
||||
public DataSetLoaderIterator(Collection<String> paths, Loader<DataSet> loader, SourceFactory sourceFactory) {
|
||||
this(paths, null, loader, sourceFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate of the specified collection of strings with optional randomization
|
||||
*
|
||||
* @param paths Paths to iterate over
|
||||
* @param rng Optional random instance to use for shuffling of order. If null, no shuffling will be used.
|
||||
* @param loader Loader to use when loading DataSets
|
||||
* @param sourceFactory The factory to use to convert the paths into streams via {@link Source}
|
||||
*/
|
||||
public DataSetLoaderIterator(Collection<String> paths, Random rng, Loader<DataSet> loader, SourceFactory sourceFactory){
|
||||
if(paths instanceof List){
|
||||
this.paths = (List<String>)paths;
|
||||
} else {
|
||||
this.paths = new ArrayList<>(paths);
|
||||
}
|
||||
this.rng = rng;
|
||||
this.loader = loader;
|
||||
this.sourceFactory = sourceFactory;
|
||||
this.iter = null;
|
||||
|
||||
if(rng != null){
|
||||
order = new int[paths.size()];
|
||||
for( int i=0; i<order.length; i++ ){
|
||||
order[i] = i;
|
||||
}
|
||||
MathUtils.shuffleArray(order, rng);
|
||||
} else {
|
||||
order = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next(int i) {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int inputColumns() {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int totalOutcomes() {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return paths != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
if(!resetSupported())
|
||||
throw new UnsupportedOperationException("Reset not supported when using Iterator<String> instead of Iterable<String>");
|
||||
position = 0;
|
||||
if (rng != null) {
|
||||
MathUtils.shuffleArray(order, rng);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batch() {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLabels() {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if(iter != null)
|
||||
return iter.hasNext();
|
||||
return position < paths.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next() {
|
||||
if(!hasNext())
|
||||
throw new NoSuchElementException("No next element");
|
||||
String path;
|
||||
if(iter != null){
|
||||
path = iter.next();
|
||||
} else {
|
||||
if(order != null){
|
||||
path = paths.get(order[position++]);
|
||||
} else {
|
||||
path = paths.get(position++);
|
||||
}
|
||||
}
|
||||
Source s = sourceFactory.getSource(path);
|
||||
DataSet ds;
|
||||
try {
|
||||
ds = loader.load(s);
|
||||
} catch (IOException e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if(preProcessor != null)
|
||||
preProcessor.preProcess(ds);
|
||||
return ds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
}
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator.loader;
|
||||
|
||||
import lombok.Data;
|
||||
import org.nd4j.common.loader.Loader;
|
||||
import org.nd4j.common.loader.Source;
|
||||
import org.nd4j.common.loader.SourceFactory;
|
||||
import org.nd4j.common.loader.LocalFileSourceFactory;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSet;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.MultiDataSetIterator;
|
||||
import org.nd4j.common.util.MathUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
@Data
|
||||
public class MultiDataSetLoaderIterator implements MultiDataSetIterator {
|
||||
|
||||
protected final List<String> paths;
|
||||
protected final Iterator<String> iter;
|
||||
protected final Loader<MultiDataSet> loader;
|
||||
protected final SourceFactory sourceFactory;
|
||||
protected final Random rng;
|
||||
protected final int[] order;
|
||||
protected MultiDataSetPreProcessor preProcessor;
|
||||
protected int position;
|
||||
|
||||
/**
|
||||
* NOTE: When using this constructor (with {@code Iterator<String>}) the MultiDataSetIterator cannot be reset.
|
||||
* Use the other construtor that takes {@code Collection<String>}
|
||||
*
|
||||
* @param paths Paths to iterate over
|
||||
* @param loader Loader to use when loading DataSets
|
||||
* @param sourceFactory The factory to use to convert the paths into streams via {@link Source}
|
||||
*/
|
||||
public MultiDataSetLoaderIterator(Iterator<String> paths, Loader<MultiDataSet> loader, SourceFactory sourceFactory){
|
||||
this.paths = null;
|
||||
this.iter = paths;
|
||||
this.loader = loader;
|
||||
this.sourceFactory = sourceFactory;
|
||||
this.rng = null;
|
||||
this.order = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate of the specified collection of strings without randomization
|
||||
*
|
||||
* @param paths Paths to iterate over
|
||||
* @param loader Loader to use when loading DataSets
|
||||
* @param sourceFactory The factory to use to convert the paths into streams via {@link Source}
|
||||
*/
|
||||
public MultiDataSetLoaderIterator(Collection<String> paths, Loader<MultiDataSet> loader, SourceFactory sourceFactory) {
|
||||
this(paths, null, loader, sourceFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate of the specified collection of strings with optional randomization
|
||||
*
|
||||
* @param paths Paths to iterate over
|
||||
* @param rng Optional random instance to use for shuffling of order. If null, no shuffling will be used.
|
||||
* @param loader Loader to use when loading DataSets
|
||||
* @param sourceFactory The factory to use to convert the paths into streams via {@link Source}
|
||||
*/
|
||||
public MultiDataSetLoaderIterator(Collection<String> paths, Random rng, Loader<MultiDataSet> loader, SourceFactory sourceFactory) {
|
||||
if(paths instanceof List){
|
||||
this.paths = (List<String>)paths;
|
||||
} else {
|
||||
this.paths = new ArrayList<>(paths);
|
||||
}
|
||||
this.rng = rng;
|
||||
this.loader = loader;
|
||||
this.sourceFactory = sourceFactory;
|
||||
this.iter = null;
|
||||
|
||||
if(rng != null){
|
||||
order = new int[paths.size()];
|
||||
for( int i=0; i<order.length; i++ ){
|
||||
order[i] = i;
|
||||
}
|
||||
MathUtils.shuffleArray(order, rng);
|
||||
} else {
|
||||
order = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSet next(int i) {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return paths != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
if(!resetSupported())
|
||||
throw new UnsupportedOperationException("Reset not supported when using Iterator<String> instead of Iterable<String>");
|
||||
position = 0;
|
||||
if (rng != null) {
|
||||
MathUtils.shuffleArray(order, rng);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if(iter != null)
|
||||
return iter.hasNext();
|
||||
return position < paths.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSet next() {
|
||||
if(!hasNext())
|
||||
throw new NoSuchElementException("No next element");
|
||||
String path;
|
||||
if(iter != null){
|
||||
path = iter.next();
|
||||
} else {
|
||||
if(order != null){
|
||||
path = paths.get(order[position++]);
|
||||
} else {
|
||||
path = paths.get(position++);
|
||||
}
|
||||
}
|
||||
Source s = sourceFactory.getSource(path);
|
||||
MultiDataSet mds;
|
||||
try {
|
||||
mds = loader.load(s);
|
||||
} catch (IOException e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if(preProcessor != null)
|
||||
preProcessor.preProcess(mds);
|
||||
return mds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
}
|
||||
+220
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator.parallel;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.ParallelDataSetIterator;
|
||||
import org.nd4j.linalg.dataset.api.iterator.enums.InequalityHandling;
|
||||
import org.nd4j.linalg.exception.ND4JIllegalStateException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
@Slf4j
|
||||
public abstract class BaseParallelDataSetIterator implements ParallelDataSetIterator {
|
||||
protected AtomicLong counter = new AtomicLong(0);
|
||||
|
||||
protected InequalityHandling inequalityHandling;
|
||||
protected int numProducers;
|
||||
|
||||
protected AtomicBoolean allDepleted = new AtomicBoolean(false);
|
||||
protected MultiBoolean states;
|
||||
protected MultiBoolean resetTracker;
|
||||
|
||||
protected ThreadLocal<Integer> producerAffinity = new ThreadLocal<>();
|
||||
|
||||
|
||||
protected BaseParallelDataSetIterator(int numProducers) {
|
||||
states = new MultiBoolean(numProducers, true);
|
||||
resetTracker = new MultiBoolean(numProducers, false, true);
|
||||
this.numProducers = numProducers;
|
||||
}
|
||||
|
||||
|
||||
public boolean hasNext() {
|
||||
// if all producers are depleted - there's nothing to do here then
|
||||
if (states.allFalse() || allDepleted.get())
|
||||
return false;
|
||||
|
||||
int curIdx = getCurrentProducerIndex();
|
||||
|
||||
boolean hasNext = hasNextFor(curIdx);
|
||||
|
||||
if (hasNext)
|
||||
return true;
|
||||
else
|
||||
states.set(hasNext, curIdx);
|
||||
|
||||
if (states.allFalse())
|
||||
return false;
|
||||
|
||||
switch (inequalityHandling) {
|
||||
// FIXME: RESET should be applicable ONLY to producers which return TRUE for resetSupported();
|
||||
case RESET: {
|
||||
resetTracker.set(true, curIdx);
|
||||
|
||||
// we don't want to have endless loop here, so we only do reset until all producers depleted at least once
|
||||
if (resetTracker.allTrue()) {
|
||||
allDepleted.set(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
reset(curIdx);
|
||||
|
||||
// triggering possible adsi underneath
|
||||
hasNextFor(curIdx);
|
||||
|
||||
return true;
|
||||
}
|
||||
case RELOCATE: {
|
||||
// TODO: transparent switch to next producer should happen here
|
||||
while (!hasNext) {
|
||||
stepForward();
|
||||
hasNext = hasNextFor(getCurrentProducerIndex());
|
||||
states.set(hasNext, getCurrentProducerIndex());
|
||||
|
||||
if (states.allFalse())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
case PASS_NULL: {
|
||||
// we just return true here, no matter what's up
|
||||
return true;
|
||||
}
|
||||
case STOP_EVERYONE: {
|
||||
if (!states.allTrue())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
throw new ND4JIllegalStateException(
|
||||
"Unknown InequalityHanding option was passed in: " + inequalityHandling);
|
||||
}
|
||||
}
|
||||
|
||||
public DataSet next() {
|
||||
DataSet ds = nextFor(getCurrentProducerIndex());
|
||||
stepForward();
|
||||
return ds;
|
||||
}
|
||||
|
||||
protected int getCurrentProducerIndex() {
|
||||
return (int) (counter.get() % numProducers);
|
||||
}
|
||||
|
||||
protected void stepForward() {
|
||||
counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
for (int i = 0; i < numProducers; i++) {
|
||||
reset(i);
|
||||
states.set(true, i);
|
||||
resetTracker.set(false, i);
|
||||
}
|
||||
|
||||
allDepleted.set(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attachThread(int producer) {
|
||||
producerAffinity.set(producer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNextFor() {
|
||||
if (producerAffinity.get() == null)
|
||||
throw new ND4JIllegalStateException("attachThread(int) should be called prior to this call");
|
||||
|
||||
return hasNextFor(producerAffinity.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet nextFor() {
|
||||
if (producerAffinity.get() == null)
|
||||
throw new ND4JIllegalStateException("attachThread(int) should be called prior to this call");
|
||||
|
||||
return nextFor(producerAffinity.get());
|
||||
}
|
||||
|
||||
public abstract boolean hasNextFor(int consumer);
|
||||
|
||||
public abstract DataSet nextFor(int consumer);
|
||||
|
||||
protected abstract void reset(int consumer);
|
||||
|
||||
@Override
|
||||
public int totalOutcomes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batch() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next(int num) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int inputColumns() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(DataSetPreProcessor preProcessor) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSetPreProcessor getPreProcessor() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLabels() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator.parallel;
|
||||
|
||||
import org.nd4j.shade.guava.collect.Lists;
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.filefilter.IOFileFilter;
|
||||
import org.apache.commons.io.filefilter.RegexFileFilter;
|
||||
import org.nd4j.linalg.dataset.AsyncDataSetIterator;;
|
||||
import org.deeplearning4j.datasets.iterator.FileSplitDataSetIterator;
|
||||
import org.deeplearning4j.datasets.iterator.callbacks.FileCallback;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
import org.nd4j.linalg.dataset.api.iterator.enums.InequalityHandling;
|
||||
import org.nd4j.linalg.exception.ND4JIllegalStateException;
|
||||
import org.nd4j.linalg.factory.Nd4j;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
public class FileSplitParallelDataSetIterator extends BaseParallelDataSetIterator {
|
||||
|
||||
public static final String DEFAULT_PATTERN = "dataset-%d.bin";
|
||||
private String pattern;
|
||||
private int buffer;
|
||||
|
||||
protected List<DataSetIterator> asyncIterators = new ArrayList<>();
|
||||
|
||||
public FileSplitParallelDataSetIterator(@NonNull File rootFolder, @NonNull String pattern,
|
||||
@NonNull FileCallback callback) {
|
||||
this(rootFolder, pattern, callback, Nd4j.getAffinityManager().getNumberOfDevices());
|
||||
}
|
||||
|
||||
public FileSplitParallelDataSetIterator(@NonNull File rootFolder, @NonNull String pattern,
|
||||
@NonNull FileCallback callback, int numThreads) {
|
||||
this(rootFolder, pattern, callback, numThreads, InequalityHandling.STOP_EVERYONE);
|
||||
}
|
||||
|
||||
public FileSplitParallelDataSetIterator(@NonNull File rootFolder, @NonNull String pattern,
|
||||
@NonNull FileCallback callback, int numThreads, @NonNull InequalityHandling inequalityHandling) {
|
||||
this(rootFolder, pattern, callback, numThreads, 2, inequalityHandling);
|
||||
}
|
||||
|
||||
public FileSplitParallelDataSetIterator(@NonNull File rootFolder, @NonNull String pattern,
|
||||
@NonNull FileCallback callback, int numThreads, int bufferPerThread,
|
||||
@NonNull InequalityHandling inequalityHandling) {
|
||||
super(numThreads);
|
||||
|
||||
if (!rootFolder.exists() || !rootFolder.isDirectory())
|
||||
throw new IllegalArgumentException("Root folder should point to existing folder");
|
||||
|
||||
this.pattern = pattern;
|
||||
this.inequalityHandling = inequalityHandling;
|
||||
this.buffer = bufferPerThread;
|
||||
|
||||
String modifiedPattern = pattern.replaceAll("\\%d", ".*.");
|
||||
|
||||
IOFileFilter fileFilter = new RegexFileFilter(modifiedPattern);
|
||||
|
||||
|
||||
List<File> files = new ArrayList<>(FileUtils.listFiles(rootFolder, fileFilter, null));
|
||||
log.debug("Files found: {}; Producers: {}", files.size(), numProducers);
|
||||
|
||||
if (files.isEmpty())
|
||||
throw new IllegalArgumentException("No suitable files were found");
|
||||
|
||||
int numDevices = Nd4j.getAffinityManager().getNumberOfDevices();
|
||||
int cnt = 0;
|
||||
for (List<File> part : Lists.partition(files, files.size() / numThreads)) {
|
||||
// discard remainder
|
||||
if (cnt >= numThreads)
|
||||
break;
|
||||
|
||||
int cDev = cnt % numDevices;
|
||||
asyncIterators.add(new AsyncDataSetIterator(new FileSplitDataSetIterator(part, callback), bufferPerThread,
|
||||
true, cDev));
|
||||
cnt++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNextFor(int consumer) {
|
||||
if (consumer >= numProducers || consumer < 0)
|
||||
throw new ND4JIllegalStateException("Non-existent consumer was requested");
|
||||
|
||||
return asyncIterators.get(consumer).hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet nextFor(int consumer) {
|
||||
if (consumer >= numProducers || consumer < 0)
|
||||
throw new ND4JIllegalStateException("Non-existent consumer was requested");
|
||||
|
||||
return asyncIterators.get(consumer).next();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void reset(int consumer) {
|
||||
if (consumer >= numProducers || consumer < 0)
|
||||
throw new ND4JIllegalStateException("Non-existent consumer was requested");
|
||||
|
||||
asyncIterators.get(consumer).reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator.parallel;
|
||||
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nd4j.linalg.dataset.AsyncDataSetIterator;;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
import org.nd4j.linalg.dataset.api.iterator.enums.InequalityHandling;
|
||||
import org.nd4j.linalg.exception.ND4JIllegalStateException;
|
||||
import org.nd4j.linalg.factory.Nd4j;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
public class JointParallelDataSetIterator extends BaseParallelDataSetIterator {
|
||||
protected List<DataSetIterator> asyncIterators = new ArrayList<>();
|
||||
protected boolean enforceSingleDevice;
|
||||
protected int bufferSizePerDevice;
|
||||
|
||||
|
||||
public JointParallelDataSetIterator(@NonNull List<DataSetIterator> iterators, boolean singleDeviceMode,
|
||||
int bufferSize, @NonNull InequalityHandling inequalityHandling) {
|
||||
super(iterators.size());
|
||||
this.enforceSingleDevice = singleDeviceMode;
|
||||
this.bufferSizePerDevice = bufferSize;
|
||||
this.numProducers = iterators.size();
|
||||
this.inequalityHandling = inequalityHandling;
|
||||
|
||||
if (numProducers == 0)
|
||||
throw new IllegalArgumentException("You can't start ParallelDataSetIterator without input data");
|
||||
|
||||
initializeIterators(iterators);
|
||||
}
|
||||
|
||||
protected void initializeIterators(List<DataSetIterator> originals) {
|
||||
int numDevices = Nd4j.getAffinityManager().getNumberOfDevices();
|
||||
|
||||
int currentDevice = Nd4j.getAffinityManager().getDeviceForCurrentThread();
|
||||
|
||||
if (originals.size() % numDevices != 0)
|
||||
log.error("WARNING: number of splits doesn't match number of devices!");
|
||||
|
||||
int cnt = 0;
|
||||
for (DataSetIterator iterator : originals) {
|
||||
int cDev = cnt % numDevices;
|
||||
asyncIterators.add(new AsyncDataSetIterator(iterator, bufferSizePerDevice, true, cDev));
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasNextFor(int consumer) {
|
||||
if (consumer >= numProducers || consumer < 0)
|
||||
throw new ND4JIllegalStateException("Non-existent consumer was requested");
|
||||
|
||||
return asyncIterators.get(consumer).hasNext();
|
||||
}
|
||||
|
||||
|
||||
public DataSet nextFor(int consumer) {
|
||||
if (consumer >= numProducers || consumer < 0)
|
||||
throw new ND4JIllegalStateException("Non-existent consumer was requested");
|
||||
|
||||
return asyncIterators.get(consumer).next();
|
||||
}
|
||||
|
||||
protected void reset(int consumer) {
|
||||
if (consumer >= numProducers || consumer < 0)
|
||||
throw new ND4JIllegalStateException("Non-existent consumer was requested");
|
||||
|
||||
asyncIterators.get(consumer).reset();
|
||||
}
|
||||
|
||||
|
||||
public static class Builder {
|
||||
private List<DataSetIterator> iterators = new ArrayList<>();
|
||||
private boolean enforceSingleDevice = true;
|
||||
private int bufferSize = 4;
|
||||
private InequalityHandling inequalityHandling;
|
||||
|
||||
public Builder(@NonNull InequalityHandling inequalityHandling) {
|
||||
this.inequalityHandling = inequalityHandling;
|
||||
}
|
||||
|
||||
public Builder(@NonNull List<DataSetIterator> iterators, @NonNull InequalityHandling inequalityHandling) {
|
||||
this.inequalityHandling = inequalityHandling;
|
||||
|
||||
for (DataSetIterator iterator : iterators)
|
||||
addSourceIterator(iterator);
|
||||
}
|
||||
|
||||
|
||||
public Builder addSourceIterator(@NonNull DataSetIterator iterator) {
|
||||
if (!iterator.asyncSupported())
|
||||
throw new IllegalArgumentException("Source iterators should support async mode");
|
||||
|
||||
//TODO: add strict equality check here, we don't want it equal
|
||||
if (!hasIterator(iterator))
|
||||
iterators.add(iterator);
|
||||
else
|
||||
throw new IllegalArgumentException("You can't put equal iterators into this joint iterator");
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
protected boolean hasIterator(DataSetIterator iterator) {
|
||||
for (DataSetIterator iter : iterators) {
|
||||
if (iter == iterator)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public Builder setBufferSizePerSplit(int bufferSize) {
|
||||
this.bufferSize = bufferSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Builder enforceSingleDevice(boolean reallyEnforce) {
|
||||
this.enforceSingleDevice = reallyEnforce;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public JointParallelDataSetIterator build() {
|
||||
JointParallelDataSetIterator jpdsi = new JointParallelDataSetIterator(iterators, enforceSingleDevice,
|
||||
bufferSize, inequalityHandling);
|
||||
|
||||
return jpdsi;
|
||||
}
|
||||
}
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator.parallel;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nd4j.linalg.exception.ND4JIllegalStateException;
|
||||
|
||||
@Slf4j
|
||||
public class MultiBoolean {
|
||||
private final int numEntries;
|
||||
private int holder = 0;
|
||||
private int max = 0;
|
||||
private boolean oneTime;
|
||||
private MultiBoolean timeTracker;
|
||||
|
||||
public MultiBoolean(int numEntries) {
|
||||
this(numEntries, false);
|
||||
}
|
||||
|
||||
public MultiBoolean(int numEntries, boolean initialValue) {
|
||||
this(numEntries, initialValue, false);
|
||||
}
|
||||
|
||||
public MultiBoolean(int numEntries, boolean initialValue, boolean oneTime) {
|
||||
if (numEntries > 32)
|
||||
throw new UnsupportedOperationException("Up to 32 entries can be tracked at once.");
|
||||
|
||||
this.oneTime = oneTime;
|
||||
this.numEntries = numEntries;
|
||||
for (int i = 1; i <= numEntries; i++) {
|
||||
this.max |= 1 << i;
|
||||
}
|
||||
|
||||
if (initialValue)
|
||||
this.holder = this.max;
|
||||
|
||||
if (oneTime)
|
||||
this.timeTracker = new MultiBoolean(numEntries, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets specified entry to specified state
|
||||
*
|
||||
* @param value
|
||||
* @param entry
|
||||
*/
|
||||
public void set(boolean value, int entry) {
|
||||
if (entry > numEntries || entry < 0)
|
||||
throw new ND4JIllegalStateException(
|
||||
"Entry index given (" + entry + ")in is higher then configured one (" + numEntries + ")");
|
||||
|
||||
if (oneTime && this.timeTracker.get(entry))
|
||||
return;
|
||||
|
||||
if (value)
|
||||
this.holder |= 1 << (entry + 1);
|
||||
else
|
||||
this.holder &= ~(1 << (entry + 1));
|
||||
|
||||
if (oneTime)
|
||||
this.timeTracker.set(true, entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets current state for specified entry
|
||||
*
|
||||
* @param entry
|
||||
* @return
|
||||
*/
|
||||
public boolean get(int entry) {
|
||||
if (entry > numEntries || entry < 0)
|
||||
throw new ND4JIllegalStateException(
|
||||
"Entry index given (" + entry + ")in is higher then configured one (" + numEntries + ")");
|
||||
|
||||
return (this.holder & 1 << (entry + 1)) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns true if ALL states are true. False otherwise.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean allTrue() {
|
||||
//log.info("Holder: {}; Max: {}", holder, max);
|
||||
return holder == max;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns true if ALL states are false. False otherwise
|
||||
* @return
|
||||
*/
|
||||
public boolean allFalse() {
|
||||
return holder == 0;
|
||||
}
|
||||
}
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator.utilty;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nd4j.linalg.api.ndarray.INDArray;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
import org.nd4j.linalg.factory.Nd4j;
|
||||
import org.nd4j.linalg.indexing.NDArrayIndex;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
@Slf4j
|
||||
public class BenchmarkDataSetIterator implements DataSetIterator {
|
||||
private INDArray baseFeatures;
|
||||
private INDArray baseLabels;
|
||||
private long limit;
|
||||
private AtomicLong counter = new AtomicLong(0);
|
||||
|
||||
/**
|
||||
* @param featuresShape Shape of the features data to randomly generate
|
||||
* @param numLabels Number of label classes (for classification)
|
||||
* @param totalIterations Total number of iterations per epoch
|
||||
*/
|
||||
public BenchmarkDataSetIterator(int[] featuresShape, int numLabels, int totalIterations) {
|
||||
this(featuresShape, numLabels, totalIterations, -1, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates 2d (shape [minibatch, numLabels]) or 4d labels ([minibatch, numLabels, gridWidth, gridHeight]),
|
||||
* depending on value of gridWidth and gridHeight.
|
||||
*
|
||||
* @param featuresShape Shape of the features data to randomly generate
|
||||
* @param numLabels Number of label classes (for classification)
|
||||
* @param totalIterations Total number of iterations
|
||||
* @param gridWidth If > 0, use to create 4d labels
|
||||
* @param gridHeight If > 0, use to create 4d labels
|
||||
*/
|
||||
public BenchmarkDataSetIterator(int[] featuresShape, int numLabels, int totalIterations, int gridWidth, int gridHeight) {
|
||||
this.baseFeatures = Nd4j.rand(featuresShape);
|
||||
this.baseLabels = gridWidth > 0 && gridHeight > 0
|
||||
? Nd4j.create(featuresShape[0], numLabels, gridWidth, gridHeight)
|
||||
: Nd4j.create(featuresShape[0], numLabels);
|
||||
if(this.baseLabels.rank() == 2){
|
||||
this.baseLabels.getColumn(1).assign(1.0);
|
||||
} else {
|
||||
this.baseLabels.get(NDArrayIndex.all(), NDArrayIndex.point(1), NDArrayIndex.all(), NDArrayIndex.all());
|
||||
}
|
||||
|
||||
Nd4j.getExecutioner().commit();
|
||||
this.limit = totalIterations;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param example DataSet to return on each call of next()
|
||||
* @param totalIterations Total number of iterations
|
||||
*/
|
||||
public BenchmarkDataSetIterator(DataSet example, int totalIterations) {
|
||||
this.baseFeatures = example.getFeatures().dup();
|
||||
this.baseLabels = example.getLabels().dup();
|
||||
|
||||
Nd4j.getExecutioner().commit();
|
||||
this.limit = totalIterations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next(int i) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int inputColumns() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int totalOutcomes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
this.counter.set(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batch() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(DataSetPreProcessor dataSetPreProcessor) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSetPreProcessor getPreProcessor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLabels() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the iteration has more elements.
|
||||
* (In other words, returns {@code true} if {@link #next} would
|
||||
* return an element rather than throwing an exception.)
|
||||
*
|
||||
* @return {@code true} if the iteration has more elements
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return counter.get() < limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next element in the iteration.
|
||||
*
|
||||
* @return the next element in the iteration
|
||||
*/
|
||||
@Override
|
||||
public DataSet next() {
|
||||
counter.incrementAndGet();
|
||||
|
||||
DataSet ds = new DataSet(baseFeatures, baseLabels);
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes from the underlying collection the last element returned
|
||||
* by this iterator (optional operation). This method can be called
|
||||
* only once per call to {@link #next}. The behavior of an iterator
|
||||
* is unspecified if the underlying collection is modified while the
|
||||
* iteration is in progress in any way other than by calling this
|
||||
* method.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the {@code remove}
|
||||
* operation is not supported by this iterator
|
||||
* @throws IllegalStateException if the {@code next} method has not
|
||||
* yet been called, or the {@code remove} method has already
|
||||
* been called after the last call to the {@code next}
|
||||
* method
|
||||
* @implSpec The default implementation throws an instance of
|
||||
* {@link UnsupportedOperationException} and performs no other action.
|
||||
*/
|
||||
@Override
|
||||
public void remove() {
|
||||
|
||||
}
|
||||
}
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator.utilty;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nd4j.linalg.api.ndarray.INDArray;
|
||||
import org.nd4j.linalg.dataset.MultiDataSet;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.MultiDataSetIterator;
|
||||
import org.nd4j.linalg.factory.Nd4j;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
@Slf4j
|
||||
public class BenchmarkMultiDataSetIterator implements MultiDataSetIterator {
|
||||
private INDArray[] baseFeatures;
|
||||
private INDArray[] baseLabels;
|
||||
private long limit;
|
||||
private AtomicLong counter = new AtomicLong(0);
|
||||
|
||||
public BenchmarkMultiDataSetIterator(int[][] featuresShape, int[] numLabels, int totalIterations) {
|
||||
if (featuresShape.length != numLabels.length)
|
||||
throw new IllegalArgumentException("Number of input features must match length of input labels.");
|
||||
|
||||
this.baseFeatures = new INDArray[featuresShape.length];
|
||||
for (int i = 0; i < featuresShape.length; i++) {
|
||||
baseFeatures[i] = Nd4j.rand(featuresShape[i]);
|
||||
}
|
||||
this.baseLabels = new INDArray[featuresShape.length];
|
||||
for (int i = 0; i < featuresShape.length; i++) {
|
||||
baseLabels[i] = Nd4j.create(featuresShape[i][0], numLabels[i]);
|
||||
baseLabels[i].getColumn(1).assign(1.0);
|
||||
}
|
||||
|
||||
Nd4j.getExecutioner().commit();
|
||||
this.limit = totalIterations;
|
||||
}
|
||||
|
||||
public BenchmarkMultiDataSetIterator(MultiDataSet example, int totalIterations) {
|
||||
this.baseFeatures = new INDArray[example.getFeatures().length];
|
||||
for (int i = 0; i < example.getFeatures().length; i++) {
|
||||
baseFeatures[i] = example.getFeatures()[i].dup();
|
||||
}
|
||||
this.baseLabels = new INDArray[example.getLabels().length];
|
||||
for (int i = 0; i < example.getLabels().length; i++) {
|
||||
baseFeatures[i] = example.getLabels()[i].dup();
|
||||
}
|
||||
|
||||
Nd4j.getExecutioner().commit();
|
||||
this.limit = totalIterations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSet next(int i) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
this.counter.set(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(MultiDataSetPreProcessor dataSetPreProcessor) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSetPreProcessor getPreProcessor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the iteration has more elements.
|
||||
* (In other words, returns {@code true} if {@link #next} would
|
||||
* return an element rather than throwing an exception.)
|
||||
*
|
||||
* @return {@code true} if the iteration has more elements
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return counter.get() < limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next element in the iteration.
|
||||
*
|
||||
* @return the next element in the iteration
|
||||
*/
|
||||
@Override
|
||||
public MultiDataSet next() {
|
||||
counter.incrementAndGet();
|
||||
|
||||
INDArray[] features = new INDArray[baseFeatures.length];
|
||||
System.arraycopy(baseFeatures, 0, features, 0, baseFeatures.length);
|
||||
INDArray[] labels = new INDArray[baseLabels.length];
|
||||
System.arraycopy(baseLabels, 0, labels, 0, baseLabels.length);
|
||||
|
||||
MultiDataSet ds = new MultiDataSet(features, labels);
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes from the underlying collection the last element returned
|
||||
* by this iterator (optional operation). This method can be called
|
||||
* only once per call to {@link #next}. The behavior of an iterator
|
||||
* is unspecified if the underlying collection is modified while the
|
||||
* iteration is in progress in any way other than by calling this
|
||||
* method.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the {@code remove}
|
||||
* operation is not supported by this iterator
|
||||
* @throws IllegalStateException if the {@code next} method has not
|
||||
* yet been called, or the {@code remove} method has already
|
||||
* been called after the last call to the {@code next}
|
||||
* method
|
||||
* @implSpec The default implementation throws an instance of
|
||||
* {@link UnsupportedOperationException} and performs no other action.
|
||||
*/
|
||||
@Override
|
||||
public void remove() {
|
||||
|
||||
}
|
||||
}
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator.utilty;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class ListDataSetIterator<T extends DataSet> implements DataSetIterator {
|
||||
|
||||
private static final long serialVersionUID = -7569201667767185411L;
|
||||
private int curr = 0;
|
||||
private int batch = 10;
|
||||
private List<T> list;
|
||||
@Getter
|
||||
private DataSetPreProcessor preProcessor;
|
||||
|
||||
/**
|
||||
* @param coll Collection of datasets with 1 example each
|
||||
* @param batch Batch size
|
||||
*/
|
||||
public ListDataSetIterator(Collection<T> coll, int batch) {
|
||||
list = new ArrayList<>(coll);
|
||||
this.batch = batch;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes with a batch of 5
|
||||
*
|
||||
* @param coll the collection to iterate over
|
||||
*/
|
||||
public ListDataSetIterator(Collection<T> coll) {
|
||||
this(coll, 5);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean hasNext() {
|
||||
return curr < list.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized DataSet next() {
|
||||
return next(batch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int inputColumns() {
|
||||
return list.get(0).getFeatures().columns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int totalOutcomes() {
|
||||
return list.get(0).getLabels().columns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
//Already in memory -> doesn't make sense to prefetch
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void reset() {
|
||||
curr = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batch() {
|
||||
return batch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(DataSetPreProcessor preProcessor) {
|
||||
this.preProcessor = preProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLabels() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DataSet next(int num) {
|
||||
int end = curr + num;
|
||||
|
||||
List<DataSet> r = new ArrayList<>();
|
||||
if (end >= list.size())
|
||||
end = list.size();
|
||||
for (; curr < end; curr++) {
|
||||
r.add(list.get(curr));
|
||||
}
|
||||
|
||||
DataSet d = DataSet.merge(r);
|
||||
if (preProcessor != null) {
|
||||
if (!d.isPreProcessed()) {
|
||||
preProcessor.preProcess(d);
|
||||
d.markAsPreProcessed();
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator.utilty;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.nd4j.linalg.dataset.DataSet;
|
||||
import org.nd4j.linalg.dataset.api.DataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public class SingletonDataSetIterator implements DataSetIterator {
|
||||
|
||||
private final DataSet dataSet;
|
||||
private boolean hasNext = true;
|
||||
private boolean preprocessed = false;
|
||||
@Getter @Setter
|
||||
private DataSetPreProcessor preProcessor;
|
||||
|
||||
/**
|
||||
* @param multiDataSet The underlying dataset to return
|
||||
*/
|
||||
public SingletonDataSetIterator(DataSet multiDataSet) {
|
||||
this.dataSet = multiDataSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next(int num) {
|
||||
return next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int inputColumns() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int totalOutcomes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
hasNext = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batch() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLabels() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return hasNext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSet next() {
|
||||
if (!hasNext) {
|
||||
throw new NoSuchElementException("No elements remaining");
|
||||
}
|
||||
hasNext = false;
|
||||
if (preProcessor != null && !preprocessed) {
|
||||
preProcessor.preProcess(dataSet);
|
||||
preprocessed = true;
|
||||
}
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
//No op
|
||||
}
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * This program and the accompanying materials are made available under the
|
||||
* * terms of the Apache License, Version 2.0 which is available at
|
||||
* * https://www.apache.org/licenses/LICENSE-2.0.
|
||||
* *
|
||||
* * See the NOTICE file distributed with this work for additional
|
||||
* * information regarding copyright ownership.
|
||||
* * Unless required by applicable law or agreed to in writing, software
|
||||
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* * License for the specific language governing permissions and limitations
|
||||
* * under the License.
|
||||
* *
|
||||
* * SPDX-License-Identifier: Apache-2.0
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.datasets.iterator.utilty;
|
||||
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSet;
|
||||
import org.nd4j.linalg.dataset.api.MultiDataSetPreProcessor;
|
||||
import org.nd4j.linalg.dataset.api.iterator.MultiDataSetIterator;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public class SingletonMultiDataSetIterator implements MultiDataSetIterator {
|
||||
|
||||
private final MultiDataSet multiDataSet;
|
||||
private boolean hasNext = true;
|
||||
private boolean preprocessed = false;
|
||||
private MultiDataSetPreProcessor preProcessor;
|
||||
|
||||
/**
|
||||
* @param multiDataSet The underlying MultiDataSet to return
|
||||
*/
|
||||
public SingletonMultiDataSetIterator(MultiDataSet multiDataSet) {
|
||||
this.multiDataSet = multiDataSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSet next(int num) {
|
||||
return next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreProcessor(MultiDataSetPreProcessor preProcessor) {
|
||||
this.preProcessor = preProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSetPreProcessor getPreProcessor() {
|
||||
return preProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
hasNext = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return hasNext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSet next() {
|
||||
if (!hasNext) {
|
||||
throw new NoSuchElementException("No elements remaining");
|
||||
}
|
||||
hasNext = false;
|
||||
if (preProcessor != null && !preprocessed) {
|
||||
preProcessor.preProcess(multiDataSet);
|
||||
preprocessed = true;
|
||||
}
|
||||
return multiDataSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
//No op
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
module deeplearning4j.utility.iterators {
|
||||
requires commons.io;
|
||||
requires guava;
|
||||
|
||||
requires transitive nd4j.api;
|
||||
requires transitive nd4j.common;
|
||||
requires transitive slf4j.api;
|
||||
|
||||
exports org.deeplearning4j.datasets.iterator;
|
||||
exports org.deeplearning4j.datasets.iterator.callbacks;
|
||||
exports org.deeplearning4j.datasets.iterator.file;
|
||||
exports org.deeplearning4j.datasets.iterator.loader;
|
||||
exports org.deeplearning4j.datasets.iterator.parallel;
|
||||
exports org.deeplearning4j.datasets.iterator.utilty;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user