TEST(Layer, WarpCTCLayer) { for (auto layerSize : {10, 64}) { for (auto batchSize : {1, 10, 32}) { for (auto normByTimes : {false, true}) { for (auto useGpu : {false, true}) { #ifndef PADDLE_WITH_CUDA if (useGpu) continue; #endif LOG(INFO) << "layerSize=" << layerSize << " batchSize=" << batchSize << " normByTimes = " << normByTimes << " useGpu=" << useGpu; FLAGS_use_gpu = useGpu; Argument data0; initArgument(batchSize, layerSize, useGpu, data0); Argument data1; data1.resizeAndCopyFrom(data0); LayerPtr dataLayer0 = createDataLayer("data", batchSize, layerSize, useGpu, data0); LayerPtr dataLayer1 = createDataLayer("data", batchSize, layerSize, useGpu, data1); LayerPtr labelLayer = createLabelLayer("label", batchSize, layerSize, useGpu); LayerPtr warpctcLayer = createWarpCTCLayer( "cost", layerSize, useGpu, normByTimes, dataLayer0, labelLayer); LayerPtr ctcLayer = createCTCLayer( "cost", layerSize, useGpu, normByTimes, dataLayer1, labelLayer); /// Check cost LOG(INFO) << "Check cost: " << checkError(*(warpctcLayer->getOutput().value), *(ctcLayer->getOutput().value)) << " different elements."; /// Check gradients LOG(INFO) << "Check gradients: " << checkError(*(dataLayer0->getOutput().grad), *(dataLayer1->getOutput().grad)) << " different elements"; } } } } }
LayerPtr createCTCLayer(string name, size_t numClasses, bool useGpu, bool normByTimes, LayerPtr dataLayer, LayerPtr labelLayer) { LayerMap layerMap; layerMap[dataLayer->getName()] = dataLayer; layerMap[labelLayer->getName()] = labelLayer; ParameterMap parameterMap; LayerConfig layerConfig; layerConfig.set_name(name); layerConfig.set_type("ctc"); layerConfig.set_size(numClasses); layerConfig.set_norm_by_times(normByTimes); layerConfig.add_inputs(); LayerInputConfig& input0 = *(layerConfig.mutable_inputs(0)); input0.set_input_layer_name(dataLayer->getName()); layerConfig.add_inputs(); LayerInputConfig& input1 = *(layerConfig.mutable_inputs(1)); input1.set_input_layer_name(labelLayer->getName()); LayerPtr layer = LayerPtr(new CTCLayer(layerConfig)); layerMap[layer->getName()] = layer; layer->init(layerMap, parameterMap); ActivationFunction* softmaxActivation = ActivationFunction::create("softmax"); softmaxActivation->forward(dataLayer->getOutput()).check(); layer->forward(PASS_GC); layer->backward(); softmaxActivation->backward(dataLayer->getOutput()).check(); return layer; }
// Test that the convTrans forward is the same as conv backward TEST(Layer, convTransLayerFwd) { // Setting up conv-trans layer TestConfig configt; configt.biasSize = 3; configt.layerConfig.set_type("exconvt"); configt.layerConfig.set_num_filters(3); configt.layerConfig.set_partial_sum(1); configt.layerConfig.set_shared_biases(true); configt.inputDefs.push_back({INPUT_DATA, "layer_0", 1024, 384}); LayerInputConfig* input = configt.layerConfig.add_inputs(); ConvConfig* conv = input->mutable_conv_conf(); conv->set_filter_size(2); conv->set_filter_size_y(4); conv->set_channels(16); conv->set_padding(0); conv->set_padding_y(1); conv->set_stride(2); conv->set_stride_y(2); conv->set_groups(1); conv->set_filter_channels(3 / conv->groups()); conv->set_img_size(16); conv->set_output_x(outputSize(conv->img_size(), conv->filter_size(), conv->padding(), conv->stride(), /* caffeMode */ true)); configt.layerConfig.set_size(conv->img_size() * conv->img_size() * configt.layerConfig.num_filters()); configt.layerConfig.set_name("convTrans"); // data layer initialize std::vector<DataLayerPtr> dataLayers; LayerMap layerMap; vector<Argument> datas; initDataLayer(configt, &dataLayers, &datas, &layerMap, "convTrans", 100, false, false); // test layer initialize std::vector<ParameterPtr> parameters; LayerPtr convtLayer; initTestLayer(configt, &layerMap, ¶meters, &convtLayer); convtLayer->getBiasParameter()->zeroMem(); convtLayer->forward(PASS_GC); // Setting up conv-layer config TestConfig config; config.biasSize = 16; config.layerConfig.set_type("exconv"); config.layerConfig.set_num_filters(16); config.layerConfig.set_partial_sum(1); config.layerConfig.set_shared_biases(true); config.inputDefs.push_back({INPUT_DATA, "layer_1", 768, 384}); input = config.layerConfig.add_inputs(); conv = input->mutable_conv_conf(); conv->set_filter_size(2); conv->set_filter_size_y(4); conv->set_channels(3); conv->set_padding(0); conv->set_padding_y(1); conv->set_stride(2); conv->set_stride_y(2); conv->set_groups(1); conv->set_filter_channels(conv->channels() / conv->groups()); conv->set_img_size(16); conv->set_output_x(outputSize(conv->img_size(), conv->filter_size(), conv->padding(), conv->stride(), /* caffeMode */ true)); config.layerConfig.set_size(conv->output_x() * conv->output_x() * config.layerConfig.num_filters()); config.layerConfig.set_name("conv"); // data layer initialize std::vector<DataLayerPtr> dataLayers2; LayerMap layerMap2; vector<Argument> datas2; initDataLayer(config, &dataLayers2, &datas2, &layerMap2, "conv", 100, false, false); // test layer initialize std::vector<ParameterPtr> parameters2; LayerPtr convLayer; initTestLayer(config, &layerMap2, ¶meters2, &convLayer); // Sync convLayer and convtLayer parameter convLayer->getBiasParameter()->zeroMem(); convLayer->getParameters()[0]->getBuf(PARAMETER_VALUE)->copyFrom( *(convtLayer->getParameters()[0]->getBuf(PARAMETER_VALUE))); // Set convLayer outputGrad as convTransLayer input value convLayer->forward(PASS_GC); convLayer->getOutput().grad->copyFrom(*(dataLayers[0]->getOutputValue())); vector<int> callbackFlags(parameters2.size(), 0); auto callback = [&](Parameter* para) { ++callbackFlags[para->getID()]; }; convLayer->backward(callback); // Check that the convLayer backward is the same as convTransLayer forward checkMatrixEqual(convtLayer->getOutputValue(), dataLayers2[0]->getOutputGrad()); }