nd4j-backends/nd4j-api-parent/nd4j-api/src/main/java/org/nd4j/linalg/dataset/api/DataSetUtil.java
public static Pair<INDArray, INDArray> merge4d(INDArray[] arrays, INDArray[] masks) {
        //4d -> images. In principle: could have 2d mask arrays (per-example masks)

        int nExamples = 0;
        long[] shape = arrays[0].shape();
        INDArray[] temp = new INDArray[arrays.length];
        boolean hasMasks = false;
        for (int i = 0; i < arrays.length; i++) {
            nExamples += arrays[i].size(0);
            long[] thisShape = arrays[i].shape();
            if (thisShape.length != 4) {
                throw new IllegalStateException("Cannot merge 4d arrays with non 4d arrays");
            }
            for (int j = 1; j < 4; j++) {
                if (thisShape[j] != shape[j])
                    throw new IllegalStateException(
                                    "Cannot merge 4d arrays with different shape (other than # examples): "
                                                    + " data[0].shape = " + Arrays.toString(shape) + ", data[" + i
                                                    + "].shape = " + Arrays.toString(thisShape));
            }

            temp[i] = arrays[i];
            if (masks != null && masks[i] != null && masks[i] != null) {
                hasMasks = true;
                if (masks[i].rank() != 2) {
                    throw new UnsupportedOperationException("Cannot merged 4d arrays with masks that are not rank 2."
                                    + " Got mask array with rank: " + masks[i].rank());
                }
            }
        }

        INDArray out = Nd4j.specialConcat(0, temp);
        INDArray outMask = null;
        if (hasMasks) {
            outMask = DataSetUtil.mergePerOutputMasks2d(out.shape(), arrays, masks);
        }

        return new Pair<>(out, outMask);
    }
public static Pair<INDArray, INDArray> merge4d(INDArray[] arrays, INDArray[] masks) {
        //4d -> images. In principle: could have 2d mask arrays (per-example masks)

        int nExamples = 0;
        long[] shape = arrays[0].shape();
        INDArray[] temp = new INDArray[arrays.length];
        boolean hasMasks = false;
        for (int i = 0; i < arrays.length; i++) {
            nExamples += arrays[i].size(0);
            long[] thisShape = arrays[i].shape();
            if (thisShape.length != 4) {
                throw new IllegalStateException("Cannot merge 4d arrays with non 4d arrays");
            }
            for (int j = 1; j < 4; j++) {
                if (thisShape[j] != shape[j])
                    throw new IllegalStateException(
                                    "Cannot merge 4d arrays with different shape (other than # examples): "
                                                    + " data[0].shape = " + Arrays.toString(shape) + ", data[" + i
                                                    + "].shape = " + Arrays.toString(thisShape));
            }

            temp[i] = arrays[i];
            if (masks != null && masks[i] != null && masks[i] != null) {
                hasMasks = true;
                if (masks[i].rank() != 2) {
                    throw new UnsupportedOperationException("Cannot merged 4d arrays with masks that are not rank 2."
                                    + " Got mask array with rank: " + masks[i].rank());
                }
            }
        }

        INDArray out = Nd4j.specialConcat(0, temp);
        INDArray outMask = null;
        if (hasMasks) {
            outMask = DataSetUtil.mergePerOutputMasks2d(out.shape(), arrays, masks);
        }

        return new Pair<>(out, outMask);
    }
Merge the specified 4d arrays and masks. See {@link #mergeFeatures(INDArray[], INDArray[])}
and {@link #mergeLabels(INDArray[], INDArray[])}

@param arrays   Arrays to merge
@param masks    Mask arrays to merge
@return Merged arrays and mask