/// <summary>
        /// Load a batch of data in the background (this is run on an internal thread within the BasePrefetchingDataLayer class).
        /// </summary>
        /// <param name="batch">Specifies the Batch of data to load.</param>
        protected override void load_batch(Batch <T> batch)
        {
            m_log.CHECK(batch.Data.count() > 0, "There is no space allocated for data!");
            int    nBatchSize    = (int)m_param.data_param.batch_size;
            int    nNewHeight    = (int)m_param.image_data_param.new_height;
            int    nNewWidth     = (int)m_param.image_data_param.new_width;
            bool   bIsColor      = m_param.image_data_param.is_color;
            string strRootFolder = getRootFolder();

            T[] rgTopLabel = null;
            int nCount     = batch.Label.count();

            m_log.CHECK_GT(nCount, 0, "The label count cannot be zero!");
            rgTopLabel = new T[nCount];

            if (m_param.data_param.display_timing)
            {
                m_swTimerBatch.Restart();
                m_dfReadTime  = 0;
                m_dfTransTime = 0;
            }

            Datum datum;
            int   nDim = 0;

            for (int i = 0; i < nBatchSize; i++)
            {
                if (m_param.data_param.display_timing)
                {
                    m_swTimerTransaction.Restart();
                }

                m_log.CHECK_GT(m_rgLines.Count, m_nLinesId, "The lines ID is too small!");
                int nIdx = m_nLinesId;
                if (m_param.data_param.enable_random_selection.GetValueOrDefault(false))
                {
                    nIdx = m_random.Next(m_rgLines.Count);
                }
                datum = loadImage(strRootFolder, m_rgLines[nIdx], bIsColor, nNewHeight, nNewWidth);

                if (m_param.data_param.display_timing)
                {
                    m_dfReadTime += m_swTimerTransaction.Elapsed.TotalMilliseconds;
                    m_swTimerTransaction.Restart();
                }

                if (i == 0)
                {
                    // Reshape according to the first datum of each batch
                    // on single input batches allows for inputs of varying dimension.
                    // Use data transformer to infer the expected blob shape for datum.
                    List <int> rgTopShape = m_transformer.InferBlobShape(datum);

                    // Reshape batch according to the batch size.
                    rgTopShape[0] = nBatchSize;
                    batch.Data.Reshape(rgTopShape);

                    nDim = 1;
                    for (int k = 1; k < rgTopShape.Count; k++)
                    {
                        nDim *= rgTopShape[k];
                    }

                    int nTopLen = nDim * nBatchSize;
                    if (m_rgTopData == null || m_rgTopData.Length != nTopLen)
                    {
                        m_rgTopData = new T[nTopLen];
                    }
                }

                // Apply data transformations (mirrow, scaling, crop, etc)
                int nDimCount = nDim;
                T[] rgTrans   = m_transformer.Transform(datum);
                Array.Copy(rgTrans, 0, m_rgTopData, nDim * i, nDimCount);

                rgTopLabel[i] = (T)Convert.ChangeType(datum.Label, typeof(T));

                if (m_param.data_param.display_timing)
                {
                    m_dfTransTime += m_swTimerTransaction.Elapsed.TotalMilliseconds;
                }

                if (m_evtCancel.WaitOne(0))
                {
                    return;
                }

                batch.Data.SetCPUData(m_rgTopData);
                batch.Label.SetCPUData(rgTopLabel);

                if (m_param.data_param.display_timing)
                {
                    m_swTimerBatch.Stop();
                    m_swTimerTransaction.Stop();
                    m_log.WriteLine("Prefetch batch: " + m_swTimerBatch.ElapsedMilliseconds.ToString() + " ms.", true);
                    m_log.WriteLine("     Read time: " + m_dfReadTime.ToString() + " ms.", true);
                    m_log.WriteLine("Transform time: " + m_dfTransTime.ToString() + " ms.", true);
                }

                // Go to the next iter.
                m_nLinesId++;

                // We have reached the end, restart from the first.
                if (m_nLinesId == m_rgLines.Count)
                {
                    m_nLinesId = 0;
                    if (m_param.image_data_param.shuffle)
                    {
                        shuffleImages();
                    }
                }
            }
        }
示例#2
0
        /// <summary>
        /// Load a batch of data in the background (this is run on an internal thread within the BasePrefetchingDataLayer class).
        /// </summary>
        /// <param name="batch">Specifies the Batch of data to load.</param>
        protected override void load_batch(Batch <T> batch)
        {
            m_log.CHECK(batch.Data.count() > 0, "There is no space allocated for data!");
            int  nBatchSize        = (int)m_param.data_param.batch_size;
            bool bLoadDataCriteria = false;

            if (m_bOutputLabels && m_param.data_param.one_hot_label_size == 0 && m_param.data_param.label_type == DataParameter.LABEL_TYPE.MULTIPLE)
            {
                bLoadDataCriteria = true;
            }

            if (m_bOutputLabels)
            {
                if (m_param.data_param.one_hot_label_size > 0 && m_param.data_param.label_type == DataParameter.LABEL_TYPE.MULTIPLE)
                {
                    int nCount = m_param.data_param.one_hot_label_size;

                    if (m_rgOneHotLabel == null || m_rgOneHotLabel.Length != nCount)
                    {
                        m_rgOneHotLabel = new T[nCount];
                    }

                    nCount = batch.Label.count();

                    if (m_rgTopLabel == null || m_rgTopLabel.Length != nCount)
                    {
                        m_rgTopLabel = new T[nCount];
                    }
                }
                else
                {
                    int nCount = batch.Label.count();
                    m_log.CHECK_GT(nCount, 0, "The label count cannot be zero!");

                    if (m_rgTopLabel == null || m_rgTopLabel.Length < nCount)
                    {
                        m_rgTopLabel = new T[nCount];
                    }
                }
            }

            if (m_param.data_param.display_timing)
            {
                m_swTimerBatch.Restart();
                m_dfReadTime  = 0;
                m_dfTransTime = 0;
            }

            SimpleDatum datum;
            int         nDim           = 0;
            List <int>  rgLabels       = null;
            List <int>  rgTargetLabels = null;

            if (OnBatchLoad != null)
            {
                rgLabels = new List <int>();
            }

            // If we are synced with another dataset, wait for it to load the initial data set.
            if (m_param.data_param.synchronize_target)
            {
                m_log.CHECK_EQ(m_param.data_param.images_per_blob, 1, "DataLayer synchronize targets are not supported when loading more than 1 image per blob.");

                int nWait = m_rgBatchLabels.WaitReady;
                if (nWait == 0)
                {
                    return;
                }

                rgTargetLabels = m_rgBatchLabels.Get();
                m_log.CHECK_EQ(nBatchSize, m_rgBatchLabels.Count, "The batch label count (previously loaded by the primary dataset) does not match the batch size '" + m_param.data_param.batch_size.ToString() + "' of this layer!");
            }

            for (int i = 0; i < nBatchSize; i++)
            {
                if (m_param.data_param.display_timing)
                {
                    m_swTimerTransaction.Restart();
                }

                while (Skip())
                {
                    if (m_evtCancel.WaitOne(0))
                    {
                        return;
                    }
                    Next();
                }

                if (rgTargetLabels == null)
                {
                    datum = m_cursor.GetValue(null, bLoadDataCriteria);

                    if (m_param.data_param.images_per_blob > 1)
                    {
                        if (m_rgDatum == null || m_rgDatum.Length != m_param.data_param.images_per_blob - 1)
                        {
                            m_rgDatum = new SimpleDatum[m_param.data_param.images_per_blob - 1];
                        }

                        for (int j = 0; j < m_param.data_param.images_per_blob - 1; j++)
                        {
                            Next();

                            while (Skip())
                            {
                                if (m_evtCancel.WaitOne(0))
                                {
                                    return;
                                }
                                Next();
                            }

                            if (m_param.data_param.balance_matches)
                            {
                                if (m_bMatchingCycle)
                                {
                                    m_rgDatum[j] = getNextPair(true, datum, bLoadDataCriteria);
                                }
                                else
                                {
                                    if (m_param.data_param.enable_noise_for_nonmatch)
                                    {
                                        m_rgDatum[j] = m_datumNoise;
                                    }
                                    else
                                    {
                                        m_rgDatum[j] = getNextPair(false, datum, bLoadDataCriteria);
                                    }
                                }
                            }
                            else
                            {
                                if (m_param.data_param.enable_noise_for_nonmatch)
                                {
                                    m_rgDatum[j] = m_datumNoise;
                                }
                                else
                                {
                                    m_rgDatum[j] = m_cursor.GetValue(null, bLoadDataCriteria);
                                }
                            }
                        }

                        m_bMatchingCycle = !m_bMatchingCycle;
                    }
                }
                else
                {
                    datum = m_cursor.GetValue(rgTargetLabels[i], bLoadDataCriteria);
                }

                // When debug output is enabled, output information each image loaded.
                if (m_param.data_param.enable_debug_output)
                {
                    saveImageInfo(m_param.data_param.data_debug_param, datum, i, 0);

                    if (m_rgDatum != null)
                    {
                        for (int n = 0; n < m_rgDatum.Length; n++)
                        {
                            saveImageInfo(m_param.data_param.data_debug_param, m_rgDatum[n], i, n + 1);
                        }
                    }
                }

                if (m_param.data_param.display_timing)
                {
                    m_dfReadTime += m_swTimerTransaction.Elapsed.TotalMilliseconds;
                    m_swTimerTransaction.Restart();
                }

                if (i == 0)
                {
                    // Reshape according to the first datum of each batch
                    // on single input batches allows for inputs of varying dimension.
                    // Use data transformer to infer the expected blob shape for datum.
                    m_rgTopShape = m_transformer.InferBlobShape(datum, m_rgTopShape);

                    // Double the channels when loading image pairs where the first image is loaded followed by the second on the channel.
                    if (m_rgDatum != null)
                    {
                        m_rgTopShape[1] *= (m_rgDatum.Length + 1);
                    }

                    // Reshape batch according to the batch size.
                    m_rgTopShape[0] = nBatchSize;
                    batch.Data.Reshape(m_rgTopShape);

                    nDim = 1;
                    for (int k = 1; k < m_rgTopShape.Length; k++)
                    {
                        nDim *= m_rgTopShape[k];
                    }

                    int nTopLen = nDim * nBatchSize;
                    if (m_rgTopData == null || m_rgTopData.Length != nTopLen)
                    {
                        m_rgTopData = new T[nTopLen];
                    }
                }

                // Apply data transformations (mirrow, scaling, crop, etc)
                int nDimCount = nDim;

                if (m_rgDatum != null)
                {
                    nDimCount /= (m_rgDatum.Length + 1);
                }

                T[] rgTrans = m_transformer.Transform(datum);
                Array.Copy(rgTrans, 0, m_rgTopData, nDim * i, nDimCount);

                // When using load_image_pairs, stack the additional images right after the first.
                if (m_rgDatum != null)
                {
                    for (int j = 0; j < m_rgDatum.Length; j++)
                    {
                        rgTrans = m_transformer.Transform(m_rgDatum[j]);
                        int nOffset = (nDim * i) + (nDimCount * (j + 1));
                        Array.Copy(rgTrans, 0, m_rgTopData, nOffset, nDimCount);
                    }
                }

                // Copy label.
                if (m_bOutputLabels)
                {
                    if (m_param.data_param.label_type == DataParameter.LABEL_TYPE.MULTIPLE)
                    {
                        if (m_param.data_param.one_hot_label_size > 0)
                        {
                            int nMask = 0x1;

                            for (int j = 0; j < m_rgOneHotLabel.Length; j++)
                            {
                                if ((datum.Label & nMask) == 0)
                                {
                                    m_rgOneHotLabel[j] = m_tZero;
                                }
                                else
                                {
                                    m_rgOneHotLabel[j] = m_tOne;
                                }

                                nMask <<= 1;
                            }

                            Array.Copy(m_rgOneHotLabel, 0, m_rgTopLabel, i * m_rgOneHotLabel.Length, m_rgOneHotLabel.Length);
                        }
                        else
                        {
                            if (m_param.data_param.images_per_blob > 1)
                            {
                                m_log.FAIL("Loading image pairs (images_per_blob > 1) currently only supports the " + DataParameter.LABEL_TYPE.SINGLE.ToString() + " label type.");
                            }

                            if (m_param.transform_param.label_mapping.Active)
                            {
                                m_log.FAIL("Label mapping is not supported on labels of type 'MULTIPLE'.");
                            }

                            if (datum.DataCriteria == null || datum.DataCriteria.Length == 0)
                            {
                                m_log.FAIL("Could not find the multi-label data.  The data source '" + m_param.data_param.source + "' does not appear to have any Image Criteria data.");
                            }

                            // Get the number of items and the item size from the end of the data.
                            int nLen      = BitConverter.ToInt32(datum.DataCriteria, datum.DataCriteria.Length - (sizeof(int) * 4));
                            int nItemSize = BitConverter.ToInt32(datum.DataCriteria, datum.DataCriteria.Length - (sizeof(int) * 3));
                            int nDstIdx   = i * nLen;

                            m_log.CHECK_EQ(nItemSize, 1, "Currently only byte sized labels are supported in multi-label scenarios.");
                            Array.Copy(datum.DataCriteria, 0, m_rgTopLabel, nDstIdx, nLen);
                        }
                    }
                    else
                    {
                        // When using image pairs, the label is set to 1 when the labels are the same and 0 when they are different.
                        if (m_rgDatum != null)
                        {
                            if (m_rgDatum.Length == 1)
                            {
                                int nLabelDim = 1;

                                if (m_param.data_param.output_all_labels)
                                {
                                    nLabelDim = m_param.data_param.images_per_blob;
                                }

                                if (m_param.data_param.output_all_labels)
                                {
                                    int nLabel = datum.Label;
                                    if (m_param.data_param.forced_primary_label >= 0)
                                    {
                                        nLabel = m_param.data_param.forced_primary_label;
                                    }

                                    m_rgTopLabel[i * nLabelDim] = (T)Convert.ChangeType(nLabel, typeof(T));

                                    for (int j = 0; j < m_rgDatum.Length; j++)
                                    {
                                        m_rgTopLabel[i * nLabelDim + 1 + j] = (T)Convert.ChangeType(m_rgDatum[j].Label, typeof(T));
                                    }
                                }
                                else
                                {
                                    if (datum.Label == m_rgDatum[0].Label)
                                    {
                                        m_rgTopLabel[i * nLabelDim] = m_tOne;
                                    }
                                    else
                                    {
                                        m_rgTopLabel[i * nLabelDim] = m_tZero;
                                    }
                                }
                            }
                            else
                            {
                                m_log.FAIL("Currently image pairing only supports up to 2 images per blob.");
                            }
                        }
                        else
                        {
                            m_rgTopLabel[i] = (T)Convert.ChangeType(datum.Label, typeof(T));
                        }
                    }
                }

                if (m_param.data_param.display_timing)
                {
                    m_dfTransTime += m_swTimerTransaction.Elapsed.TotalMilliseconds;
                }

                if (rgLabels != null)
                {
                    rgLabels.Add(datum.Label);
                }

                Next();

                if (m_evtCancel.WaitOne(0))
                {
                    return;
                }
            }

            m_nBatchCount++;
            batch.Data.SetCPUData(m_rgTopData);

            if (m_bOutputLabels)
            {
                batch.Label.SetCPUData(m_rgTopLabel);
            }

            if (m_param.data_param.display_timing)
            {
                m_swTimerBatch.Stop();
                m_swTimerTransaction.Stop();
                m_log.WriteLine("Prefetch batch: " + m_swTimerBatch.ElapsedMilliseconds.ToString() + " ms.", true);
                m_log.WriteLine("     Read time: " + m_dfReadTime.ToString() + " ms.", true);
                m_log.WriteLine("Transform time: " + m_dfTransTime.ToString() + " ms.", true);
            }

            if (m_param.data_param.synchronize_target)
            {
                if (m_rgBatchLabels != null)
                {
                    m_rgBatchLabels.Done();
                }
            }

            if (OnBatchLoad != null)
            {
                OnBatchLoad(this, new LastBatchLoadedArgs(rgLabels));
            }
        }
示例#3
0
 /// <summary>
 /// The load_batch abstract function should be overriden by each derivative data Layer to
 /// load a batch of data.
 /// </summary>
 /// <param name="batch">Specifies the Batch of data loaded.</param>
 protected abstract void load_batch(Batch <T> batch);