- For now flatten layer flatten all dimension except batch.
This commit will be able to flatten only the sub dimensions
Signed-off-by: hyeonseok <hs89.lee@samsung.com>
return value < ml::train::TensorDim::MAXDIM;
}
+StartDimension::StartDimension(unsigned int value) { set(value); }
+
+bool StartDimension::isValid(const unsigned int &value) const {
+ return value > 0 && value < ml::train::TensorDim::MAXDIM;
+}
+
+EndDimension::EndDimension(unsigned int value) { set(value); }
+
+bool EndDimension::isValid(const unsigned int &value) const {
+ return value > 0 && value < ml::train::TensorDim::MAXDIM;
+}
+
bool SplitDimension::isValid(const unsigned int &value) const {
return value > 0 && value < ml::train::TensorDim::MAXDIM;
}
bool isValid(const unsigned int &value) const override;
};
+/**
+ * @brief StartDimension property, start dimension to be flatten
+ *
+ */
+class StartDimension : public Axis {
+public:
+ StartDimension(unsigned int value = 1);
+ static constexpr const char *key = "start_dimension";
+ using prop_tag = uint_prop_tag;
+
+ /**
+ * @brief check if given value is valid
+ *
+ * @param v value to check
+ * @retval true if it is greater than 0 and smaller than
+ * ml::train::TensorDim::MAXDIM
+ * @retval false if it is smaller or equal to 0 or greater than
+ * ml::train::TensorDim::MAXDIM
+ */
+ bool isValid(const unsigned int &value) const override;
+};
+
+/**
+ * @brief EndDimension property, end dimension to be flatten
+ *
+ */
+class EndDimension : public Axis {
+public:
+ EndDimension(unsigned int value = ml::train::TensorDim::MAXDIM - 1);
+ static constexpr const char *key = "end_dimension";
+ using prop_tag = uint_prop_tag;
+
+ /**
+ * @brief check if given value is valid
+ *
+ * @param v value to check
+ * @retval true if it is greater than 0 and smaller than
+ * ml::train::TensorDim::MAXDIM
+ * @retval false if it is smaller or equal to 0 or greater than
+ * ml::train::TensorDim::MAXDIM
+ */
+ bool isValid(const unsigned int &value) const override;
+};
+
/**
* @brief SplitDimension property, dimension along which to split the input
*
* @date 16 June 2020
* @see https://github.com/nnstreamer/nntrainer
* @author Jijoong Moon <jijoong.moon@samsung.com>
+ * @author hyeonseok Lee <hs89.lee@samsung.com>
* @bug No known bugs except for NYI items
* @brief This is Flatten Layer Class for Neural Network
*
void FlattenLayer::finalize(InitLayerContext &context) {
const TensorDim &in_dim = context.getInputDimensions()[0];
- std::string target_shape =
- "target_shape=1:1:" + std::to_string(in_dim.getFeatureLen());
+ std::string target_shape;
+
+ const unsigned int start_dimension =
+ std::get<props::StartDimension>(flatten_props).get();
+ const unsigned int end_dimension =
+ std::get<props::EndDimension>(flatten_props).get();
+
+ NNTR_THROW_IF(start_dimension > end_dimension, std::invalid_argument)
+ << "start_dimension is bigger than end_dimension";
+
+ TensorDim target_dim = in_dim;
+
+ unsigned int flattened_size = 1;
+ for (unsigned int i = start_dimension; i <= end_dimension; ++i) {
+ flattened_size *= in_dim[i];
+ target_dim[i] = 1;
+ }
+ target_dim[end_dimension] = flattened_size;
+
+ target_shape = "target_shape=" + std::to_string(target_dim[1]) + ":" +
+ std::to_string(target_dim[2]) + ":" +
+ std::to_string(target_dim[3]);
+
ReshapeLayer::setProperty({target_shape});
/** @note the output dimension is in invalid state till finalize of
}
void FlattenLayer::setProperty(const std::vector<std::string> &values) {
- auto remain_props = loadProperties(values, reshape_props);
+ auto remain_props = loadProperties(values, flatten_props);
+ remain_props = loadProperties(remain_props, reshape_props);
if (!remain_props.empty()) {
std::string msg = "[FlattenLayer] Unknown Layer Properties count " +
std::to_string(values.size());
/**
* @brief Constructor of Flatten Layer
*/
- FlattenLayer() : ReshapeLayer() {}
+ FlattenLayer() : ReshapeLayer(), flatten_props(
+ props::StartDimension(), props::EndDimension()) {}
/**
* @brief Destructor of Flatten Layer
const std::string getType() const override { return FlattenLayer::type; };
inline static const std::string type = "flatten";
+
+ std::tuple<props::StartDimension, props::EndDimension> flatten_props;
};
} // namespace nntrainer
nntrainer::FlattenLayer::type, {},
LayerCreateSetPropertyOptions::AVAILABLE_FROM_APP_CONTEXT, false, 1);
-GTEST_PARAMETER_TEST(Flatten, LayerSemantics,
- ::testing::Values(semantic_flatten));
+auto semantic_flatten_with_start_dim = LayerSemanticsParamType(
+ nntrainer::createLayer<nntrainer::FlattenLayer>,
+ nntrainer::FlattenLayer::type, {"start_dimension = 2"},
+ LayerCreateSetPropertyOptions::AVAILABLE_FROM_APP_CONTEXT, false, 1);
+
+auto semantic_flatten_with_start_dim_end_dim = LayerSemanticsParamType(
+ nntrainer::createLayer<nntrainer::FlattenLayer>,
+ nntrainer::FlattenLayer::type, {"start_dimension = 2", "end_dimension = 3"},
+ LayerCreateSetPropertyOptions::AVAILABLE_FROM_APP_CONTEXT, false, 1);
+
+GTEST_PARAMETER_TEST(
+ Flatten, LayerSemantics,
+ ::testing::Values(semantic_flatten, semantic_flatten_with_start_dim,
+ semantic_flatten_with_start_dim_end_dim));