/// <summary> /// Setup the layer for both Engine.CUDNN and Engine.CAFFE modes. /// </summary> /// <param name="colBottom">Specifies the collection of bottom (input) Blobs.</param> /// <param name="colTop">Specifies the collection of top (output) Blobs.</param> public override void LayerSetUp(BlobCollection <T> colBottom, BlobCollection <T> colTop) { m_nSize = (int)m_param.lrn_param.local_size; m_log.CHECK_EQ(m_nSize % 2, 1, "LRN only supports odd values for local_size."); m_nPrePad = (m_nSize - 1) / 2; m_dfAlpha = m_param.lrn_param.alpha; m_dfBeta = m_param.lrn_param.beta; m_dfK = m_param.lrn_param.k; if (m_param.lrn_param.norm_region == LRNParameter.NormRegion.WITHIN_CHANNEL) { // Set up split_layer to use in the numerator and denominator. m_colSplitTopVec = new BlobCollection <T>(); m_colSplitTopVec.Add(m_blobProductInput); m_colSplitTopVec.Add(m_blobSquareInput); LayerParameter split_param = new LayerParameter(LayerParameter.LayerType.SPLIT, "split"); m_splitLayer = new SplitLayer <T>(m_cuda, m_log, split_param); m_splitLayer.Setup(colBottom, m_colSplitTopVec); // Set up square_layer to square teh inputs. m_colSquareBottomVec = new BlobCollection <T>(); m_colSquareTopVec = new BlobCollection <T>(); m_colSquareBottomVec.Add(m_blobSquareInput); m_colSquareTopVec.Add(m_blobSquareOutput); LayerParameter square_param = new LayerParameter(LayerParameter.LayerType.POWER, "square"); square_param.power_param.power = 2.0; m_squareLayer = new PowerLayer <T>(m_cuda, m_log, square_param); m_squareLayer.Setup(m_colSquareBottomVec, m_colSquareTopVec); // Set up pool_layer to sum over square neighborhoods of the input. m_colPoolTopVec = new BlobCollection <T>(); m_colPoolTopVec.Add(m_blobPoolOutput); LayerParameter pool_param = new LayerParameter(LayerParameter.LayerType.POOLING, "pool"); pool_param.pooling_param.pool = PoolingParameter.PoolingMethod.AVE; pool_param.pooling_param.pad.Add((uint)m_nPrePad); pool_param.pooling_param.kernel_size.Add((uint)m_nSize); m_poolLayer = new PoolingLayer <T>(m_cuda, m_log, pool_param); m_poolLayer.Setup(m_colSquareTopVec, m_colPoolTopVec); // Set up power_layer to compute (1 + alpha/N^2 s)^-beta, where s is // the sum of the squared neighborhood (the output of pool_layer) m_colPowerTopVec = new BlobCollection <T>(); m_colPowerTopVec.Add(m_blobPowerOutput); LayerParameter power_param = new LayerParameter(LayerParameter.LayerType.POWER, "power"); power_param.power_param.power = -m_dfBeta; power_param.power_param.scale = m_dfAlpha; power_param.power_param.shift = 1.0; m_powerLayer = new PowerLayer <T>(m_cuda, m_log, power_param); m_powerLayer.Setup(m_colPoolTopVec, m_colPowerTopVec); // Set up a product_layer to compute outputs by multiplying inputs by the // inverse denominator computed by the power layer. m_colProductBottomVec = new BlobCollection <T>(); m_colProductBottomVec.Add(m_blobProductInput); m_colProductBottomVec.Add(m_blobPowerOutput); LayerParameter product_param = new LayerParameter(LayerParameter.LayerType.ELTWISE, "product"); product_param.eltwise_param.operation = EltwiseParameter.EltwiseOp.PROD; m_productLayer = new EltwiseLayer <T>(m_cuda, m_log, product_param); m_productLayer.Setup(m_colProductBottomVec, colTop); } if (!m_param.lrn_param.useCudnn()) { return; } m_hCuDnn = m_cuda.CreateCuDNN(); m_hNormDesc = m_cuda.CreateLRNDesc(); m_hBottomDesc = m_cuda.CreateTensorDesc(); m_hTopDesc = m_cuda.CreateTensorDesc(); }
/** @copydoc Layer::dispose */ protected override void dispose() { m_blobScale.Dispose(); m_blobSquareInput.Dispose(); m_blobSquareOutput.Dispose(); m_blobPoolOutput.Dispose(); m_blobPowerOutput.Dispose(); m_blobProductInput.Dispose(); if (m_splitLayer != null) { m_splitLayer.Dispose(); m_splitLayer = null; } if (m_squareLayer != null) { m_squareLayer.Dispose(); m_squareLayer = null; } if (m_poolLayer != null) { m_poolLayer.Dispose(); m_poolLayer = null; } if (m_powerLayer != null) { m_powerLayer.Dispose(); m_powerLayer = null; } if (m_powerLayer != null) { m_productLayer.Dispose(); m_powerLayer = null; } if (m_hNormDesc != 0) { m_cuda.FreeLRNDesc(m_hNormDesc); m_hNormDesc = 0; } if (m_hBottomDesc != 0) { m_cuda.FreeTensorDesc(m_hBottomDesc); m_hBottomDesc = 0; } if (m_hTopDesc != 0) { m_cuda.FreeTensorDesc(m_hTopDesc); m_hTopDesc = 0; } if (m_hCuDnn != 0) { m_cuda.FreeCuDNN(m_hCuDnn); m_hCuDnn = 0; } if (m_hTempData1 != 0) { m_cuda.FreeMemory(m_hTempData1); m_hTempData1 = 0; } if (m_hTempData2 != 0) { m_cuda.FreeMemory(m_hTempData2); m_hTempData2 = 0; } base.dispose(); }