Skip to content
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

Implement im2col and update conv2d #134

Merged
merged 10 commits into from
Aug 10, 2020
Merged

Conversation

philomath213
Copy link
Member

Description

  • Implement matrix vertical and horizontal scan.
  • Implement im2col (Image Block to Columns) in C++.
  • Update conv2d_im2col implementation in order to simplify the API.
  • Implement im2col_encoding, it will allow user apply a im2col on input matrix and compute the convolution layer using on TenSEAL, there's no need to pad the input and the kernel nor flatting them in Python.
  • Update tests.
  • Update Convolution notebook.

Affected Dependencies

None.

How has this been tested?

  • Unit tests.

Checklist

@philomath213 philomath213 added Type: New Feature ➕ Introduction of a completely new addition to the codebase Type: Improvement 📈 Performance improvement not introducing a new feature or requiring a major refactor labels Aug 6, 2020
Copy link
Member

@bcebere bcebere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! I've left just some minor observations.

tenseal/cpp/tensors/ckksvector.cpp Outdated Show resolved Hide resolved
tenseal/cpp/tensors/utils/utils.h Outdated Show resolved Hide resolved
tenseal/cpp/tensors/utils/utils.h Outdated Show resolved Hide resolved
* horizontally scan matrix (vector of vectors)
**/
template <typename T>
void horizontal_scan(const vector<vector<T>>& src, vector<T>& dst) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These operations might be easier to execute using a gsl::multi_span structure. For sure not for this PR, I don't know if they actually help. But they should prevent extra-copies

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I will check this out, maybe they will be helpful.

Comment on lines +85 to +98
// CKKSVector utils
m.def("im2col_encoding",
[](shared_ptr<TenSEALContext> ctx, vector<vector<double>> &input,
const size_t kernel_n_rows, const size_t kernel_n_cols,
const size_t stride) {
vector<vector<double>> view_as_window;
vector<double> final_vector;
size_t windows_nb = im2col(input, view_as_window, kernel_n_rows,
kernel_n_cols, stride);
vertical_scan(view_as_window, final_vector);
CKKSVector ckks_vector = CKKSVector(ctx, final_vector);
return make_pair(ckks_vector, windows_nb);
});

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe not in this PR, but the encoding shouldn't be doing encryption, just encoding it into a vector, then encryption should be something separate

Comment on lines +580 to +583
if (kernel.empty() ||
(any_of(kernel.begin(), kernel.end(),
[](const vector<double>& i) { return i.empty(); }))) {
throw invalid_argument("Kernel matrix can't be empty");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about something like this? to check whether the vector is a well organized matrix?

Suggested change
if (kernel.empty() ||
(any_of(kernel.begin(), kernel.end(),
[](const vector<double>& i) { return i.empty(); }))) {
throw invalid_argument("Kernel matrix can't be empty");
if (kernel.empty() ||
(any_of(kernel.begin(), kernel.end(),
[](const vector<double>& i) { return i.size() == kernel[0].size(); }))) {
throw invalid_argument("Kernel matrix can't be empty");

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test will be wrong in the case where kernel[0].size() == 0.
in other hand horizontal_scan always check if the rows have the same size.

Copy link
Member

@youben11 youben11 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work!

@philomath213 philomath213 merged commit f764d2e into master Aug 10, 2020
@philomath213 philomath213 deleted the philomath213/update-conv2d branch August 15, 2020 10:48
pierreeliseeflory pushed a commit to pierreeliseeflory/TenSEAL that referenced this pull request Apr 27, 2022
* implement matrix vertical and horizontal scan

* Image Block to Columns implementation

* update conv2d_im2col

* im2col_encoding python binding

* update conv2d_im2col python test

* update Convolution notebook

* linting

* use const ref to prevent the copy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Improvement 📈 Performance improvement not introducing a new feature or requiring a major refactor Type: New Feature ➕ Introduction of a completely new addition to the codebase
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants