ImageBatch Convolution::ConvForward(ImageBatch src, Filter filter, NArray bias, ConvInfo info) { CHECK_EQ(src.GetNumFeatureMaps(), filter.GetNumInputs()) << "#input channels mismatch"; CHECK_EQ(bias.Size().NumDims(), 1) << "bias dimension mismatch"; CHECK_EQ(bias.Size()[0], filter.GetNumOutputs()) << "bias size mismatch"; //no such limit //CHECK_EQ((src.GetHeight() + 2 * info.pad_height - filter.GetHeight()) % info.stride_vertical, 0) << "filter height mismatch"; //CHECK_EQ((src.GetWidth() + 2 * info.pad_width - filter.GetWidth()) % info.stride_horizontal, 0) << "filter width mismatch"; Scale new_size { (src.GetWidth() + 2 * info.pad_width - filter.GetWidth()) / info.stride_horizontal + 1, (src.GetHeight() + 2 * info.pad_height - filter.GetHeight()) / info.stride_vertical + 1, filter.GetNumOutputs(), src.GetNumImages() }; ConvForwardOp* op = new ConvForwardOp(); op->closure = { info.pad_height, info.pad_width, info.stride_vertical, info.stride_horizontal }; return NArray::ComputeOne({src, filter, bias}, new_size, op); }
ImageBatch Convolution::ConvBackwardData(ImageBatch diff, ImageBatch bottom, Filter filter, ConvInfo info) { CHECK_EQ(diff.GetNumFeatureMaps(), filter.GetNumOutputs()) << "#output channels mismatch"; /* * We can't get filter size when (top + 2*pad) % stride != 0 Scale new_size { (diff.GetWidth() - 1) * info.stride_horizontal + filter.GetWidth() - 2 * info.pad_width, (diff.GetHeight() - 1) * info.stride_vertical + filter.GetHeight() - 2 * info.pad_height, filter.GetNumInputs(), diff.GetNumImages() }; */ ConvBackwardDataOp* op = new ConvBackwardDataOp(); op->closure = { info.pad_height, info.pad_width, info.stride_vertical, info.stride_horizontal }; return NArray::ComputeOne({diff, filter}, bottom.Size(), op); }