From f8f6a35d44698c9c7e6fdc304dbb61f2dc65ac0c Mon Sep 17 00:00:00 2001 From: lg Date: Sun, 24 Feb 2019 12:18:04 +0800 Subject: [PATCH 01/19] support mean pool --- include/nn/bits/ops/pool.hpp | 82 ++++++++++++++++++++++++++++++------ tests/test_pool.cpp | 17 ++++++++ 2 files changed, 85 insertions(+), 14 deletions(-) diff --git a/include/nn/bits/ops/pool.hpp b/include/nn/bits/ops/pool.hpp index 5252004..c3eb5f2 100644 --- a/include/nn/bits/ops/pool.hpp +++ b/include/nn/bits/ops/pool.hpp @@ -78,42 +78,92 @@ template <> class pool_trait struct pool_max; struct pool_mean; +namespace internal +{ +template class max_accumulator +{ + R val; + + public: + max_accumulator() : val(std::numeric_limits::lowest()) {} + + void operator()(R x) + { + if (x > val) { val = x; } + } + + operator R() const { return val; } +}; + +template class mean_accumulator +{ + R sum; + uint32_t n; + + public: + mean_accumulator() : sum(0), n(0) {} + + void operator()(R x) + { + sum += x; + ++n; + } + + operator R() const { return sum / n; } +}; + +template struct accumulator; + +template struct accumulator { + using type = max_accumulator; +}; +template struct accumulator { + using type = mean_accumulator; +}; +} // namespace internal + template class pool; -template <> class pool : public pool_trait +template class pool : public pool_trait { using pool_trait::pool_trait; public: + shape<2> operator()(const shape<2> &x) const + { + return pool_trait::operator()(x); // FIXME: auto pass through + } + // TODO: support strided tensor template void operator()(const ttl::tensor_ref &y, const ttl::tensor_view &x) const { + using accumulator = typename internal::accumulator::type; + const auto [h, w] = x.shape().dims; const auto [h_, w_] = y.shape().dims; const auto [r, s] = get_ksize().dims; for (auto i_ : range(h_)) { for (auto j_ : range(w_)) { - R yy = std::numeric_limits::lowest(); + accumulator acc; for (auto u : range(r)) { for (auto v : range(s)) { const auto i = h_sample_(i_, u); const auto j = w_sample_(j_, v); if (h_sample_.inside(i, h) && w_sample_.inside(j, w)) { - yy = std::max(yy, x.at(h_sample_.unpad(i), - w_sample_.unpad(j))); + acc(x.at(h_sample_.unpad(i), w_sample_.unpad(j))); } } } - y.at(i_, j_) = yy; + y.at(i_, j_) = acc; } } } }; -template <> class pool : public pool_trait +template class pool : public pool_trait { using pool_trait::pool_trait; @@ -122,6 +172,8 @@ template <> class pool : public pool_trait void operator()(const ttl::tensor_ref &y, const ttl::tensor_view &x) const { + using accumulator = typename internal::accumulator::type; + const auto [h, w, c] = x.shape().dims; const auto [h_, w_, _c] = y.shape().dims; const auto [r, s] = get_ksize().dims; @@ -130,19 +182,19 @@ template <> class pool : public pool_trait for (auto k : range(c)) { for (auto i_ : range(h_)) { for (auto j_ : range(w_)) { - R yy = std::numeric_limits::lowest(); + accumulator acc; for (auto u : range(r)) { for (auto v : range(s)) { const auto i = h_sample_(i_, u); const auto j = w_sample_(j_, v); if (h_sample_.inside(i, h) && w_sample_.inside(j, w)) { - yy = std::max(yy, x.at(h_sample_.unpad(i), - w_sample_.unpad(j), k)); + acc(x.at(h_sample_.unpad(i), w_sample_.unpad(j), + k)); } } } - y.at(i_, j_, k) = yy; + y.at(i_, j_, k) = acc; } } } @@ -157,7 +209,8 @@ shape<4> pooled_shape(const shape<4> &x, const PoolTrait &pt) channel_size(x)); } -template <> class pool : public pool_trait +template +class pool : public pool_trait { using pool_trait::pool_trait; @@ -171,12 +224,13 @@ template <> class pool : public pool_trait void operator()(const ttl::tensor_ref &y, const ttl::tensor_view &x) const { - pool op(get_ksize(), get_stride()); + pool op(get_ksize(), get_stride()); for (auto i : range(x.shape().dims[0])) { op(y[i], x[i]); } } }; -template <> class pool : public pool_trait +template +class pool : public pool_trait { public: using pool_trait::pool_trait; @@ -190,7 +244,7 @@ template <> class pool : public pool_trait void operator()(const ttl::tensor_ref &y, const ttl::tensor_view &x) const { - pool op(get_ksize(), get_stride()); + pool op(get_ksize(), get_stride()); for (auto i : range(x.shape().dims[0])) { for (auto j : range(x.shape().dims[1])) { op(y[i][j], x[i][j]); } } diff --git a/tests/test_pool.cpp b/tests/test_pool.cpp index 21800ae..2ebf56f 100644 --- a/tests/test_pool.cpp +++ b/tests/test_pool.cpp @@ -146,3 +146,20 @@ TEST(pool_test, test_padding) } } } + +TEST(pool_test, test_mean) +{ + using pool = nn::ops::pool; + const pool op; + const auto x = ttl::tensor(4, 4); + std::iota(x.data(), x.data() + 16, 0); + using add = nn::ops::add; + add()(ref(x), view(x), view(x)); + + const auto y = ttl::tensor(op(x.shape())); + op(ref(y), view(x)); + ASSERT_EQ(y.data()[0], 5); + ASSERT_EQ(y.data()[1], 9); + ASSERT_EQ(y.data()[2], 21); + ASSERT_EQ(y.data()[3], 25); +} From 5644ae05d12eb401bda559a238caa244771e6f84 Mon Sep 17 00:00:00 2001 From: lg Date: Sun, 24 Feb 2019 15:38:09 +0800 Subject: [PATCH 02/19] add detailed doc for linear sample --- doc/linear-sample.tex | 61 +++++++++++++++++++++++++++++++++++++++++++ doc/nn.tex | 36 +++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 doc/linear-sample.tex create mode 100644 doc/nn.tex diff --git a/doc/linear-sample.tex b/doc/linear-sample.tex new file mode 100644 index 0000000..5166ab7 --- /dev/null +++ b/doc/linear-sample.tex @@ -0,0 +1,61 @@ +\section{Linear Sample of Dimension One} + +\begin{defi}[valid convolution] +A valid convolution is the linear map +\begin{align*} + x[n] \circ y[k] \to z[m] +\end{align*} +where +\begin{align*} + z[i] &= \sum_{j=0}^{k - 1} x[i + j] \cdot y[j] \quad (0 \leq i < m) \\ + n &= m + k - 1 +\end{align*} +\end{defi} + +\begin{defi}[strided valid convolution] +A strided valid convolution is the linear map +\begin{align*} + x[n] \circ y[k] \to z[m] +\end{align*} +where +\begin{align*} + z[i] &= \sum_{j=0}^{k - 1} x[i \cdot s + j] \cdot y[j] \quad (0 \leq i < m) \\ + n &= s (m - 1) + k +\end{align*} +\end{defi} + +\begin{defi}[linear sample] +A linear sample is a map that maps a sequence of length $n$ to a sequence of +length $m$. +\end{defi} + +The sampling takes the following steps: +\begin{itemize} +\item The input sequence $x[n]$ is padded to $\hat x[\hat n]$ by +prepending $p_l$ zero elements and appending $p_r$ zero elements, where +\begin{align*} + \hat n = p_l + n + p_r +\end{align*} +In most case $p_r = p_l$ or $p_r = p_l + 1$. + +\item The kernel (filter) $y[k]$ is extended to $\hat y[\hat k]$ +by inserting $r - 1$ zero elements to adjacent elements, where +\begin{align*} + \hat k = r * (k - 1) + 1 +\end{align*} + +\item The padded input $\hat x$ and the extended kernel $\hat y$ takes a +valid convolution with stride $s$, resulting the output sequence $z[m]$, +where +\begin{align*} + m = {\hat n - \hat k \over s} + 1 +\end{align*} +and $s \mid \hat n - \hat k$ should be granted. +\end{itemize} + + +$(p_l, p_r, k, s, r, n, m)$, $p_l, p_r \in \mathbb N$, $k, s, r, n, m \in \mathbb N^\ast$ +is called a valid configuration of linear sample if +\begin{align*} + s (m - 1) = (n + p_l + p_r) - (r (k - 1) + 1) +\end{align*} diff --git a/doc/nn.tex b/doc/nn.tex new file mode 100644 index 0000000..0f13a89 --- /dev/null +++ b/doc/nn.tex @@ -0,0 +1,36 @@ +\documentclass{article} +\usepackage{amsthm} +\usepackage{amsmath} +\usepackage{amssymb} +\usepackage{enumerate} +\usepackage{color} +\usepackage[ + colorlinks, + citecolor=black, + filecolor=black, + linkcolor=black, + urlcolor=black + colorlinks=true, + linktoc=all, + linkcolor=blue, + linktocpage=true +]{hyperref} +% \usepackage{minitoc} + + +\newtheorem{defi}{Definition}[section] + +\newtheorem*{exer}{Exercise} +\newtheorem*{exmp}{Example} +\newtheorem*{prf}{Proof} +\newtheorem*{rem}{Remark} +\newtheorem{cly}[defi]{Corollary} +\newtheorem{lem}[defi]{Lemma} +\newtheorem{pro}[defi]{Proposition} +\newtheorem{thm}[defi]{Theorem} + +\begin{document} + +\include{linear-sample} + +\end{document} From c360ddc2e0401d5e13239e994584329c45717fb1 Mon Sep 17 00:00:00 2001 From: lg Date: Sun, 24 Feb 2019 18:35:50 +0800 Subject: [PATCH 03/19] plain34 --- doc/.gitignore | 4 + examples/example_model_plain34.cpp | 148 ++++++++++++++++++++++++++ include/nn/bits/layers/pool.hpp | 6 +- include/nn/bits/ops/conv.hpp | 2 + include/nn/bits/ops/linear_sample.hpp | 38 +++++-- include/nn/bits/ops/pool.hpp | 44 +++++--- 6 files changed, 219 insertions(+), 23 deletions(-) create mode 100644 doc/.gitignore create mode 100644 examples/example_model_plain34.cpp diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 0000000..fb9153b --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1,4 @@ +*.aux +*.pdf +*.log +*.out diff --git a/examples/example_model_plain34.cpp b/examples/example_model_plain34.cpp new file mode 100644 index 0000000..e1ce9b8 --- /dev/null +++ b/examples/example_model_plain34.cpp @@ -0,0 +1,148 @@ +// #define STDNN_OPS_HAVE_CBLAS + +#include +#include + +#include + +#include "utils.hpp" + +using std::experimental::range; + +// pool_max_3x3s2 = Pool(ksize=(3, 3), strides=(2, 2)); +// pool_ave_7x7 = Pool(ksize=(7, 7), strides=(7, 7), algo=MEAN); + +template +class plain34_model +{ + const size_t logits = 1000; + + using relu = nn::ops::pointwise; + using pool_ave = nn::layers::pool; + + using dense = nn::layers::dense<>; + using softmax = nn::layers::activation; + using top = nn::ops::top; + + auto conv1(int d) const + { + using conv_layer = + nn::layers::conv; + using conv_trait = nn::ops::conv_trait; + + return conv_layer( + conv_layer::ksize(7, 7), d, + conv_trait(conv_trait::padding(conv_trait::padding_1d(3, 2), + conv_trait::padding_1d(3, 2)), + conv_trait::stride(2, 2))); + } + + auto pool1() const + { + using pool_max = nn::layers::pool; + const auto padding = pool_max::sample1d_t::auto_padding(3, 2, 1, 112); + return pool_max(pool_max::ksize(3, 3), + pool_max::padding(padding, padding), + pool_max::stride(2, 2)); + } + + auto pool2() const + { + using pool_mean = nn::layers::pool; + return pool_mean(pool_mean::ksize(7, 7)); + } + + using conv_trait = nn::ops::conv_trait; + + auto conv(int d, int s, const conv_trait::padding_1d_t &padding) const + { + using conv_layer = + nn::layers::conv; + return conv_layer(conv_layer::ksize(3, 3), d, + conv_trait(conv_trait::padding(padding, padding), + conv_trait::stride(s, s))); + } + + const std::string prefix_; + + const auto p(const std::string &name) const + { + return nn::ops::readtar(prefix_, name); + } + + public: + const size_t h = 224; + const size_t w = 224; + + plain34_model(const std::string &prefix) : prefix_(prefix) {} + + template + auto operator()(const ttl::tensor_ref &x, int m = 5) const + { + auto conv_layers = nn::models::make_sequential() // + << conv1(64) // + << pool1() // + + << conv(64, 1, conv_trait::padding_1d(1, 1)) + << conv(64, 1, conv_trait::padding_1d(1, 1)) + << conv(64, 1, conv_trait::padding_1d(1, 1)) + << conv(64, 1, conv_trait::padding_1d(1, 1)) + << conv(64, 1, conv_trait::padding_1d(1, 1)) + << conv(64, 1, conv_trait::padding_1d(1, 1)) + + << conv(128, 2, conv_trait::padding_1d(0, 1)) // + << conv(128, 1, conv_trait::padding_1d(1, 1)) // + << conv(128, 1, conv_trait::padding_1d(1, 1)) // + << conv(128, 1, conv_trait::padding_1d(1, 1)) // + << conv(128, 1, conv_trait::padding_1d(1, 1)) // + << conv(128, 1, conv_trait::padding_1d(1, 1)) // + << conv(128, 1, conv_trait::padding_1d(1, 1)) // + << conv(128, 1, conv_trait::padding_1d(1, 1)) // + + << conv(256, 2, conv_trait::padding_1d(0, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + + << conv(512, 2, conv_trait::padding_1d(0, 1)) // + << conv(512, 1, conv_trait::padding_1d(1, 1)) // + << conv(512, 1, conv_trait::padding_1d(1, 1)) // + << conv(512, 1, conv_trait::padding_1d(1, 1)) // + << conv(512, 1, conv_trait::padding_1d(1, 1)) // + << conv(512, 1, conv_trait::padding_1d(1, 1)) // + + << pool2() // + ; + + auto dense_layers = nn::models::make_sequential() // + << dense(logits) // + << softmax() // + ; + + auto y1 = conv_layers(x); + auto y2 = nn::ops::as_matrix<1, 3, ttl::tensor_ref>(*y1); + auto y = dense_layers(y2); + return y; + } +}; + +int main(int argc, char *argv[]) +{ + const std::string home(std::getenv("HOME")); + const std::string prefix = home + "/var/models/vgg16"; + plain34_model model(prefix); + const auto x = ttl::tensor(1, model.h, model.w, 3); + const auto y = model(ref(x)); + PPRINT(x); + PPRINT(*y); + return 0; +} diff --git a/include/nn/bits/layers/pool.hpp b/include/nn/bits/layers/pool.hpp index aaf6352..fb3502c 100644 --- a/include/nn/bits/layers/pool.hpp +++ b/include/nn/bits/layers/pool.hpp @@ -7,17 +7,17 @@ namespace nn::layers { -template +template class pool : public ops::pool_trait { using pool_trait::pool_trait; - using pool_op = nn::ops::pool; + using pool_op = nn::ops::pool; public: template auto operator()(const ttl::tensor_ref &x) const { auto y = ops::new_result>( - pool_op(get_ksize(), get_stride()), x); + pool_op(get_ksize(), get_padding(), get_stride()), x); return make_layer(y); } }; diff --git a/include/nn/bits/ops/conv.hpp b/include/nn/bits/ops/conv.hpp index 06bac1a..b6252c2 100644 --- a/include/nn/bits/ops/conv.hpp +++ b/include/nn/bits/ops/conv.hpp @@ -71,6 +71,8 @@ template <> class conv_trait { using dim_t = size_t; using conv_trait_1d_t = linear_conv_trait; + + public: using padding_1d_t = conv_trait_1d_t::padding_t; protected: diff --git a/include/nn/bits/ops/linear_sample.hpp b/include/nn/bits/ops/linear_sample.hpp index d12c200..21fbf7a 100644 --- a/include/nn/bits/ops/linear_sample.hpp +++ b/include/nn/bits/ops/linear_sample.hpp @@ -1,4 +1,6 @@ #pragma once +#include + #include /*! @@ -56,13 +58,24 @@ template class linear_sample_trait using padding_t = std::experimental::new_type, padding_trait>; - static padding_t padding(dim_t p) { return padding_t(p, p); } + static constexpr padding_t padding(dim_t p) { return padding_t(p, p); } - static padding_t padding(dim_t left, dim_t right) + static constexpr padding_t padding(dim_t left, dim_t right) { return padding_t(left, right); }; + static dim_t patch_size(dim_t k, dim_t r) { return r * (k - 1) + 1; } + + static padding_t auto_padding(dim_t k, dim_t s, dim_t r, dim_t n) + { + const dim_t ps = patch_size(k, r); + // p is the minimal p such that (n + p - ps) == 0 (mod s) + // p == ps - n (mod s) + const dim_t p = (ps + s - (n % s)) % s; + return padding_t(p / 2, p - p / 2); + } + public: linear_sample_trait(dim_t ksize) : linear_sample_trait(ksize, default_stride) @@ -110,14 +123,16 @@ template class linear_sample_trait dim_t get_stride() const { return stride_; } + padding_t get_padding() const { return padding(pad_l_, pad_r_); } + /*! Compute the output size from input size. */ dim_t operator()(dim_t n) const { const dim_t n_padded = n + pad_l_ + pad_r_; - const dim_t patch_size = rate_ * (ksize_ - 1) + 1; - contract_assert(n_padded >= patch_size); - contract_assert((n_padded - patch_size) % stride_ == 0); - return (n_padded - patch_size) / stride_ + 1; + const dim_t ps = patch_size(ksize_, rate_); + contract_assert(n_padded >= ps); + contract_assert((n_padded - ps) % stride_ == 0); + return (n_padded - ps) / stride_ + 1; } /*! Compute the index $i^\prime$ of padded input from the output index and @@ -144,6 +159,17 @@ template class linear_sample_trait } dim_t unpad(dim_t i) const { return i - pad_l_; } + + std::string to_string() const + { + std::stringstream ss; + ss << ""; + return ss.str(); + } }; namespace internal diff --git a/include/nn/bits/ops/pool.hpp b/include/nn/bits/ops/pool.hpp index c3eb5f2..d08ba72 100644 --- a/include/nn/bits/ops/pool.hpp +++ b/include/nn/bits/ops/pool.hpp @@ -13,22 +13,21 @@ template class pool_trait; template <> class pool_trait { protected: - struct padding_trait; struct ksize_trait; struct stride_trait; - using padding_t = std::experimental::new_type, padding_trait>; + using dim_t = size_t; + using sample1d_t_ = linear_sample_trait; + + using padding_1d_t = typename sample1d_t_::padding_t; + using padding_t = std::array; using ksize_t = std::experimental::new_type, ksize_trait>; using stride_t = std::experimental::new_type, stride_trait>; - static constexpr auto default_padding = padding_t(0, 0); static constexpr auto default_ksize = ksize_t(2, 2); - using dim_t = size_t; - using sample_t = linear_sample_trait; - - const sample_t h_sample_; - const sample_t w_sample_; + const sample1d_t_ h_sample_; + const sample1d_t_ w_sample_; ksize_t get_ksize() const { @@ -40,10 +39,27 @@ template <> class pool_trait return stride_t(h_sample_.get_stride(), w_sample_.get_stride()); } + padding_t get_padding() const + { + return padding(h_sample_.get_padding(), w_sample_.get_padding()); + } + public: - static padding_t padding(dim_t r, dim_t s) { return padding_t(r, s); }; - static ksize_t ksize(dim_t r, dim_t s) { return ksize_t(r, s); }; - static stride_t stride(dim_t r, dim_t s) { return stride_t(r, s); }; + using sample1d_t = sample1d_t_; + + static padding_t padding(const padding_1d_t &r, const padding_1d_t &s) + { + return {r, s}; + }; + + static padding_t padding(dim_t r, dim_t s) + { + return padding(sample1d_t::padding(r), sample1d_t::padding(s)); + } + + static ksize_t ksize(dim_t r, dim_t s) { return ksize_t(r, s); } + + static stride_t stride(dim_t r, dim_t s) { return stride_t(r, s); } pool_trait() : pool_trait(default_ksize) {} @@ -53,7 +69,7 @@ template <> class pool_trait } pool_trait(const ksize_t &ksize, const stride_t &stride) - : pool_trait(ksize, default_padding, stride) + : pool_trait(ksize, padding(0, 0), stride) { } @@ -64,8 +80,8 @@ template <> class pool_trait pool_trait(const ksize_t &ksize, const padding_t &padding, const stride_t &stride) - : h_sample_(ksize.dims[0], stride.dims[0], 1, padding.dims[0]), - w_sample_(ksize.dims[1], stride.dims[1], 1, padding.dims[1]) + : h_sample_(ksize.dims[0], stride.dims[0], 1, std::get<0>(padding)), + w_sample_(ksize.dims[1], stride.dims[1], 1, std::get<1>(padding)) { } From 0cc42586651bd70402b9e125e6bb9b5f11c51cf8 Mon Sep 17 00:00:00 2001 From: lg Date: Mon, 25 Feb 2019 06:00:29 +0800 Subject: [PATCH 04/19] same_padding --- examples/example_model_plain34.cpp | 2 +- include/nn/bits/ops/linear_sample.hpp | 41 +++++++++++---------------- tests/test_linear_sample.cpp | 29 +++++++++++++++++++ 3 files changed, 47 insertions(+), 25 deletions(-) diff --git a/examples/example_model_plain34.cpp b/examples/example_model_plain34.cpp index e1ce9b8..5f559cd 100644 --- a/examples/example_model_plain34.cpp +++ b/examples/example_model_plain34.cpp @@ -41,7 +41,7 @@ class plain34_model auto pool1() const { using pool_max = nn::layers::pool; - const auto padding = pool_max::sample1d_t::auto_padding(3, 2, 1, 112); + const auto padding = pool_max::sample1d_t::valid_padding(3, 2, 1, 112); return pool_max(pool_max::ksize(3, 3), pool_max::padding(padding, padding), pool_max::stride(2, 2)); diff --git a/include/nn/bits/ops/linear_sample.hpp b/include/nn/bits/ops/linear_sample.hpp index 21fbf7a..0de72ed 100644 --- a/include/nn/bits/ops/linear_sample.hpp +++ b/include/nn/bits/ops/linear_sample.hpp @@ -4,27 +4,6 @@ #include /*! -\begin{definition} -A Linear sample is a map that maps a sequence of length $n$ to a sequence of -length $m$. -\end{definition} - - -The sample takes the following steps -\begin{itemize} -\item The input sequence $x[n]$ is padded to $x^\prime[pad_l + n + pad_r]$ by -prepending $pad_l$ zero elements and appending $pad_r$ zero elements. - -\item The kernel (filter) $y[k]$ is extended to $y^\prime[rate * (k - 1) + 1]$ -by inserting $rate - 1$ zero elements to adjacent elemnts. - -\item The padded input $x^\prime$ and the extended kernel $y^\prime$ takes a -valid convolution with stride $s$, resulting the output sequence $Z[m]$, -where $m = (n^\prime - k^prime) / s + 1$, and $s \mid n^\prime - k^prime$ should -be granted. -\end{itemize} - - e.g. 012345678901234567890123456789 @@ -67,13 +46,27 @@ template class linear_sample_trait static dim_t patch_size(dim_t k, dim_t r) { return r * (k - 1) + 1; } - static padding_t auto_padding(dim_t k, dim_t s, dim_t r, dim_t n) + static padding_t even_padding(dim_t p) + { + return padding_t(p / 2, p - p / 2); + } + + static padding_t valid_padding(dim_t k, dim_t s, dim_t r, dim_t n) { const dim_t ps = patch_size(k, r); // p is the minimal p such that (n + p - ps) == 0 (mod s) // p == ps - n (mod s) - const dim_t p = (ps + s - (n % s)) % s; - return padding_t(p / 2, p - p / 2); + return even_padding((ps + s - (n % s)) % s); + } + + static padding_t same_padding(dim_t k, dim_t s, dim_t r, dim_t n) + { + const dim_t ps = patch_size(k, r); + const dim_t n0 = n % s; + // p = ps - s - (n % s) + // TODO: support negative padding + contract_assert(ps >= s + n0); + return even_padding(ps - s - n0); } public: diff --git a/tests/test_linear_sample.cpp b/tests/test_linear_sample.cpp index 2c60a08..b2e3ce5 100644 --- a/tests/test_linear_sample.cpp +++ b/tests/test_linear_sample.cpp @@ -74,3 +74,32 @@ TEST(linear_sample_test, test_2) ASSERT_EQ(y, nn::shape<3>(9, 7, 5)); } } + +template +void test_valid_padding_ksize_3(dim_t n, dim_t s, dim_t pad_l, dim_t pad_r) +{ + using sample_t = nn::ops::linear_sample_trait; + const auto padding = sample_t::valid_padding(3, s, 1, n); + const auto [u, v] = padding.dims; + ASSERT_EQ(u, pad_l); + ASSERT_EQ(v, pad_r); +} + +template +void test_same_padding_ksize_3(dim_t n, dim_t s, dim_t pad_l, dim_t pad_r) +{ + using sample_t = nn::ops::linear_sample_trait; + const auto padding = sample_t::same_padding(3, s, 1, n); + const auto [u, v] = padding.dims; + ASSERT_EQ(u, pad_l); + ASSERT_EQ(v, pad_r); +} + +TEST(linear_sample_test, test_auto_padding) +{ + test_valid_padding_ksize_3(56, 1, 0, 0); + test_valid_padding_ksize_3(56, 2, 0, 1); + + test_same_padding_ksize_3(56, 1, 1, 1); + test_same_padding_ksize_3(112, 2, 0, 1); +} From b21a4b3207909d49e09a9a4b774d3a9e2e179865 Mon Sep 17 00:00:00 2001 From: lg Date: Mon, 25 Feb 2019 06:09:48 +0800 Subject: [PATCH 05/19] remove debug code --- examples/example_model_plain34.cpp | 2 +- include/nn/bits/ops/linear_sample.hpp | 13 ------------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/examples/example_model_plain34.cpp b/examples/example_model_plain34.cpp index 5f559cd..b81e5d6 100644 --- a/examples/example_model_plain34.cpp +++ b/examples/example_model_plain34.cpp @@ -41,7 +41,7 @@ class plain34_model auto pool1() const { using pool_max = nn::layers::pool; - const auto padding = pool_max::sample1d_t::valid_padding(3, 2, 1, 112); + const auto padding = pool_max::sample1d_t::same_padding(3, 2, 1, 112); return pool_max(pool_max::ksize(3, 3), pool_max::padding(padding, padding), pool_max::stride(2, 2)); diff --git a/include/nn/bits/ops/linear_sample.hpp b/include/nn/bits/ops/linear_sample.hpp index 0de72ed..007ee2f 100644 --- a/include/nn/bits/ops/linear_sample.hpp +++ b/include/nn/bits/ops/linear_sample.hpp @@ -1,6 +1,4 @@ #pragma once -#include - #include /*! @@ -152,17 +150,6 @@ template class linear_sample_trait } dim_t unpad(dim_t i) const { return i - pad_l_; } - - std::string to_string() const - { - std::stringstream ss; - ss << ""; - return ss.str(); - } }; namespace internal From 28eda06a400c638dee285e71bf0935c3c6854e98 Mon Sep 17 00:00:00 2001 From: lg Date: Mon, 25 Feb 2019 12:30:26 +0800 Subject: [PATCH 06/19] flatten layer --- examples/example_model_plain34.cpp | 95 +++++++++++++++--------------- include/nn/bits/layers/reshape.hpp | 20 +++++++ include/nn/bits/ops/reshape.hpp | 19 ++++++ include/nn/layers | 1 + 4 files changed, 86 insertions(+), 49 deletions(-) create mode 100644 include/nn/bits/layers/reshape.hpp diff --git a/examples/example_model_plain34.cpp b/examples/example_model_plain34.cpp index b81e5d6..f349030 100644 --- a/examples/example_model_plain34.cpp +++ b/examples/example_model_plain34.cpp @@ -21,6 +21,7 @@ class plain34_model using relu = nn::ops::pointwise; using pool_ave = nn::layers::pool; + using flatten = nn::layers::flatten<1, 3>; using dense = nn::layers::dense<>; using softmax = nn::layers::activation; using top = nn::ops::top; @@ -80,57 +81,53 @@ class plain34_model template auto operator()(const ttl::tensor_ref &x, int m = 5) const { - auto conv_layers = nn::models::make_sequential() // - << conv1(64) // - << pool1() // - - << conv(64, 1, conv_trait::padding_1d(1, 1)) - << conv(64, 1, conv_trait::padding_1d(1, 1)) - << conv(64, 1, conv_trait::padding_1d(1, 1)) - << conv(64, 1, conv_trait::padding_1d(1, 1)) - << conv(64, 1, conv_trait::padding_1d(1, 1)) - << conv(64, 1, conv_trait::padding_1d(1, 1)) - - << conv(128, 2, conv_trait::padding_1d(0, 1)) // - << conv(128, 1, conv_trait::padding_1d(1, 1)) // - << conv(128, 1, conv_trait::padding_1d(1, 1)) // - << conv(128, 1, conv_trait::padding_1d(1, 1)) // - << conv(128, 1, conv_trait::padding_1d(1, 1)) // - << conv(128, 1, conv_trait::padding_1d(1, 1)) // - << conv(128, 1, conv_trait::padding_1d(1, 1)) // - << conv(128, 1, conv_trait::padding_1d(1, 1)) // - - << conv(256, 2, conv_trait::padding_1d(0, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - - << conv(512, 2, conv_trait::padding_1d(0, 1)) // - << conv(512, 1, conv_trait::padding_1d(1, 1)) // - << conv(512, 1, conv_trait::padding_1d(1, 1)) // - << conv(512, 1, conv_trait::padding_1d(1, 1)) // - << conv(512, 1, conv_trait::padding_1d(1, 1)) // - << conv(512, 1, conv_trait::padding_1d(1, 1)) // - - << pool2() // + auto layers = nn::models::make_sequential() // + << conv1(64) // + << pool1() // + + << conv(64, 1, conv_trait::padding_1d(1, 1)) + << conv(64, 1, conv_trait::padding_1d(1, 1)) + << conv(64, 1, conv_trait::padding_1d(1, 1)) + << conv(64, 1, conv_trait::padding_1d(1, 1)) + << conv(64, 1, conv_trait::padding_1d(1, 1)) + << conv(64, 1, conv_trait::padding_1d(1, 1)) + + << conv(128, 2, conv_trait::padding_1d(0, 1)) // + << conv(128, 1, conv_trait::padding_1d(1, 1)) // + << conv(128, 1, conv_trait::padding_1d(1, 1)) // + << conv(128, 1, conv_trait::padding_1d(1, 1)) // + << conv(128, 1, conv_trait::padding_1d(1, 1)) // + << conv(128, 1, conv_trait::padding_1d(1, 1)) // + << conv(128, 1, conv_trait::padding_1d(1, 1)) // + << conv(128, 1, conv_trait::padding_1d(1, 1)) // + + << conv(256, 2, conv_trait::padding_1d(0, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + << conv(256, 1, conv_trait::padding_1d(1, 1)) // + + << conv(512, 2, conv_trait::padding_1d(0, 1)) // + << conv(512, 1, conv_trait::padding_1d(1, 1)) // + << conv(512, 1, conv_trait::padding_1d(1, 1)) // + << conv(512, 1, conv_trait::padding_1d(1, 1)) // + << conv(512, 1, conv_trait::padding_1d(1, 1)) // + << conv(512, 1, conv_trait::padding_1d(1, 1)) // + + << pool2() // + << flatten() // + << dense(logits) // + << softmax() // ; - auto dense_layers = nn::models::make_sequential() // - << dense(logits) // - << softmax() // - ; - - auto y1 = conv_layers(x); - auto y2 = nn::ops::as_matrix<1, 3, ttl::tensor_ref>(*y1); - auto y = dense_layers(y2); + auto y = layers(x); return y; } }; diff --git a/include/nn/bits/layers/reshape.hpp b/include/nn/bits/layers/reshape.hpp new file mode 100644 index 0000000..9d17a71 --- /dev/null +++ b/include/nn/bits/layers/reshape.hpp @@ -0,0 +1,20 @@ +#pragma once +#include +#include +#include + +namespace nn::layers +{ +template class flatten +{ + using op = ops::flatten; + + public: + template + auto operator()(const ttl::tensor_ref &x) const + { + auto y = nn::ops::new_result>(op(), x); + return nn::layers::make_layer(y); + } +}; +} // namespace nn::layers diff --git a/include/nn/bits/ops/reshape.hpp b/include/nn/bits/ops/reshape.hpp index 6aa78d6..b427520 100644 --- a/include/nn/bits/ops/reshape.hpp +++ b/include/nn/bits/ops/reshape.hpp @@ -14,4 +14,23 @@ T as_matrix(const T1 &t) return T(t.data(), as_mat_shape(t.shape())); } +// TODO: make it generic: template +template class flatten +{ + static constexpr ttl::rank_t r = p + q; + + public: + shape<2> operator()(const shape &x) const + { + return as_mat_shape(x); + } + + template + void operator()(const ttl::tensor_ref &y, + const ttl::tensor_view &x) const + { + std::copy(x.data(), x.data() + x.shape().size(), y.data()); + } +}; + } // namespace nn::ops diff --git a/include/nn/layers b/include/nn/layers index f4e15c6..6a2ff5c 100644 --- a/include/nn/layers +++ b/include/nn/layers @@ -8,3 +8,4 @@ #include #include #include +#include From 4bf8fda27176bb4495795967f2ec1e00335f37c6 Mon Sep 17 00:00:00 2001 From: lg Date: Mon, 25 Feb 2019 12:40:28 +0800 Subject: [PATCH 07/19] bn --- examples/example_model_plain34.cpp | 102 ++++++++++++++--------------- 1 file changed, 48 insertions(+), 54 deletions(-) diff --git a/examples/example_model_plain34.cpp b/examples/example_model_plain34.cpp index f349030..22ed1a5 100644 --- a/examples/example_model_plain34.cpp +++ b/examples/example_model_plain34.cpp @@ -7,11 +7,6 @@ #include "utils.hpp" -using std::experimental::range; - -// pool_max_3x3s2 = Pool(ksize=(3, 3), strides=(2, 2)); -// pool_ave_7x7 = Pool(ksize=(7, 7), strides=(7, 7), algo=MEAN); - template class plain34_model @@ -19,12 +14,11 @@ class plain34_model const size_t logits = 1000; using relu = nn::ops::pointwise; - using pool_ave = nn::layers::pool; + using bn_layer = nn::layers::batch_norm; using flatten = nn::layers::flatten<1, 3>; using dense = nn::layers::dense<>; using softmax = nn::layers::activation; - using top = nn::ops::top; auto conv1(int d) const { @@ -58,8 +52,7 @@ class plain34_model auto conv(int d, int s, const conv_trait::padding_1d_t &padding) const { - using conv_layer = - nn::layers::conv; + using conv_layer = nn::layers::conv; return conv_layer(conv_layer::ksize(3, 3), d, conv_trait(conv_trait::padding(padding, padding), conv_trait::stride(s, s))); @@ -81,50 +74,51 @@ class plain34_model template auto operator()(const ttl::tensor_ref &x, int m = 5) const { - auto layers = nn::models::make_sequential() // - << conv1(64) // - << pool1() // - - << conv(64, 1, conv_trait::padding_1d(1, 1)) - << conv(64, 1, conv_trait::padding_1d(1, 1)) - << conv(64, 1, conv_trait::padding_1d(1, 1)) - << conv(64, 1, conv_trait::padding_1d(1, 1)) - << conv(64, 1, conv_trait::padding_1d(1, 1)) - << conv(64, 1, conv_trait::padding_1d(1, 1)) - - << conv(128, 2, conv_trait::padding_1d(0, 1)) // - << conv(128, 1, conv_trait::padding_1d(1, 1)) // - << conv(128, 1, conv_trait::padding_1d(1, 1)) // - << conv(128, 1, conv_trait::padding_1d(1, 1)) // - << conv(128, 1, conv_trait::padding_1d(1, 1)) // - << conv(128, 1, conv_trait::padding_1d(1, 1)) // - << conv(128, 1, conv_trait::padding_1d(1, 1)) // - << conv(128, 1, conv_trait::padding_1d(1, 1)) // - - << conv(256, 2, conv_trait::padding_1d(0, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - << conv(256, 1, conv_trait::padding_1d(1, 1)) // - - << conv(512, 2, conv_trait::padding_1d(0, 1)) // - << conv(512, 1, conv_trait::padding_1d(1, 1)) // - << conv(512, 1, conv_trait::padding_1d(1, 1)) // - << conv(512, 1, conv_trait::padding_1d(1, 1)) // - << conv(512, 1, conv_trait::padding_1d(1, 1)) // - << conv(512, 1, conv_trait::padding_1d(1, 1)) // - - << pool2() // - << flatten() // - << dense(logits) // - << softmax() // + auto layers = + nn::models::make_sequential() // + << conv1(64) // + << pool1() // + + << conv(64, 1, conv_trait::padding_1d(1, 1)) << bn_layer() + << conv(64, 1, conv_trait::padding_1d(1, 1)) << bn_layer() + << conv(64, 1, conv_trait::padding_1d(1, 1)) << bn_layer() + << conv(64, 1, conv_trait::padding_1d(1, 1)) << bn_layer() + << conv(64, 1, conv_trait::padding_1d(1, 1)) << bn_layer() + << conv(64, 1, conv_trait::padding_1d(1, 1)) << bn_layer() + + << conv(128, 2, conv_trait::padding_1d(0, 1)) << bn_layer() // + << conv(128, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + << conv(128, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + << conv(128, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + << conv(128, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + << conv(128, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + << conv(128, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + << conv(128, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + + << conv(256, 2, conv_trait::padding_1d(0, 1)) << bn_layer() // + << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + + << conv(512, 2, conv_trait::padding_1d(0, 1)) << bn_layer() // + << conv(512, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + << conv(512, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + << conv(512, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + << conv(512, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + << conv(512, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // + + << pool2() // + << flatten() // + << dense(logits) // + << softmax() // ; auto y = layers(x); @@ -135,7 +129,7 @@ class plain34_model int main(int argc, char *argv[]) { const std::string home(std::getenv("HOME")); - const std::string prefix = home + "/var/models/vgg16"; + const std::string prefix = home + "/var/models/resnet"; plain34_model model(prefix); const auto x = ttl::tensor(1, model.h, model.w, 3); const auto y = model(ref(x)); From ede3a58d9c227eba657a2c8ce6f96ace6ce3a11f Mon Sep 17 00:00:00 2001 From: lg Date: Thu, 28 Feb 2019 05:29:57 +0800 Subject: [PATCH 08/19] new padding constructor --- examples/example_model_plain34.cpp | 99 +++++++++++++-------------- examples/utils.hpp | 2 +- include/nn/bits/ops/linear_sample.hpp | 12 ++++ tests/test_linear_sample.cpp | 9 +++ 4 files changed, 71 insertions(+), 51 deletions(-) diff --git a/examples/example_model_plain34.cpp b/examples/example_model_plain34.cpp index 22ed1a5..2168f0f 100644 --- a/examples/example_model_plain34.cpp +++ b/examples/example_model_plain34.cpp @@ -7,6 +7,8 @@ #include "utils.hpp" +using nn::ops::pad; + template class plain34_model @@ -26,11 +28,9 @@ class plain34_model nn::layers::conv; using conv_trait = nn::ops::conv_trait; - return conv_layer( - conv_layer::ksize(7, 7), d, - conv_trait(conv_trait::padding(conv_trait::padding_1d(3, 2), - conv_trait::padding_1d(3, 2)), - conv_trait::stride(2, 2))); + return conv_layer(conv_layer::ksize(7, 7), d, + conv_trait(conv_trait::padding(pad(3, 2), pad(3, 2)), + conv_trait::stride(2, 2))); } auto pool1() const @@ -74,51 +74,50 @@ class plain34_model template auto operator()(const ttl::tensor_ref &x, int m = 5) const { - auto layers = - nn::models::make_sequential() // - << conv1(64) // - << pool1() // - - << conv(64, 1, conv_trait::padding_1d(1, 1)) << bn_layer() - << conv(64, 1, conv_trait::padding_1d(1, 1)) << bn_layer() - << conv(64, 1, conv_trait::padding_1d(1, 1)) << bn_layer() - << conv(64, 1, conv_trait::padding_1d(1, 1)) << bn_layer() - << conv(64, 1, conv_trait::padding_1d(1, 1)) << bn_layer() - << conv(64, 1, conv_trait::padding_1d(1, 1)) << bn_layer() - - << conv(128, 2, conv_trait::padding_1d(0, 1)) << bn_layer() // - << conv(128, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - << conv(128, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - << conv(128, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - << conv(128, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - << conv(128, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - << conv(128, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - << conv(128, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - - << conv(256, 2, conv_trait::padding_1d(0, 1)) << bn_layer() // - << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - << conv(256, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - - << conv(512, 2, conv_trait::padding_1d(0, 1)) << bn_layer() // - << conv(512, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - << conv(512, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - << conv(512, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - << conv(512, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - << conv(512, 1, conv_trait::padding_1d(1, 1)) << bn_layer() // - - << pool2() // - << flatten() // - << dense(logits) // - << softmax() // + auto layers = nn::models::make_sequential() // + << conv1(64) // + << pool1() // + + << conv(64, 1, pad(1, 1)) << bn_layer() // + << conv(64, 1, pad(1, 1)) << bn_layer() + << conv(64, 1, pad(1, 1)) << bn_layer() + << conv(64, 1, pad(1, 1)) << bn_layer() + << conv(64, 1, pad(1, 1)) << bn_layer() + << conv(64, 1, pad(1, 1)) << bn_layer() + + << conv(128, 2, pad(0, 1)) << bn_layer() // + << conv(128, 1, pad(1, 1)) << bn_layer() // + << conv(128, 1, pad(1, 1)) << bn_layer() // + << conv(128, 1, pad(1, 1)) << bn_layer() // + << conv(128, 1, pad(1, 1)) << bn_layer() // + << conv(128, 1, pad(1, 1)) << bn_layer() // + << conv(128, 1, pad(1, 1)) << bn_layer() // + << conv(128, 1, pad(1, 1)) << bn_layer() // + + << conv(256, 2, pad(0, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + + << conv(512, 2, pad(0, 1)) << bn_layer() // + << conv(512, 1, pad(1, 1)) << bn_layer() // + << conv(512, 1, pad(1, 1)) << bn_layer() // + << conv(512, 1, pad(1, 1)) << bn_layer() // + << conv(512, 1, pad(1, 1)) << bn_layer() // + << conv(512, 1, pad(1, 1)) << bn_layer() // + + << pool2() // + << flatten() // + << dense(logits) // + << softmax() // ; auto y = layers(x); diff --git a/examples/utils.hpp b/examples/utils.hpp index 44e4b0d..e254fa5 100644 --- a/examples/utils.hpp +++ b/examples/utils.hpp @@ -21,7 +21,7 @@ void show_signature(const T &y, const Ts &... x) { std::array args({show_shape(x.shape())...}); std::string ss; - for (auto p : args) { + for (const auto& p : args) { if (!ss.empty()) { ss += ", "; } ss += p; } diff --git a/include/nn/bits/ops/linear_sample.hpp b/include/nn/bits/ops/linear_sample.hpp index 007ee2f..dd7b391 100644 --- a/include/nn/bits/ops/linear_sample.hpp +++ b/include/nn/bits/ops/linear_sample.hpp @@ -152,6 +152,18 @@ template class linear_sample_trait dim_t unpad(dim_t i) const { return i - pad_l_; } }; +template +constexpr typename linear_sample_trait::padding_t pad(dim_t p) +{ + return typename linear_sample_trait::padding_t(p, p); +} + +template +constexpr typename linear_sample_trait::padding_t pad(dim_t l, dim_t r) +{ + return typename linear_sample_trait::padding_t(l, r); +} + namespace internal { template static T constant(const T &x) { return x; } diff --git a/tests/test_linear_sample.cpp b/tests/test_linear_sample.cpp index b2e3ce5..51b9fbd 100644 --- a/tests/test_linear_sample.cpp +++ b/tests/test_linear_sample.cpp @@ -103,3 +103,12 @@ TEST(linear_sample_test, test_auto_padding) test_same_padding_ksize_3(56, 1, 1, 1); test_same_padding_ksize_3(112, 2, 0, 1); } + +TEST(linear_sample_test, test_pad) +{ + using nn::ops::pad; + pad(1); + pad(2); + pad(1, 2); + pad(0, 1); +} From 38dbe5f6ba21adf2a8ad44c71f9f986e890cff87 Mon Sep 17 00:00:00 2001 From: lg Date: Thu, 28 Feb 2019 06:08:17 +0800 Subject: [PATCH 09/19] fix build --- examples/example_model_plain34.cpp | 78 +++++++++++++-------------- include/nn/bits/ops/conv.hpp | 2 +- include/nn/bits/ops/im2col.hpp | 3 +- include/nn/bits/ops/linear_sample.hpp | 4 ++ include/nn/bits/ops/pool.hpp | 2 +- 5 files changed, 47 insertions(+), 42 deletions(-) diff --git a/examples/example_model_plain34.cpp b/examples/example_model_plain34.cpp index 2168f0f..1ba9164 100644 --- a/examples/example_model_plain34.cpp +++ b/examples/example_model_plain34.cpp @@ -27,10 +27,10 @@ class plain34_model using conv_layer = nn::layers::conv; using conv_trait = nn::ops::conv_trait; - - return conv_layer(conv_layer::ksize(7, 7), d, - conv_trait(conv_trait::padding(pad(3, 2), pad(3, 2)), - conv_trait::stride(2, 2))); + const conv_trait::padding_1d_t p = pad(3, 2); + return conv_layer( + conv_layer::ksize(7, 7), d, + conv_trait(conv_trait::padding(p, p), conv_trait::stride(2, 2))); } auto pool1() const @@ -78,41 +78,41 @@ class plain34_model << conv1(64) // << pool1() // - << conv(64, 1, pad(1, 1)) << bn_layer() // - << conv(64, 1, pad(1, 1)) << bn_layer() - << conv(64, 1, pad(1, 1)) << bn_layer() - << conv(64, 1, pad(1, 1)) << bn_layer() - << conv(64, 1, pad(1, 1)) << bn_layer() - << conv(64, 1, pad(1, 1)) << bn_layer() - - << conv(128, 2, pad(0, 1)) << bn_layer() // - << conv(128, 1, pad(1, 1)) << bn_layer() // - << conv(128, 1, pad(1, 1)) << bn_layer() // - << conv(128, 1, pad(1, 1)) << bn_layer() // - << conv(128, 1, pad(1, 1)) << bn_layer() // - << conv(128, 1, pad(1, 1)) << bn_layer() // - << conv(128, 1, pad(1, 1)) << bn_layer() // - << conv(128, 1, pad(1, 1)) << bn_layer() // - - << conv(256, 2, pad(0, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - - << conv(512, 2, pad(0, 1)) << bn_layer() // - << conv(512, 1, pad(1, 1)) << bn_layer() // - << conv(512, 1, pad(1, 1)) << bn_layer() // - << conv(512, 1, pad(1, 1)) << bn_layer() // - << conv(512, 1, pad(1, 1)) << bn_layer() // - << conv(512, 1, pad(1, 1)) << bn_layer() // + << conv(64, 1, pad(1, 1)) << bn_layer() // + << conv(64, 1, pad(1, 1)) << bn_layer() + << conv(64, 1, pad(1, 1)) << bn_layer() + << conv(64, 1, pad(1, 1)) << bn_layer() + << conv(64, 1, pad(1, 1)) << bn_layer() + << conv(64, 1, pad(1, 1)) << bn_layer() + + << conv(128, 2, pad(0, 1)) << bn_layer() // + << conv(128, 1, pad(1, 1)) << bn_layer() // + << conv(128, 1, pad(1, 1)) << bn_layer() // + << conv(128, 1, pad(1, 1)) << bn_layer() // + << conv(128, 1, pad(1, 1)) << bn_layer() // + << conv(128, 1, pad(1, 1)) << bn_layer() // + << conv(128, 1, pad(1, 1)) << bn_layer() // + << conv(128, 1, pad(1, 1)) << bn_layer() // + + << conv(256, 2, pad(0, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + << conv(256, 1, pad(1, 1)) << bn_layer() // + + << conv(512, 2, pad(0, 1)) << bn_layer() // + << conv(512, 1, pad(1, 1)) << bn_layer() // + << conv(512, 1, pad(1, 1)) << bn_layer() // + << conv(512, 1, pad(1, 1)) << bn_layer() // + << conv(512, 1, pad(1, 1)) << bn_layer() // + << conv(512, 1, pad(1, 1)) << bn_layer() // << pool2() // << flatten() // diff --git a/include/nn/bits/ops/conv.hpp b/include/nn/bits/ops/conv.hpp index b6252c2..ef69bb9 100644 --- a/include/nn/bits/ops/conv.hpp +++ b/include/nn/bits/ops/conv.hpp @@ -69,7 +69,7 @@ template class conv_trait; template <> class conv_trait { - using dim_t = size_t; + using dim_t = uint32_t; using conv_trait_1d_t = linear_conv_trait; public: diff --git a/include/nn/bits/ops/im2col.hpp b/include/nn/bits/ops/im2col.hpp index cedfdac..ccc5058 100644 --- a/include/nn/bits/ops/im2col.hpp +++ b/include/nn/bits/ops/im2col.hpp @@ -8,7 +8,8 @@ namespace nn::ops { template class im2col_trait; -template <> class im2col_trait : public multi_linear_sample_trait<2, size_t> +template <> +class im2col_trait : public multi_linear_sample_trait<2, uint32_t> { using multi_linear_sample_trait::multi_linear_sample_trait; }; diff --git a/include/nn/bits/ops/linear_sample.hpp b/include/nn/bits/ops/linear_sample.hpp index dd7b391..1dae929 100644 --- a/include/nn/bits/ops/linear_sample.hpp +++ b/include/nn/bits/ops/linear_sample.hpp @@ -16,6 +16,10 @@ e.g. namespace nn::ops { +struct fixed_padding; + +template +class basic_linear_sample_trait; template class linear_sample_trait { diff --git a/include/nn/bits/ops/pool.hpp b/include/nn/bits/ops/pool.hpp index d08ba72..cffb2dd 100644 --- a/include/nn/bits/ops/pool.hpp +++ b/include/nn/bits/ops/pool.hpp @@ -16,7 +16,7 @@ template <> class pool_trait struct ksize_trait; struct stride_trait; - using dim_t = size_t; + using dim_t = uint32_t; using sample1d_t_ = linear_sample_trait; using padding_1d_t = typename sample1d_t_::padding_t; From b600fcc53acce0b7faef11bfc5570d27b9274a7a Mon Sep 17 00:00:00 2001 From: lg Date: Tue, 5 Mar 2019 19:58:01 +0800 Subject: [PATCH 10/19] padding_policy traits --- .gitignore | 3 ++- doc/Makefile | 2 ++ include/nn/bits/ops/linear_sample.hpp | 20 ++++++++++++++++++-- tests/test_linear_sample.cpp | 3 ++- 4 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 doc/Makefile diff --git a/.gitignore b/.gitignore index 502ae5e..12bee65 100644 --- a/.gitignore +++ b/.gitignore @@ -3,9 +3,11 @@ *.png /3rdparty /bin +/build /cmake-build /lib /local +/Makefile /release cmake_install.cmake CMakeCache.txt @@ -16,5 +18,4 @@ CPackSourceConfig.cmake CTestTestfile.cmake install_manifest.txt libstdtensor-prefix -Makefile Testing diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000..9426424 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,2 @@ +pdf: + pdflatex nn.tex diff --git a/include/nn/bits/ops/linear_sample.hpp b/include/nn/bits/ops/linear_sample.hpp index 1dae929..700cb33 100644 --- a/include/nn/bits/ops/linear_sample.hpp +++ b/include/nn/bits/ops/linear_sample.hpp @@ -17,11 +17,13 @@ e.g. namespace nn::ops { struct fixed_padding; +struct valid_padding; +struct same_padding; template -class basic_linear_sample_trait; +class linear_sample_trait; -template class linear_sample_trait +template class linear_sample_trait { const dim_t pad_l_; // TODO: make it template parameter const dim_t pad_r_; // TODO: make it template parameter @@ -156,6 +158,20 @@ template class linear_sample_trait dim_t unpad(dim_t i) const { return i - pad_l_; } }; +template class linear_sample_trait +{ + const dim_t rate_; + const dim_t stride_; + const dim_t ksize_; +}; + +template class linear_sample_trait +{ + const dim_t rate_; + const dim_t stride_; + const dim_t ksize_; +}; + template constexpr typename linear_sample_trait::padding_t pad(dim_t p) { diff --git a/tests/test_linear_sample.cpp b/tests/test_linear_sample.cpp index 51b9fbd..5720ac7 100644 --- a/tests/test_linear_sample.cpp +++ b/tests/test_linear_sample.cpp @@ -7,7 +7,8 @@ void test_linear_sample_ksr_nm(int ksize, int stride, int rate, int n, int m) { - nn::ops::linear_sample_trait sample(ksize, stride, rate); + using sample_t = nn::ops::linear_sample_trait; + sample_t sample(ksize, stride, rate); ASSERT_EQ(sample(n), m); ASSERT_EQ(sample(0, 0), 0); From aa02498e974422805aa309ac0faffa9c673f4e77 Mon Sep 17 00:00:00 2001 From: lg Date: Tue, 5 Mar 2019 20:03:59 +0800 Subject: [PATCH 11/19] update clang-format --- .clang-format | 36 +++++++++++++++++++++++++------- examples/example_1.cpp | 3 ++- examples/example_layer_mlp.cpp | 3 ++- examples/example_layer_vgg16.cpp | 2 +- examples/example_mlp.cpp | 3 ++- examples/example_mnist.cpp | 3 ++- examples/example_model_vgg16.cpp | 2 +- 7 files changed, 39 insertions(+), 13 deletions(-) diff --git a/.clang-format b/.clang-format index bf55d3b..d894970 100644 --- a/.clang-format +++ b/.clang-format @@ -1,18 +1,40 @@ # https://clang.llvm.org/docs/ClangFormatStyleOptions.html # clang-format version 6.0.0 (tags/RELEASE_600/final) +# AlignConsecutiveAssignments: true AllowShortBlocksOnASingleLine: true AllowShortIfStatementsOnASingleLine: true AllowShortLoopsOnASingleLine: true - -IndentWidth: 4 BreakBeforeBraces: Linux -SortIncludes: true -# IncludeBlocks: true - ColumnLimit: 80 -SpacesBeforeTrailingComments: 2 - ConstructorInitializerAllOnOneLineOrOnePerLine: true +DerivePointerAlignment: false +IncludeBlocks: Regroup +IndentPPDirectives: AfterHash +IndentWidth: 4 +PointerAlignment: Right +SortIncludes: true +SpacesBeforeTrailingComments: 2 # TODO: require one blank line between blocks + + +# FIXME: auto generate this section +IncludeCategories: + # standard C headers + # TODO: add as needed + - Regex: ^<(cstdint|cstdio|cstdlib|cstring)>$ + Priority: 1 + # standard C++ headers + # TODO: add as needed + - Regex: ^<(algorithm|condition_variable|functional|iostream|map|memory|mutex|numeric|string|thread|vector)>$ + Priority: 2 + # third party headers + - Regex: ^ + Priority: 3 + # public nn headers + - Regex: ^ #include +#include + struct examples { const uint32_t n = 10; const uint32_t c = 3; diff --git a/examples/example_layer_mlp.cpp b/examples/example_layer_mlp.cpp index d4828d6..ffda591 100644 --- a/examples/example_layer_mlp.cpp +++ b/examples/example_layer_mlp.cpp @@ -1,8 +1,9 @@ #include -#include #include +#include + #include "utils.hpp" void example_mlp() diff --git a/examples/example_layer_vgg16.cpp b/examples/example_layer_vgg16.cpp index bf549df..3291fc8 100644 --- a/examples/example_layer_vgg16.cpp +++ b/examples/example_layer_vgg16.cpp @@ -9,7 +9,7 @@ #include #ifdef USE_OPENCV -#include +# include #endif #include "utils.hpp" diff --git a/examples/example_mlp.cpp b/examples/example_mlp.cpp index e3db82a..81f36af 100644 --- a/examples/example_mlp.cpp +++ b/examples/example_mlp.cpp @@ -1,8 +1,9 @@ #include -#include #include +#include + #include "utils.hpp" void example_mlp() diff --git a/examples/example_mnist.cpp b/examples/example_mnist.cpp index 63ec9fa..13e9d2c 100644 --- a/examples/example_mnist.cpp +++ b/examples/example_mnist.cpp @@ -1,10 +1,11 @@ #include + #include #include #ifdef USE_OPENCV -#include +# include #endif #include diff --git a/examples/example_model_vgg16.cpp b/examples/example_model_vgg16.cpp index 7c41af9..c388c93 100644 --- a/examples/example_model_vgg16.cpp +++ b/examples/example_model_vgg16.cpp @@ -8,7 +8,7 @@ #include #ifdef USE_OPENCV -#include +# include #endif #include "utils.hpp" From 7fa0182f29ac9c392c21b43c2fa46dddb43de24c Mon Sep 17 00:00:00 2001 From: lg Date: Fri, 5 Apr 2019 19:28:05 +0800 Subject: [PATCH 12/19] resolve conflict --- examples/example_model_plain34.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/example_model_plain34.cpp b/examples/example_model_plain34.cpp index 1ba9164..5cdc3f4 100644 --- a/examples/example_model_plain34.cpp +++ b/examples/example_model_plain34.cpp @@ -29,7 +29,7 @@ class plain34_model using conv_trait = nn::ops::conv_trait; const conv_trait::padding_1d_t p = pad(3, 2); return conv_layer( - conv_layer::ksize(7, 7), d, + d, conv_layer::ksize(7, 7), conv_trait(conv_trait::padding(p, p), conv_trait::stride(2, 2))); } @@ -53,7 +53,7 @@ class plain34_model auto conv(int d, int s, const conv_trait::padding_1d_t &padding) const { using conv_layer = nn::layers::conv; - return conv_layer(conv_layer::ksize(3, 3), d, + return conv_layer(d, conv_layer::ksize(3, 3), conv_trait(conv_trait::padding(padding, padding), conv_trait::stride(s, s))); } From 09caef0b6b0df77d8f4f200c79b5829c9f791556 Mon Sep 17 00:00:00 2001 From: lg Date: Fri, 5 Apr 2019 19:32:18 +0800 Subject: [PATCH 13/19] simplify --- examples/example_model_plain34.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/examples/example_model_plain34.cpp b/examples/example_model_plain34.cpp index 5cdc3f4..6033820 100644 --- a/examples/example_model_plain34.cpp +++ b/examples/example_model_plain34.cpp @@ -28,9 +28,8 @@ class plain34_model nn::layers::conv; using conv_trait = nn::ops::conv_trait; const conv_trait::padding_1d_t p = pad(3, 2); - return conv_layer( - d, conv_layer::ksize(7, 7), - conv_trait(conv_trait::padding(p, p), conv_trait::stride(2, 2))); + return conv_layer(d, conv_layer::ksize(7, 7), conv_trait::padding(p, p), + conv_trait::stride(2, 2)); } auto pool1() const @@ -54,8 +53,8 @@ class plain34_model { using conv_layer = nn::layers::conv; return conv_layer(d, conv_layer::ksize(3, 3), - conv_trait(conv_trait::padding(padding, padding), - conv_trait::stride(s, s))); + conv_trait::padding(padding, padding), + conv_trait::stride(s, s)); } const std::string prefix_; From 8f340f406942e2939606b8097fa0264f5171ae73 Mon Sep 17 00:00:00 2001 From: lg Date: Sat, 6 Apr 2019 22:52:59 +0800 Subject: [PATCH 14/19] resolve conflict --- examples/example_model_plain34.cpp | 100 +++++++++++++---------------- include/nn/bits/layers/conv.hpp | 7 +- include/nn/bits/layers/pool.hpp | 7 +- 3 files changed, 53 insertions(+), 61 deletions(-) diff --git a/examples/example_model_plain34.cpp b/examples/example_model_plain34.cpp index 6033820..fdf7f70 100644 --- a/examples/example_model_plain34.cpp +++ b/examples/example_model_plain34.cpp @@ -24,37 +24,29 @@ class plain34_model auto conv1(int d) const { - using conv_layer = - nn::layers::conv; - using conv_trait = nn::ops::conv_trait; - const conv_trait::padding_1d_t p = pad(3, 2); - return conv_layer(d, conv_layer::ksize(7, 7), conv_trait::padding(p, p), - conv_trait::stride(2, 2)); + using layer = nn::layers::conv; + return layer(d, layer::ksize(7, 7), layer::padding_same(), + layer::stride(2, 2)); } auto pool1() const { - using pool_max = nn::layers::pool; - const auto padding = pool_max::sample1d_t::same_padding(3, 2, 1, 112); - return pool_max(pool_max::ksize(3, 3), - pool_max::padding(padding, padding), - pool_max::stride(2, 2)); + using layer = nn::layers::pool; + return layer(layer::ksize(3, 3), layer::padding_same(), + layer::stride(2, 2)); } auto pool2() const { - using pool_mean = nn::layers::pool; - return pool_mean(pool_mean::ksize(7, 7)); + using layer = nn::layers::pool; + return layer(layer::ksize(7, 7)); } - using conv_trait = nn::ops::conv_trait; - - auto conv(int d, int s, const conv_trait::padding_1d_t &padding) const + auto conv(int d, int s) const { - using conv_layer = nn::layers::conv; - return conv_layer(d, conv_layer::ksize(3, 3), - conv_trait::padding(padding, padding), - conv_trait::stride(s, s)); + using layer = nn::layers::conv; + return layer(d, layer::ksize(3, 3), layer::padding_same(), + layer::stride(s, s)); } const std::string prefix_; @@ -77,41 +69,39 @@ class plain34_model << conv1(64) // << pool1() // - << conv(64, 1, pad(1, 1)) << bn_layer() // - << conv(64, 1, pad(1, 1)) << bn_layer() - << conv(64, 1, pad(1, 1)) << bn_layer() - << conv(64, 1, pad(1, 1)) << bn_layer() - << conv(64, 1, pad(1, 1)) << bn_layer() - << conv(64, 1, pad(1, 1)) << bn_layer() - - << conv(128, 2, pad(0, 1)) << bn_layer() // - << conv(128, 1, pad(1, 1)) << bn_layer() // - << conv(128, 1, pad(1, 1)) << bn_layer() // - << conv(128, 1, pad(1, 1)) << bn_layer() // - << conv(128, 1, pad(1, 1)) << bn_layer() // - << conv(128, 1, pad(1, 1)) << bn_layer() // - << conv(128, 1, pad(1, 1)) << bn_layer() // - << conv(128, 1, pad(1, 1)) << bn_layer() // - - << conv(256, 2, pad(0, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - << conv(256, 1, pad(1, 1)) << bn_layer() // - - << conv(512, 2, pad(0, 1)) << bn_layer() // - << conv(512, 1, pad(1, 1)) << bn_layer() // - << conv(512, 1, pad(1, 1)) << bn_layer() // - << conv(512, 1, pad(1, 1)) << bn_layer() // - << conv(512, 1, pad(1, 1)) << bn_layer() // - << conv(512, 1, pad(1, 1)) << bn_layer() // + << conv(64, 1) << bn_layer() // + << conv(64, 1) << bn_layer() << conv(64, 1) << bn_layer() + << conv(64, 1) << bn_layer() << conv(64, 1) << bn_layer() + << conv(64, 1) << bn_layer() + + << conv(128, 2) << bn_layer() // + << conv(128, 1) << bn_layer() // + << conv(128, 1) << bn_layer() // + << conv(128, 1) << bn_layer() // + << conv(128, 1) << bn_layer() // + << conv(128, 1) << bn_layer() // + << conv(128, 1) << bn_layer() // + << conv(128, 1) << bn_layer() // + + << conv(256, 2) << bn_layer() // + << conv(256, 1) << bn_layer() // + << conv(256, 1) << bn_layer() // + << conv(256, 1) << bn_layer() // + << conv(256, 1) << bn_layer() // + << conv(256, 1) << bn_layer() // + << conv(256, 1) << bn_layer() // + << conv(256, 1) << bn_layer() // + << conv(256, 1) << bn_layer() // + << conv(256, 1) << bn_layer() // + << conv(256, 1) << bn_layer() // + << conv(256, 1) << bn_layer() // + + << conv(512, 2) << bn_layer() // + << conv(512, 1) << bn_layer() // + << conv(512, 1) << bn_layer() // + << conv(512, 1) << bn_layer() // + << conv(512, 1) << bn_layer() // + << conv(512, 1) << bn_layer() // << pool2() // << flatten() // diff --git a/include/nn/bits/layers/conv.hpp b/include/nn/bits/layers/conv.hpp index 7003af3..cdac628 100644 --- a/include/nn/bits/layers/conv.hpp +++ b/include/nn/bits/layers/conv.hpp @@ -21,7 +21,8 @@ class conv_trait using stride_t = std::experimental::new_type, stride_trait>; using rate_t = std::experimental::new_type, rate_trait>; - using padding_policy = ops::linear_sample_trait::padding_policy; + using dim_t = uint32_t; + using padding_policy = ops::linear_sample_trait::padding_policy; const size_t n_filters_; const ksize_t ksize_; @@ -36,12 +37,12 @@ class conv_trait static padding_policy padding_same() { - return ops::linear_sample_trait::padding_same(); + return ops::linear_sample_trait::padding_same(); } static padding_policy padding_valid() { - return ops::linear_sample_trait::padding_valid(); + return ops::linear_sample_trait::padding_valid(); } conv_trait(size_t n_filters, const ksize_t &ksize) diff --git a/include/nn/bits/layers/pool.hpp b/include/nn/bits/layers/pool.hpp index afb89fe..df657fb 100644 --- a/include/nn/bits/layers/pool.hpp +++ b/include/nn/bits/layers/pool.hpp @@ -18,7 +18,8 @@ template <> class pool_trait using ksize_t = std::experimental::new_type, ksize_trait>; using stride_t = std::experimental::new_type, stride_trait>; - using padding_policy = ops::linear_sample_trait::padding_policy; + using dim_t = uint32_t; + using padding_policy = ops::linear_sample_trait::padding_policy; const ksize_t ksize_; const padding_policy padding_; @@ -30,12 +31,12 @@ template <> class pool_trait static padding_policy padding_same() { - return ops::linear_sample_trait::padding_same(); + return ops::linear_sample_trait::padding_same(); } static padding_policy padding_valid() { - return ops::linear_sample_trait::padding_valid(); + return ops::linear_sample_trait::padding_valid(); } pool_trait() : pool_trait(ksize(2, 2)) {} From 70667e7e5a86673f10e642ed74f006f9f9018afc Mon Sep 17 00:00:00 2001 From: lg Date: Sun, 7 Apr 2019 00:43:30 +0800 Subject: [PATCH 15/19] support negative padding --- .clang-format | 2 +- examples/example_model_plain34.cpp | 2 - examples/example_model_plain50.cpp | 175 ++++++++++++++++++++++++++ include/nn/bits/ops/conv.hpp | 5 +- include/nn/bits/ops/linear_sample.hpp | 49 +++++--- tests/test_linear_sample.cpp | 16 ++- 6 files changed, 214 insertions(+), 35 deletions(-) create mode 100644 examples/example_model_plain50.cpp diff --git a/.clang-format b/.clang-format index fbacfbd..adfa75e 100644 --- a/.clang-format +++ b/.clang-format @@ -27,7 +27,7 @@ IncludeCategories: Priority: 1 # standard C++ headers # TODO: add as needed - - Regex: ^<(algorithm|array|condition_variable|functional|iostream|map|memory|mutex|numeric|string|thread|vector)>$ + - Regex: ^<(algorithm|array|condition_variable|functional|iostream|map|memory|mutex|numeric|string|thread|type_traits|vector)>$ Priority: 2 # third party headers - Regex: ^ diff --git a/examples/example_model_plain34.cpp b/examples/example_model_plain34.cpp index fdf7f70..cd5751a 100644 --- a/examples/example_model_plain34.cpp +++ b/examples/example_model_plain34.cpp @@ -7,8 +7,6 @@ #include "utils.hpp" -using nn::ops::pad; - template class plain34_model diff --git a/examples/example_model_plain50.cpp b/examples/example_model_plain50.cpp new file mode 100644 index 0000000..455dd13 --- /dev/null +++ b/examples/example_model_plain50.cpp @@ -0,0 +1,175 @@ +// #define STDNN_OPS_HAVE_CBLAS + +#include +#include + +#include + +#include "utils.hpp" + +template +class plain50_model +{ + const size_t logits = 1000; + + using relu = nn::ops::pointwise; + using bn_layer = nn::layers::batch_norm; + + using flatten = nn::layers::flatten<1, 3>; + using conv = nn::layers::conv; + using conv_relu = nn::layers::conv; + using dense = nn::layers::dense<>; + using softmax = nn::layers::activation; + + auto conv7x7(int d) const + { + return conv_relu(d, conv_relu::ksize(7, 7), conv_relu::padding_same(), + conv_relu::stride(2, 2)); + } + + auto pool1() const + { + using pool_max = nn::layers::pool; + return pool_max(pool_max::ksize(3, 3), pool_max::padding_same(), + pool_max::stride(2, 2)); + } + + auto pool2() const + { + using pool_mean = nn::layers::pool; + return pool_mean(pool_mean::ksize(7, 7)); + } + + auto conv1x1(int d, int s) const + { + return conv(d, conv::ksize(1, 1), conv::padding_same(), + conv::stride(s, s)); + } + + auto conv3x3(int d, int s) const + { + return conv(d, conv::ksize(3, 3), conv::padding_same(), + conv::stride(s, s)); + } + + // auto conv2_x() const {} + // auto conv3_x() const {} + // auto conv4_x() const {} + // auto conv5_x() const {} + + const std::string prefix_; + + const auto p(const std::string &name) const + { + return nn::ops::readtar(prefix_, name); + } + + public: + const size_t h = 224; + const size_t w = 224; + + plain34_model(const std::string &prefix) : prefix_(prefix) {} + + template + auto operator()(const ttl::tensor_ref &x, int m = 5) const + { + auto layers = nn::models::make_sequential() // + << conv7x7(64) << bn_layer() // + << pool1() // + + // conv2_x [1x1, 64; 3x3, 64; 1x1, 256] x 3 + << conv1x1(64, 1) << bn_layer() // + << conv3x3(64, 1) << bn_layer() // + << conv1x1(256, 1) << bn_layer() // + + << conv1x1(64, 1) << bn_layer() // + << conv3x3(64, 1) << bn_layer() // + << conv1x1(256, 1) << bn_layer() // + + << conv1x1(64, 1) << bn_layer() // + << conv3x3(64, 1) << bn_layer() // + << conv1x1(256, 1) + << bn_layer() // + + // conv3_x [1x1, 128; 3x3, 128; 1x1, 512] x 4 + << conv1x1(128, 2) << bn_layer() // + << conv3x3(128, 1) << bn_layer() // + << conv1x1(512, 1) << bn_layer() // + + << conv1x1(128, 1) << bn_layer() // + << conv3x3(128, 1) << bn_layer() // + << conv1x1(512, 1) << bn_layer() // + + << conv1x1(128, 1) << bn_layer() // + << conv3x3(128, 1) << bn_layer() // + << conv1x1(512, 1) << bn_layer() // + + << conv1x1(128, 1) << bn_layer() // + << conv3x3(128, 1) << bn_layer() // + << conv1x1(512, 1) + << bn_layer() // + + // conv4_x [1x1, 256; 3x3, 256; 1x1, 1024] x 6 + << conv1x1(256, 2) << bn_layer() // + << conv3x3(256, 1) << bn_layer() // + << conv1x1(1024, 1) << bn_layer() // + + << conv1x1(256, 1) << bn_layer() // + << conv3x3(256, 1) << bn_layer() // + << conv1x1(1024, 1) << bn_layer() // + + << conv1x1(256, 1) << bn_layer() // + << conv3x3(256, 1) << bn_layer() // + << conv1x1(1024, 1) << bn_layer() // + + << conv1x1(256, 1) << bn_layer() // + << conv3x3(256, 1) << bn_layer() // + << conv1x1(1024, 1) << bn_layer() // + + << conv1x1(256, 1) << bn_layer() // + << conv3x3(256, 1) << bn_layer() // + << conv1x1(1024, 1) << bn_layer() // + + << conv1x1(256, 1) << bn_layer() // + << conv3x3(256, 1) << bn_layer() // + << conv1x1(1024, 1) + << bn_layer() // + + // conv5_x [1x1, 512; 3x3, 512; 1x1, 2048] x 3 + << conv1x1(512, 2) << bn_layer() // + << conv3x3(512, 1) << bn_layer() // + << conv1x1(2048, 1) << bn_layer() // + + << conv1x1(512, 1) << bn_layer() // + << conv3x3(512, 1) << bn_layer() // + << conv1x1(2048, 1) << bn_layer() // + + << conv1x1(512, 1) << bn_layer() // + << conv3x3(512, 1) << bn_layer() // + << conv1x1(2048, 1) + << bn_layer() // + + // + << pool2() // + << flatten() // + << dense(logits) // + << softmax() // + ; + + auto y = layers(x); + return y; + } +}; + +int main(int argc, char *argv[]) +{ + const std::string home(std::getenv("HOME")); + const std::string prefix = home + "/var/models/resnet"; + plain50_model model(prefix); + const auto x = ttl::tensor(1, model.h, model.w, 3); + const auto y = model(ref(x)); + PPRINT(x); + PPRINT(*y); + return 0; +} diff --git a/include/nn/bits/ops/conv.hpp b/include/nn/bits/ops/conv.hpp index 5861d93..5d07f04 100644 --- a/include/nn/bits/ops/conv.hpp +++ b/include/nn/bits/ops/conv.hpp @@ -50,10 +50,7 @@ template class linear_conv_trait } linear_conv_trait(const padding_t &pad, dim_t stride, dim_t rate) - : pad_l_(std::get<0>(pad.dims)), - pad_r_(std::get<1>(pad.dims)), - rate_(rate), - stride_(stride) + : pad_l_(pad.left_), pad_r_(pad.right_), rate_(rate), stride_(stride) { } diff --git a/include/nn/bits/ops/linear_sample.hpp b/include/nn/bits/ops/linear_sample.hpp index d76fc5c..868aff3 100644 --- a/include/nn/bits/ops/linear_sample.hpp +++ b/include/nn/bits/ops/linear_sample.hpp @@ -1,4 +1,6 @@ #pragma once +#include + #include /*! @@ -25,32 +27,43 @@ class linear_sample_trait; template class linear_sample_trait { - const dim_t pad_l_; // TODO: make it template parameter - const dim_t pad_r_; // TODO: make it template parameter + using signed_dim_t = typename std::make_signed::type; + + const signed_dim_t pad_l_; // TODO: make it template parameter + const signed_dim_t pad_r_; // TODO: make it template parameter const dim_t rate_; const dim_t stride_; const dim_t ksize_; - struct padding_trait; - public: static constexpr dim_t default_rate = 1; static constexpr dim_t default_stride = 1; static constexpr dim_t default_pad_lr = 0; - using padding_t = std::experimental::new_type, padding_trait>; + struct padding_t { + signed_dim_t left_; + signed_dim_t right_; - static constexpr padding_t padding(dim_t p) { return padding_t(p, p); } + padding_t(signed_dim_t left, signed_dim_t right) + : left_(left), right_(right) + { + } + }; - static constexpr padding_t padding(dim_t left, dim_t right) + static constexpr padding_t padding(signed_dim_t p) + { + return padding_t(p, p); + } + + static constexpr padding_t padding(signed_dim_t left, signed_dim_t right) { return padding_t(left, right); }; static dim_t patch_size(dim_t k, dim_t r) { return r * (k - 1) + 1; } - static padding_t even_padding(dim_t p) + static padding_t even_padding(signed_dim_t p) { return padding_t(p / 2, p - p / 2); } @@ -67,10 +80,9 @@ template class linear_sample_trait { const dim_t ps = patch_size(k, r); const dim_t n0 = n % s; - // p = ps - s - (n % s) - // TODO: support negative padding - contract_assert(ps >= s + n0); - return even_padding(ps - s - n0); + // tot_pad = ps - s - (n % s) + return even_padding(static_cast(ps) - + static_cast(s + n0)); } using padding_policy = std::function; @@ -108,13 +120,14 @@ template class linear_sample_trait { } - linear_sample_trait(dim_t ksize, dim_t stride, dim_t rate, dim_t pad_lr) + linear_sample_trait(dim_t ksize, dim_t stride, dim_t rate, + signed_dim_t pad_lr) : linear_sample_trait(ksize, stride, rate, padding(pad_lr)) { } - linear_sample_trait(dim_t ksize, dim_t stride, dim_t rate, dim_t pad_l, - dim_t pad_r) + linear_sample_trait(dim_t ksize, dim_t stride, dim_t rate, + signed_dim_t pad_l, signed_dim_t pad_r) : linear_sample_trait(ksize, stride, rate, padding(pad_l, pad_r)) { // TODO: deprecate it @@ -122,8 +135,8 @@ template class linear_sample_trait linear_sample_trait(dim_t ksize, dim_t stride, dim_t rate, const padding_t &pad) - : pad_l_(std::get<0>(pad.dims)), - pad_r_(std::get<1>(pad.dims)), + : pad_l_(pad.left_), + pad_r_(pad.right_), rate_(rate), stride_(stride), ksize_(ksize) @@ -131,8 +144,6 @@ template class linear_sample_trait contract_assert(rate_ >= 1); contract_assert(stride_ >= 1); contract_assert(ksize_ >= 1); - contract_assert(pad_l_ >= 0); - contract_assert(pad_r_ >= 0); } dim_t get_ksize() const { return ksize_; } diff --git a/tests/test_linear_sample.cpp b/tests/test_linear_sample.cpp index 5720ac7..38b13c6 100644 --- a/tests/test_linear_sample.cpp +++ b/tests/test_linear_sample.cpp @@ -1,9 +1,9 @@ -#include "testing.hpp" - -#include #include #include +#include + +#include "testing.hpp" void test_linear_sample_ksr_nm(int ksize, int stride, int rate, int n, int m) { @@ -81,9 +81,8 @@ void test_valid_padding_ksize_3(dim_t n, dim_t s, dim_t pad_l, dim_t pad_r) { using sample_t = nn::ops::linear_sample_trait; const auto padding = sample_t::valid_padding(3, s, 1, n); - const auto [u, v] = padding.dims; - ASSERT_EQ(u, pad_l); - ASSERT_EQ(v, pad_r); + ASSERT_EQ(padding.left_, pad_l); + ASSERT_EQ(padding.right_, pad_r); } template @@ -91,9 +90,8 @@ void test_same_padding_ksize_3(dim_t n, dim_t s, dim_t pad_l, dim_t pad_r) { using sample_t = nn::ops::linear_sample_trait; const auto padding = sample_t::same_padding(3, s, 1, n); - const auto [u, v] = padding.dims; - ASSERT_EQ(u, pad_l); - ASSERT_EQ(v, pad_r); + ASSERT_EQ(padding.left_, pad_l); + ASSERT_EQ(padding.right_, pad_r); } TEST(linear_sample_test, test_auto_padding) From b17f56ee216071de0239c13cfe78905230938fcc Mon Sep 17 00:00:00 2001 From: lg Date: Sun, 7 Apr 2019 00:44:17 +0800 Subject: [PATCH 16/19] fix example --- examples/example_model_plain50.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/example_model_plain50.cpp b/examples/example_model_plain50.cpp index 455dd13..24b9f6c 100644 --- a/examples/example_model_plain50.cpp +++ b/examples/example_model_plain50.cpp @@ -69,7 +69,7 @@ class plain50_model const size_t h = 224; const size_t w = 224; - plain34_model(const std::string &prefix) : prefix_(prefix) {} + plain50_model(const std::string &prefix) : prefix_(prefix) {} template auto operator()(const ttl::tensor_ref &x, int m = 5) const From 0256d9865fc382c2a31a6bde38cd607334c6eeab Mon Sep 17 00:00:00 2001 From: lg Date: Sun, 7 Apr 2019 17:25:00 +0800 Subject: [PATCH 17/19] debug --- examples/example_model_plain50.cpp | 135 +++++++++++++++++------------ examples/utils.hpp | 25 +++++- 2 files changed, 100 insertions(+), 60 deletions(-) diff --git a/examples/example_model_plain50.cpp b/examples/example_model_plain50.cpp index 24b9f6c..e781fe1 100644 --- a/examples/example_model_plain50.cpp +++ b/examples/example_model_plain50.cpp @@ -7,6 +7,9 @@ #include "utils.hpp" +using nn::layers::with_init; +using nn::layers::debug::show_name; + template class plain50_model @@ -18,14 +21,24 @@ class plain50_model using flatten = nn::layers::flatten<1, 3>; using conv = nn::layers::conv; - using conv_relu = nn::layers::conv; - using dense = nn::layers::dense<>; using softmax = nn::layers::activation; auto conv7x7(int d) const { - return conv_relu(d, conv_relu::ksize(7, 7), conv_relu::padding_same(), - conv_relu::stride(2, 2)); + using conv_relu = + nn::layers::conv; + + return with_init(conv_relu(d, conv_relu::ksize(7, 7), + conv_relu::padding_same(), + conv_relu::stride(2, 2)), + show_name("w")); + } + + auto bn() const + { + return with_init(bn_layer(), // + show_name("mean"), show_name("var"), show_name("beta"), + show_name("gamma")); } auto pool1() const @@ -43,14 +56,16 @@ class plain50_model auto conv1x1(int d, int s) const { - return conv(d, conv::ksize(1, 1), conv::padding_same(), - conv::stride(s, s)); + return with_init(conv(d, conv::ksize(1, 1), conv::padding_same(), + conv::stride(s, s)), + show_name("W")); } auto conv3x3(int d, int s) const { - return conv(d, conv::ksize(3, 3), conv::padding_same(), - conv::stride(s, s)); + return with_init(conv(d, conv::ksize(3, 3), conv::padding_same(), + conv::stride(s, s)), + show_name("W")); } // auto conv2_x() const {} @@ -58,6 +73,12 @@ class plain50_model // auto conv4_x() const {} // auto conv5_x() const {} + auto dense(int logits) const + { + using layer = nn::layers::dense<>; + return with_init(layer(logits), show_name("W"), show_name("b")); + } + const std::string prefix_; const auto p(const std::string &name) const @@ -75,80 +96,80 @@ class plain50_model auto operator()(const ttl::tensor_ref &x, int m = 5) const { auto layers = nn::models::make_sequential() // - << conv7x7(64) << bn_layer() // + << conv7x7(64) << bn() // << pool1() // // conv2_x [1x1, 64; 3x3, 64; 1x1, 256] x 3 - << conv1x1(64, 1) << bn_layer() // - << conv3x3(64, 1) << bn_layer() // - << conv1x1(256, 1) << bn_layer() // + << conv1x1(64, 1) << bn() // + << conv3x3(64, 1) << bn() // + << conv1x1(256, 1) << bn() // - << conv1x1(64, 1) << bn_layer() // - << conv3x3(64, 1) << bn_layer() // - << conv1x1(256, 1) << bn_layer() // + << conv1x1(64, 1) << bn() // + << conv3x3(64, 1) << bn() // + << conv1x1(256, 1) << bn() // - << conv1x1(64, 1) << bn_layer() // - << conv3x3(64, 1) << bn_layer() // + << conv1x1(64, 1) << bn() // + << conv3x3(64, 1) << bn() // << conv1x1(256, 1) - << bn_layer() // + << bn() // // conv3_x [1x1, 128; 3x3, 128; 1x1, 512] x 4 - << conv1x1(128, 2) << bn_layer() // - << conv3x3(128, 1) << bn_layer() // - << conv1x1(512, 1) << bn_layer() // + << conv1x1(128, 2) << bn() // + << conv3x3(128, 1) << bn() // + << conv1x1(512, 1) << bn() // - << conv1x1(128, 1) << bn_layer() // - << conv3x3(128, 1) << bn_layer() // - << conv1x1(512, 1) << bn_layer() // + << conv1x1(128, 1) << bn() // + << conv3x3(128, 1) << bn() // + << conv1x1(512, 1) << bn() // - << conv1x1(128, 1) << bn_layer() // - << conv3x3(128, 1) << bn_layer() // - << conv1x1(512, 1) << bn_layer() // + << conv1x1(128, 1) << bn() // + << conv3x3(128, 1) << bn() // + << conv1x1(512, 1) << bn() // - << conv1x1(128, 1) << bn_layer() // - << conv3x3(128, 1) << bn_layer() // + << conv1x1(128, 1) << bn() // + << conv3x3(128, 1) << bn() // << conv1x1(512, 1) - << bn_layer() // + << bn() // // conv4_x [1x1, 256; 3x3, 256; 1x1, 1024] x 6 - << conv1x1(256, 2) << bn_layer() // - << conv3x3(256, 1) << bn_layer() // - << conv1x1(1024, 1) << bn_layer() // + << conv1x1(256, 2) << bn() // + << conv3x3(256, 1) << bn() // + << conv1x1(1024, 1) << bn() // - << conv1x1(256, 1) << bn_layer() // - << conv3x3(256, 1) << bn_layer() // - << conv1x1(1024, 1) << bn_layer() // + << conv1x1(256, 1) << bn() // + << conv3x3(256, 1) << bn() // + << conv1x1(1024, 1) << bn() // - << conv1x1(256, 1) << bn_layer() // - << conv3x3(256, 1) << bn_layer() // - << conv1x1(1024, 1) << bn_layer() // + << conv1x1(256, 1) << bn() // + << conv3x3(256, 1) << bn() // + << conv1x1(1024, 1) << bn() // - << conv1x1(256, 1) << bn_layer() // - << conv3x3(256, 1) << bn_layer() // - << conv1x1(1024, 1) << bn_layer() // + << conv1x1(256, 1) << bn() // + << conv3x3(256, 1) << bn() // + << conv1x1(1024, 1) << bn() // - << conv1x1(256, 1) << bn_layer() // - << conv3x3(256, 1) << bn_layer() // - << conv1x1(1024, 1) << bn_layer() // + << conv1x1(256, 1) << bn() // + << conv3x3(256, 1) << bn() // + << conv1x1(1024, 1) << bn() // - << conv1x1(256, 1) << bn_layer() // - << conv3x3(256, 1) << bn_layer() // + << conv1x1(256, 1) << bn() // + << conv3x3(256, 1) << bn() // << conv1x1(1024, 1) - << bn_layer() // + << bn() // // conv5_x [1x1, 512; 3x3, 512; 1x1, 2048] x 3 - << conv1x1(512, 2) << bn_layer() // - << conv3x3(512, 1) << bn_layer() // - << conv1x1(2048, 1) << bn_layer() // + << conv1x1(512, 2) << bn() // + << conv3x3(512, 1) << bn() // + << conv1x1(2048, 1) << bn() // - << conv1x1(512, 1) << bn_layer() // - << conv3x3(512, 1) << bn_layer() // - << conv1x1(2048, 1) << bn_layer() // + << conv1x1(512, 1) << bn() // + << conv3x3(512, 1) << bn() // + << conv1x1(2048, 1) << bn() // - << conv1x1(512, 1) << bn_layer() // - << conv3x3(512, 1) << bn_layer() // + << conv1x1(512, 1) << bn() // + << conv3x3(512, 1) << bn() // << conv1x1(2048, 1) - << bn_layer() // + << bn() // // << pool2() // diff --git a/examples/utils.hpp b/examples/utils.hpp index e254fa5..0fa7281 100644 --- a/examples/utils.hpp +++ b/examples/utils.hpp @@ -1,9 +1,11 @@ #include -#include -#include #include +#include + +#include + template std::string show_shape(const ttl::internal::basic_shape &shape, char bracket_l = '(', char bracket_r = ')') @@ -21,7 +23,7 @@ void show_signature(const T &y, const Ts &... x) { std::array args({show_shape(x.shape())...}); std::string ss; - for (const auto& p : args) { + for (const auto &p : args) { if (!ss.empty()) { ss += ", "; } ss += p; } @@ -35,3 +37,20 @@ template void pprint(const T &t, const char *name) } #define PPRINT(e) pprint(e, #e); + +namespace nn::layers::debug +{ +class show_name +{ + const std::string name_; + + public: + show_name(const std::string name) : name_(name) {} + + template + void operator()(const ttl::tensor_ref &y) const + { + std::cerr << name_ << " :: " << std::endl; + } +}; +} // namespace nn::layers::debug From 94077e6a7b64802467bcfafbf814913d4c8dcb21 Mon Sep 17 00:00:00 2001 From: lg Date: Sun, 7 Apr 2019 17:54:09 +0800 Subject: [PATCH 18/19] fix build --- .clang-format | 2 +- examples/example_model_plain50.cpp | 20 ++++++++++++-------- examples/utils.hpp | 5 ++++- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/.clang-format b/.clang-format index adfa75e..b82f1d7 100644 --- a/.clang-format +++ b/.clang-format @@ -27,7 +27,7 @@ IncludeCategories: Priority: 1 # standard C++ headers # TODO: add as needed - - Regex: ^<(algorithm|array|condition_variable|functional|iostream|map|memory|mutex|numeric|string|thread|type_traits|vector)>$ + - Regex: ^<(algorithm|array|condition_variable|functional|iomanip|iostream|map|memory|mutex|numeric|string|thread|type_traits|vector)>$ Priority: 2 # third party headers - Regex: ^ diff --git a/examples/example_model_plain50.cpp b/examples/example_model_plain50.cpp index e781fe1..6f4e8ed 100644 --- a/examples/example_model_plain50.cpp +++ b/examples/example_model_plain50.cpp @@ -20,25 +20,27 @@ class plain50_model using bn_layer = nn::layers::batch_norm; using flatten = nn::layers::flatten<1, 3>; - using conv = nn::layers::conv; + using conv = nn::layers::conv; using softmax = nn::layers::activation; auto conv7x7(int d) const { using conv_relu = - nn::layers::conv; - + nn::layers::conv; return with_init(conv_relu(d, conv_relu::ksize(7, 7), conv_relu::padding_same(), conv_relu::stride(2, 2)), - show_name("w")); + show_name("conv1/kernel"), show_name("conv1/bias")); } auto bn() const { return with_init(bn_layer(), // - show_name("mean"), show_name("var"), show_name("beta"), - show_name("gamma")); + // show_name("mean"), show_name("var"), + nn::ops::noop(), // + nn::ops::noop(), // + show_name("bn_conv?/beta"), + show_name("bn_conv?/gamma")); } auto pool1() const @@ -58,14 +60,16 @@ class plain50_model { return with_init(conv(d, conv::ksize(1, 1), conv::padding_same(), conv::stride(s, s)), - show_name("W")); + show_name("res??_branch??/kernel"), + show_name("res??_branch??/bias")); } auto conv3x3(int d, int s) const { return with_init(conv(d, conv::ksize(3, 3), conv::padding_same(), conv::stride(s, s)), - show_name("W")); + show_name("res??_branch??/kernel"), + show_name("res??_branch??/bias")); } // auto conv2_x() const {} diff --git a/examples/utils.hpp b/examples/utils.hpp index 0fa7281..21d43bb 100644 --- a/examples/utils.hpp +++ b/examples/utils.hpp @@ -1,3 +1,5 @@ +#include +#include #include #include @@ -50,7 +52,8 @@ class show_name template void operator()(const ttl::tensor_ref &y) const { - std::cerr << name_ << " :: " << std::endl; + std::cerr << std::left << std::setw(32) << name_ + << " :: " << show_shape(y.shape()) << std::endl; } }; } // namespace nn::layers::debug From 969972a6953c75541e0376e33bdc01d34c6ff150 Mon Sep 17 00:00:00 2001 From: lg Date: Fri, 12 Apr 2019 19:35:55 +0800 Subject: [PATCH 19/19] -Werror --- CMakeLists.txt | 3 ++- examples/example_mnist.cpp | 3 +++ examples/example_model_plain50.cpp | 8 ++++---- examples/example_train_mnist_slp.cpp | 1 + examples/utils.hpp | 7 +++++++ include/nn/experimental/bits/ops/utility.hpp | 7 ++++++- 6 files changed, 23 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 04a2560..6023586 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,8 +6,9 @@ SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) FIND_PACKAGE(stdtensor REQUIRED) -ADD_DEFINITIONS(-Wfatal-errors) ADD_DEFINITIONS(-Wall) +ADD_DEFINITIONS(-Werror) +ADD_DEFINITIONS(-Wfatal-errors) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/3rdparty/include) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) diff --git a/examples/example_mnist.cpp b/examples/example_mnist.cpp index 13e9d2c..8d479dc 100644 --- a/examples/example_mnist.cpp +++ b/examples/example_mnist.cpp @@ -10,6 +10,8 @@ #include +#include "utils.hpp" + void example_mnist() {} int main() @@ -26,6 +28,7 @@ int main() int i = 0; system("mkdir -p images"); for (auto im : t) { + UNUSED(im); char name[20]; sprintf(name, "images/%d.png", ++i); #ifdef USE_OPENCV diff --git a/examples/example_model_plain50.cpp b/examples/example_model_plain50.cpp index 6f4e8ed..d28a425 100644 --- a/examples/example_model_plain50.cpp +++ b/examples/example_model_plain50.cpp @@ -60,16 +60,16 @@ class plain50_model { return with_init(conv(d, conv::ksize(1, 1), conv::padding_same(), conv::stride(s, s)), - show_name("res??_branch??/kernel"), - show_name("res??_branch??/bias")); + show_name("res?_branch?/kernel"), + show_name("res?_branch?/bias")); } auto conv3x3(int d, int s) const { return with_init(conv(d, conv::ksize(3, 3), conv::padding_same(), conv::stride(s, s)), - show_name("res??_branch??/kernel"), - show_name("res??_branch??/bias")); + show_name("res?_branch?/kernel"), + show_name("res?_branch?/bias")); } // auto conv2_x() const {} diff --git a/examples/example_train_mnist_slp.cpp b/examples/example_train_mnist_slp.cpp index f3e652a..f5bc4d0 100644 --- a/examples/example_train_mnist_slp.cpp +++ b/examples/example_train_mnist_slp.cpp @@ -125,6 +125,7 @@ void train_slp_model(const D &ds, // const int n_epochs = 1; int step = 0; for (auto _ : range(n_epochs)) { + UNUSED(_); for (auto offset : range(n / batch_size)) { ++step; printf("step: %d\n", step); diff --git a/examples/utils.hpp b/examples/utils.hpp index 21d43bb..e1d53be 100644 --- a/examples/utils.hpp +++ b/examples/utils.hpp @@ -57,3 +57,10 @@ class show_name } }; } // namespace nn::layers::debug + +inline void make_unuse(void *) {} + +#define UNUSED(e) \ + { \ + make_unuse(&e); \ + } diff --git a/include/nn/experimental/bits/ops/utility.hpp b/include/nn/experimental/bits/ops/utility.hpp index cc811e9..fc62344 100644 --- a/include/nn/experimental/bits/ops/utility.hpp +++ b/include/nn/experimental/bits/ops/utility.hpp @@ -46,7 +46,12 @@ class onehot const auto y_flat = nn::ops::as_matrix>(y); const auto n = x.shape().size(); for (auto i : range(n)) { - y_flat.at(i, x.data()[i]) = static_cast(1); + const dim_t j = x.data()[i]; + if (0 <= j && j < k_) { + y_flat.at(i, j) = static_cast(1); + } else { + // TODO: maybe throw runtime_error(""): + } } } };