void DeConv3DLayer::backward(const UpdateCallback &callback) { backwardActivation(); int batchSize = getOutputGrad()->getHeight(); if (biases_ && biases_->getWGrad()) { bpropBiases(); biases_->getParameterPtr()->incUpdate(callback); } REGISTER_TIMER_INFO("BwdDeConv3D", getName().c_str()); for (size_t i = 0; i < inputLayers_.size(); ++i) { if (weights_[i]->getWGrad() || this->needGradient_) { int M = M_[i]; int N = N_[i]; int K = K_[i]; Matrix::resizeOrCreate(colBuf_, K * groups_[i], N, false, useGpu_); const MatrixPtr &inMat = getInputValue(i); for (int n = 0; n < batchSize; ++n) { colBuf_->vol2Col( getOutputGrad()->getData() + n * getOutputGrad()->getStride(), numFilters_, imgSizeD_[i], imgSizeH_[i], imgSizeW_[i], filterSizeZ_[i], filterSizeY_[i], filterSize_[i], strideZ_[i], strideY_[i], stride_[i], paddingZ_[i], paddingY_[i], padding_[i]); if (weights_[i]->getWGrad()) { real *inData = inMat->getData() + n * inMat->getStride(); for (int g = 0; g < groups_[i]; ++g) { MatrixPtr colBufDataSub = colBuf_->subMatrix(g * K, K); MatrixPtr wGradMatSub = weights_[i]->getWGrad()->subMatrix(g * K, K); MatrixPtr inMatSub = Matrix::create(inData, M, N, false, useGpu_); wGradMatSub->mul( *colBufDataSub, *(inMatSub->getTranspose()), 1.0, 1.0); inData += M * N; } } if (getInputGrad(i)) { real *preGrad = getInputGrad(i)->getData() + n * getInputGrad(i)->getStride(); for (int g = 0; g < groups_[i]; ++g) { MatrixPtr w = weights_[i]->getW()->subMatrix(g * K, K); MatrixPtr outGradMat = colBuf_->subMatrix(g * K, K); MatrixPtr inGradMatSub = Matrix::create(preGrad, M, N, false, useGpu_); inGradMatSub->mul(*(w->getTranspose()), *outGradMat, 1.0, 1.0); preGrad += M * N; } } } weights_[i]->getParameterPtr()->incUpdate(callback); } } }
void SelectiveFullyConnectedLayer::backward(const UpdateCallback& callback) { backwardActivation(); MatrixPtr oGrad = getOutputGrad(); if (!fullOutput_) { interOutGrad_ = Matrix::createSparseMatrix(oGrad->getData(), interOutput_->getRows(), interOutput_->getCols(), interOutput_->getHeight(), interOutput_->getWidth(), interOutput_->getElementCnt(), FLOAT_VALUE, SPARSE_CSR, /*trans=*/false, /*useGpu=*/useGpu_); } else { interOutGrad_ = Matrix::create(oGrad->getData(), oGrad->getHeight(), oGrad->getWidth(), /*trans=*/false, /*useGpu=*/useGpu_); } if (biases_ && biases_->getWGrad()) { REGISTER_TIMER_INFO("BpBiasTimer", getName().c_str()); biases_->getWGrad()->collectBias(*interOutGrad_, 1); biases_->getParameterPtr()->incUpdate(callback); } // backward is different from FullyConnectedLayer // because the weight is transposed for (size_t i = 0; i < inputNum_; i++) { AsyncGpuBlock block; MatrixPtr preGrad = getInputGrad(i); if (preGrad) { REGISTER_TIMER_INFO("BpMulTimer", getName().c_str()); preGrad->mul(*interOutGrad_, *weights_[i]->getW(), 1, 1); } MatrixPtr wGrad = weights_[i]->getWGrad(); if (wGrad) { REGISTER_TIMER_INFO("GradMulTimer", getName().c_str()); MatrixPtr input = getInputValue(i); wGrad->mul(*interOutGrad_->getTranspose(), *input, 1, 1); } { REGISTER_TIMER_INFO("WeightUpdate", getName().c_str()); weights_[i]->getParameterPtr()->incUpdate(callback); } } }
void DeConv3DLayer::forward(PassType passType) { Layer::forward(passType); int batchSize = inputLayers_[0]->getOutputValue()->getHeight(); int outWidth = getSize(); resetOutput(batchSize, outWidth); const MatrixPtr outMat = getOutputValue(); REGISTER_TIMER_INFO("FwdDeConv3D", getName().c_str()); for (size_t i = 0; i != inputLayers_.size(); ++i) { const MatrixPtr &inMat = getInputValue(i); int M = M_[i]; int N = N_[i]; int K = K_[i]; MatrixPtr wMat = weights_[i]->getW(); Matrix::resizeOrCreate(colBuf_, K * groups_[i], N, false, useGpu_); for (int n = 0; n < batchSize; ++n) { real *inData = inMat->getData() + n * inMat->getStride(); for (int g = 0; g < groups_[i]; ++g) { MatrixPtr inMatSub = Matrix::create(inData, M, N, false, useGpu_); MatrixPtr wMatSub = wMat->subMatrix(g * K, K); MatrixPtr colBufDataSub = colBuf_->subMatrix(g * K, K); colBufDataSub->mul(*wMatSub, *inMatSub, 1.0, 0.0); inData += M * N; } colBuf_->col2Vol(outMat->getData() + n * outMat->getStride(), numFilters_, imgSizeD_[i], imgSizeH_[i], imgSizeW_[i], filterSizeZ_[i], filterSizeY_[i], filterSize_[i], strideZ_[i], strideY_[i], stride_[i], paddingZ_[i], paddingY_[i], padding_[i], 1.0, 1.0); } } if (nullptr != this->biasParameter_) { this->addBias(); } forwardActivation(); }