-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update MobileNet Model #85
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
{ | ||
"files.associations": { | ||
"cctype": "cpp", | ||
"clocale": "cpp", | ||
"cmath": "cpp", | ||
"csetjmp": "cpp", | ||
"csignal": "cpp", | ||
"cstdarg": "cpp", | ||
"cstddef": "cpp", | ||
"cstdio": "cpp", | ||
"cstdlib": "cpp", | ||
"cstring": "cpp", | ||
"ctime": "cpp", | ||
"cwchar": "cpp", | ||
"cwctype": "cpp", | ||
"any": "cpp", | ||
"array": "cpp", | ||
"atomic": "cpp", | ||
"strstream": "cpp", | ||
"bit": "cpp", | ||
"*.tcc": "cpp", | ||
"bitset": "cpp", | ||
"chrono": "cpp", | ||
"codecvt": "cpp", | ||
"compare": "cpp", | ||
"complex": "cpp", | ||
"concepts": "cpp", | ||
"condition_variable": "cpp", | ||
"coroutine": "cpp", | ||
"cstdint": "cpp", | ||
"deque": "cpp", | ||
"list": "cpp", | ||
"map": "cpp", | ||
"set": "cpp", | ||
"string": "cpp", | ||
"unordered_map": "cpp", | ||
"unordered_set": "cpp", | ||
"vector": "cpp", | ||
"exception": "cpp", | ||
"algorithm": "cpp", | ||
"functional": "cpp", | ||
"iterator": "cpp", | ||
"memory": "cpp", | ||
"memory_resource": "cpp", | ||
"numeric": "cpp", | ||
"optional": "cpp", | ||
"random": "cpp", | ||
"ratio": "cpp", | ||
"regex": "cpp", | ||
"source_location": "cpp", | ||
"string_view": "cpp", | ||
"system_error": "cpp", | ||
"tuple": "cpp", | ||
"type_traits": "cpp", | ||
"utility": "cpp", | ||
"fstream": "cpp", | ||
"future": "cpp", | ||
"initializer_list": "cpp", | ||
"iomanip": "cpp", | ||
"iosfwd": "cpp", | ||
"iostream": "cpp", | ||
"istream": "cpp", | ||
"limits": "cpp", | ||
"mutex": "cpp", | ||
"new": "cpp", | ||
"numbers": "cpp", | ||
"ostream": "cpp", | ||
"semaphore": "cpp", | ||
"span": "cpp", | ||
"sstream": "cpp", | ||
"stdexcept": "cpp", | ||
"stop_token": "cpp", | ||
"streambuf": "cpp", | ||
"thread": "cpp", | ||
"cfenv": "cpp", | ||
"cinttypes": "cpp", | ||
"typeindex": "cpp", | ||
"typeinfo": "cpp", | ||
"valarray": "cpp", | ||
"variant": "cpp" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,142 @@ | ||||||
/** | ||||||
* @file mobilenet.hpp | ||||||
* @author Aakash Kaushik | ||||||
* | ||||||
* Definition of MobileNet model. | ||||||
* | ||||||
* For more information, kindly refer to the following paper. | ||||||
* | ||||||
* @code | ||||||
* @article{Andrew G2017, | ||||||
* author = {Andrew G. Howard, Menglong Zhu, Bo Chen, Dmitry Kalenichenko, | ||||||
* Weijun Wang, Tobias Weyand, Marco Andreetto, Hartwig Adam}, | ||||||
* title = {MobileNets: Efficient Convolutional Neural Networks for Mobile | ||||||
* Vision Applications}, | ||||||
* year = {2017}, | ||||||
* url = {https://arxiv.org/pdf/1704.04861} | ||||||
* } | ||||||
* @endcode | ||||||
* | ||||||
* mlpack is free software; you may redistribute it and/or modify it under the | ||||||
* terms of the 3-clause BSD license. You should have received a copy of the | ||||||
* 3-clause BSD license along with mlpack. If not, see | ||||||
* http://www.opensource.org/licenses/BSD-3-Clause for more information. | ||||||
*/ | ||||||
#ifndef MODELS_MODELS_MOBILENET_MOBILENET_HPP | ||||||
#define MODELS_MODELS_MOBILENET_MOBILENET_HPP | ||||||
|
||||||
#define MLPACK_ENABLE_ANN_SERIALIZATION | ||||||
#include <mlpack.hpp> | ||||||
|
||||||
#include "separable_convolution.hpp" | ||||||
|
||||||
#include "./../../utils/utils.hpp" | ||||||
|
||||||
namespace mlpack { | ||||||
namespace models { | ||||||
|
||||||
/** | ||||||
* Definition of a MobileNet CNN. | ||||||
* | ||||||
* @tparam OutputLayerType The output layer type used to evaluate the network. | ||||||
* @tparam InitializationRuleType Rule used to initialize the weight matrix. | ||||||
*/ | ||||||
template< | ||||||
typename MatType = arma::mat | ||||||
> | ||||||
class MobileNetType : public MultiLayer<MatType> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have a general question about the design. I think it might be cleaner to simply have |
||||||
{ | ||||||
public: | ||||||
//! Create the MobileNet model. | ||||||
//MobileNetType(); | ||||||
|
||||||
/** | ||||||
* MobileNetType constructor initializes input shape and number of classes. | ||||||
* | ||||||
* @param numClasses Number of classes to classify images into, | ||||||
* only to be specified if includeTop is true. | ||||||
* @param includeTop Must be set to true if classifier layers are set. | ||||||
* * @param alpha Controls the number of output channels in pointwise | ||||||
* convolution: outSize * depthMultiplier. | ||||||
* @param depthMultiplier Controls the number of output channels in depthwise | ||||||
* convolution: inSize * depthMultiplier. | ||||||
*/ | ||||||
MobileNetType(const size_t numClasses = 1000, | ||||||
const bool includeTop = true, | ||||||
const float alpha = 1.0, | ||||||
const size_t depthMultiplier = 1.0); | ||||||
|
||||||
//! Copy the given MobileNetType. | ||||||
MobileNetType(const MobileNetType& other); | ||||||
//! Take ownership of the layers of the given MobileNetType. | ||||||
MobileNetType(MobileNetType&& other); | ||||||
//! Copy the given MobileNetType. | ||||||
MobileNetType& operator=(const MobileNetType& other); | ||||||
//! Take ownership of the given MobileNetType. | ||||||
MobileNetType& operator=(MobileNetType&& other); | ||||||
|
||||||
//! Virtual destructor: delete all held layers. | ||||||
virtual ~MobileNetType() | ||||||
{ /* Nothing to do here. */ } | ||||||
|
||||||
//! Create a copy of the MobileNetType (this is safe for polymorphic use). | ||||||
MobileNetType* Clone() const { return new MobileNetType(*this); } | ||||||
|
||||||
/** | ||||||
* Get the FFN object representing the network. | ||||||
* | ||||||
* @tparam OutputLayerType The output layer type used to evaluate the network. | ||||||
* @tparam InitializationRuleType Rule used to initialize the weight matrix. | ||||||
*/ | ||||||
template< | ||||||
typename OutputLayerType = CrossEntropyError, | ||||||
typename InitializationRuleType = RandomInitialization | ||||||
> | ||||||
FFN<OutputLayerType, InitializationRuleType, MatType>* GetModel() | ||||||
{ | ||||||
FFN<OutputLayerType, InitializationRuleType, MatType>* mobileNet = | ||||||
new FFN<OutputLayerType, InitializationRuleType, MatType>(); | ||||||
mobileNet->Add(this); | ||||||
return mobileNet; | ||||||
} | ||||||
|
||||||
//! Serialize the MobileNetType. | ||||||
template<typename Archive> | ||||||
void serialize(Archive& ar, const uint32_t /* version */); | ||||||
|
||||||
private: | ||||||
//! Generate the layers of the MobileNet. | ||||||
void MakeModel(); | ||||||
|
||||||
//! Locally stored number of output classes. | ||||||
size_t numClasses; | ||||||
|
||||||
//! Locally stored if classifier layers are included or not. | ||||||
bool includeTop; | ||||||
|
||||||
//! Locally stored alpha for mobileNet block creation. | ||||||
float alpha; | ||||||
|
||||||
//! Locally stored Depth multiplier for mobileNet block creation. | ||||||
float depthMultiplier; | ||||||
|
||||||
//! Locally stored map to construct mobileNetV1 blocks. | ||||||
std::map<size_t, size_t> mobileNetConfig = { | ||||||
{128, 2}, | ||||||
{256, 2}, | ||||||
{512, 6}, | ||||||
{1024, 2}, | ||||||
}; | ||||||
}; // MobileNetType class | ||||||
|
||||||
// convenience typedef. | ||||||
typedef MobileNetType<arma::mat> Mobilenet; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
} // namespace models | ||||||
} // namespace mlpack | ||||||
|
||||||
CEREAL_REGISTER_TYPE(mlpack::models::MobileNetType<arma::mat>); | ||||||
|
||||||
#include "mobilenet_impl.hpp" | ||||||
|
||||||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
/** | ||
* @file mobilenet_impl.hpp | ||
* @author Aakash Kaushik | ||
* | ||
* Implementation of MobileNet using mlpack. | ||
* | ||
* mlpack is free software; you may redistribute it and/or modify it under the | ||
* terms of the 3-clause BSD license. You should have received a copy of the | ||
* 3-clause BSD license along with mlpack. If not, see | ||
* http://www.opensource.org/licenses/BSD-3-Clause for more information. | ||
*/ | ||
#ifndef MODELS_MODELS_MOBILENET_MOBILENET_IMPL_HPP | ||
#define MODELS_MODELS_MOBILENET_MOBILENET_IMPL_HPP | ||
|
||
#include "mobilenet.hpp" | ||
|
||
namespace mlpack { | ||
namespace models { | ||
|
||
template<typename MatType> | ||
MobileNetType<MatType>::MobileNetType( | ||
const size_t numClasses, | ||
const bool includeTop, | ||
const float alpha, | ||
const size_t depthMultiplier) : | ||
MultiLayer<MatType>(), | ||
numClasses(numClasses), | ||
includeTop(includeTop), | ||
alpha(alpha), | ||
depthMultiplier(depthMultiplier) | ||
{ | ||
MakeModel(); | ||
} | ||
|
||
template<typename MatType> | ||
MobileNetType<MatType>::MobileNetType( | ||
const MobileNetType& other) : | ||
MultiLayer<MatType>(other), | ||
numClasses(other.numClasses), | ||
includeTop(other.includeTop), | ||
alpha(other.alpha), | ||
depthMultiplier(other.depthMultiplier) | ||
{ | ||
// Nothing to do here. | ||
} | ||
|
||
template<typename MatType> | ||
MobileNetType<MatType>::MobileNetType( | ||
MobileNetType&& other) : | ||
MultiLayer<MatType>(std::move(other)), | ||
numClasses(std::move(other.numClasses)), | ||
includeTop(std::move(other.includeTop)), | ||
alpha(std::move(other.alpha)), | ||
depthMultiplier(std::move(other.depthMultiplier)) | ||
{ | ||
// Nothing to do here. | ||
} | ||
|
||
template<typename MatType> | ||
MobileNetType<MatType>& | ||
MobileNetType<MatType>::operator=( | ||
const MobileNetType& other) | ||
{ | ||
if (this != &other) | ||
{ | ||
MultiLayer<MatType>::operator=(other); | ||
numClasses = other.numClasses; | ||
includeTop = other.includeTop; | ||
alpha = other.alpha; | ||
depthMultiplier = other.depthMultiplier; | ||
} | ||
|
||
return *this; | ||
} | ||
|
||
template<typename MatType> | ||
MobileNetType<MatType>& | ||
MobileNetType<MatType>::operator=( | ||
MobileNetType&& other) | ||
{ | ||
if (this != &other) | ||
{ | ||
MultiLayer<MatType>::operator=(std::move(other)); | ||
numClasses = std::move(other.numClasses); | ||
includeTop = std::move(other.includeTop); | ||
alpha = std::move(other.alpha); | ||
depthMultiplier = std::move(other.depthMultiplier); | ||
} | ||
|
||
return *this; | ||
} | ||
|
||
template<typename MatType> | ||
template<typename Archive> | ||
void MobileNetType<MatType>::serialize( | ||
Archive& ar, const uint32_t /* version */) | ||
{ | ||
ar(cereal::base_class<MultiLayer<MatType>>(this)); | ||
|
||
ar(CEREAL_NVP(numClasses)); | ||
ar(CEREAL_NVP(includeTop)); | ||
ar(CEREAL_NVP(alpha)); | ||
ar(CEREAL_NVP(depthMultiplier)); | ||
} | ||
|
||
template<typename MatType> | ||
void MobileNetType<MatType>::MakeModel() | ||
{ | ||
this->template Add<Convolution>(32, 3, 3, 2, 2, 0, 0); | ||
this->template Add<BatchNorm>(); | ||
|
||
size_t outSize = size_t(32 * alpha); | ||
|
||
this->template Add<SeparableConvolution>(outSize, outSize*depthMultiplier, | ||
alpha, depthMultiplier); | ||
|
||
outSize = size_t(64 * alpha); | ||
|
||
for (const auto& blockConfig : mobileNetConfig){ | ||
this->template Add<Padding>(0, 1, 0, 1); | ||
this->template Add<SeparableConvolution>(outSize, outSize*depthMultiplier, | ||
3, 3, 2, 2, 0, 0, 1, 1, 1, "valid"); | ||
this->template Add<BatchNorm>(); | ||
this->template Add<ReLU6>(); | ||
|
||
outSize = size_t(blockConfig.first * alpha); | ||
|
||
for (size_t numBlock = 1; numBlock < blockConfig.second; ++numBlock) | ||
{ | ||
this->template Add<SeparableConvolution>(outSize, outSize*depthMultiplier, | ||
3, 3, 1, 1, 0, 0, 0, 0, 1, "same"); | ||
this->template Add<BatchNorm>(); | ||
this->template Add<ReLU6>(); | ||
|
||
outSize = size_t(blockConfig.first * alpha); | ||
} | ||
|
||
this->template Add<AdaptiveMeanPooling>(1,1); | ||
} | ||
|
||
if (includeTop) | ||
{ | ||
this->template Add<Dropout>(1e-3); | ||
this->template Add<Convolution>(size_t(1024 * alpha), numClasses, | ||
1, 1, 1, 0, 0); | ||
this->template Add<Softmax>(); | ||
} | ||
} | ||
|
||
} // namespace models | ||
} // namespace mlpack | ||
|
||
#endif // MODELS_MODELS_MOBILENET_MOBILENET_IMPL_HPP |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to add this file---we could add it to the
.gitignore
perhaps?