-
Notifications
You must be signed in to change notification settings - Fork 0
GRA-191: implement pool and crossEntropyLoss #80
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
base: task33_addOp
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 |
|---|---|---|
| @@ -1,13 +1,17 @@ | ||
| #include <cassert> | ||
| #include <vector> | ||
| #include <optional> | ||
| #include <algorithm> | ||
| #include <cmath> | ||
|
|
||
|
|
||
| #include "LazyBlob.h" | ||
| #include "Iterations.h" | ||
| #include "Allocator.h" | ||
| #include "Blob.h" | ||
|
|
||
| #define MAX_DIMS_COUNT 4 | ||
| #define EPS 1e-9 | ||
|
|
||
| const Shape& LazyBlob::shape() const { | ||
| if (shape_.has_value()) { | ||
|
|
@@ -568,3 +572,145 @@ std::ostream& operator<<(std::ostream& os, const LazyBlob &b) { | |
| } | ||
| return os; | ||
| } | ||
|
|
||
| class LazyBlobEntropy: public LazyBlob { | ||
| public: | ||
| const LazyBlob &a, &b; | ||
| const int classCount; | ||
| LazyBlobEntropy(const LazyBlob &a, const LazyBlob &b, int classCount): | ||
| a(a), b(b), classCount(classCount) {}; | ||
|
|
||
| void initShape() const final override { | ||
| shape_ = b.shape(); | ||
| } | ||
|
|
||
| float operator() (std::size_t k, std::size_t l, std::size_t i, std::size_t j) const override { | ||
| assert(b(k, l, i, j) < classCount); | ||
| // WARNING: если проблемы, меняем на случай с EPS | ||
| return std::log(a(k, l, i, (int) b(k, l, i, j))); | ||
| // return std::log(a(k, l, i, (int) b(k, l, i, j)) + EPS); | ||
| } | ||
| }; | ||
|
|
||
| class LazyBlobEntropyDerivative: public LazyBlob { | ||
| public: | ||
| const LazyBlob &a, &b; | ||
| const int classCount; | ||
| LazyBlobEntropyDerivative(const LazyBlob &a, const LazyBlob &b, int classCount): | ||
| a(a), b(b), classCount(classCount) {}; | ||
|
|
||
| void initShape() const final override { | ||
| shape_ = a.shape(); | ||
| } | ||
|
|
||
| float operator() (std::size_t k, std::size_t l, std::size_t i, std::size_t j) const override { | ||
| assert(b(k, l, i, j) < classCount); | ||
| if (j != (int) b(k, 0, 0, 0)) { | ||
| return 0; | ||
| } | ||
| // WARNING: если проблемы, меняем на случай с EPS | ||
| return - 1.0f / (a(k, l, i, j)); | ||
| // return - 1.0f / (a(k, l, i, j) + EPS); | ||
|
Comment on lines
+611
to
+613
Contributor
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. так а может чтоб проблем не было сразу на EPS поставим, ахахах, не?
Contributor
Author
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. нет, у torch такого нету |
||
| } | ||
| }; | ||
|
|
||
| const LazyBlob& LazyBlob::entropy(const LazyBlob& a, int classCount) const { | ||
| assert(shape().cols() == classCount); | ||
| assert(shape().dim4() == a.shape().dim4()); | ||
| assert(shape().dim3() == 1); | ||
| assert(shape().rows() == 1); | ||
| assert(a.shape().dim3() == 1); | ||
| assert(a.shape().rows() == 1); | ||
| assert(a.shape().cols() == 1); | ||
|
|
||
| void* location = Allocator::allocateBytes(sizeof(LazyBlobEntropy)); | ||
| return *(new(location) LazyBlobEntropy(*this, a, classCount)); | ||
| } | ||
|
|
||
| const LazyBlob& LazyBlob::entropyDerivative(const LazyBlob& a, int classCount) const { | ||
| assert(shape().cols() == classCount); | ||
| assert(shape().dim4() == a.shape().dim4()); | ||
| assert(shape().dim3() == 1); | ||
| assert(shape().rows() == 1); | ||
| assert(a.shape().dim3() == 1); | ||
| assert(a.shape().rows() == 1); | ||
| assert(a.shape().cols() == 1); | ||
| void* location = Allocator::allocateBytes(sizeof(LazyBlobEntropyDerivative)); | ||
| return *(new(location) LazyBlobEntropyDerivative(*this, a, classCount)); | ||
| } | ||
|
|
||
| class LazyBlobMaxPool: public LazyBlob { | ||
| public: | ||
| const LazyBlob &a; | ||
| LazyBlobMaxPool(const LazyBlob &a): a(a) {}; | ||
|
|
||
| void initShape() const final override { | ||
| shape_ = { | ||
| { | ||
| a.shape().dim4(), a.shape().dim3(), a.shape().rows() / 2, a.shape().cols() / 2 | ||
| }, | ||
| a.shape().dimsCount | ||
| }; | ||
| } | ||
|
|
||
| float operator() (std::size_t k, std::size_t l, std::size_t i, std::size_t j) const override { | ||
| return std::max( | ||
| std::max(a(k, l, i * 2, j * 2), a(k, l, i * 2 + 1, j * 2)), | ||
| std::max(a(k, l, i * 2, j * 2 + 1), a(k, l, i * 2 + 1, j * 2 + 1)) | ||
| ); | ||
| } | ||
| }; | ||
|
|
||
| class LazyBlobMaxPoolDerivative: public LazyBlob { | ||
| public: | ||
| const LazyBlob &a, &b; | ||
| LazyBlobMaxPoolDerivative(const LazyBlob &a, const LazyBlob& b): a(a), b(b) {}; | ||
|
|
||
| void initShape() const final override { | ||
| shape_ = a.shape(); | ||
| } | ||
|
|
||
| float operator() (std::size_t k, std::size_t l, std::size_t i, std::size_t j) const override { | ||
| size_t start_i = (i / 2) * 2; | ||
| size_t start_j = (j / 2) * 2; | ||
| size_t indexOfMax_i = start_i; | ||
| size_t indexOfMax_j = start_j; | ||
| float max = a(k, l, indexOfMax_i, indexOfMax_j); | ||
| if (max < a(k, l, start_i, start_j + 1)) { | ||
| indexOfMax_i = start_i; | ||
| indexOfMax_j = start_j + 1; | ||
| max = a(k, l, indexOfMax_i, indexOfMax_j); | ||
| } | ||
|
|
||
| if (max < a(k, l, start_i + 1, start_j)) { | ||
| indexOfMax_i = start_i + 1; | ||
| indexOfMax_j = start_j; | ||
| max = a(k, l, indexOfMax_i, indexOfMax_j); | ||
| } | ||
|
|
||
| if (max < a(k, l, start_i + 1, start_j + 1)) { | ||
| indexOfMax_i = start_i + 1; | ||
| indexOfMax_j = start_j + 1; | ||
| max = a(k, l, indexOfMax_i, indexOfMax_j); | ||
| } | ||
|
|
||
| if (indexOfMax_i == i && indexOfMax_j == j) | ||
| return b(k, l, i / 2, j / 2); | ||
|
|
||
| return 0.0f; | ||
| } | ||
| }; | ||
|
|
||
| const LazyBlob& LazyBlob::maxPool() const { | ||
| assert(shape().cols() % 2 == 0); | ||
| assert(shape().rows() % 2 == 0); | ||
| void* location = Allocator::allocateBytes(sizeof(LazyBlobEntropyDerivative)); | ||
| return *(new(location) LazyBlobMaxPool(*this)); | ||
| } | ||
|
|
||
| const LazyBlob& LazyBlob::maxPoolDerivative(const LazyBlob& b) const { | ||
| assert(shape().cols() % 2 == 0); | ||
| assert(shape().rows() % 2 == 0); | ||
| void* location = Allocator::allocateBytes(sizeof(LazyBlobMaxPoolDerivative)); | ||
| return *(new(location) LazyBlobMaxPoolDerivative(*this, b)); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -273,3 +273,49 @@ Shape EPS::computeDim(const vector<LazyBlobRef>& args) const { | |
| args1(a); | ||
| return a.shape(); | ||
| } | ||
|
|
||
| Blob Exp::compute(const vector<LazyBlobRef>& args) const { | ||
| args1(a); | ||
| return a.applying([](float x) { return std::exp(x); }); | ||
| } | ||
|
Comment on lines
+277
to
+280
Contributor
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. а зато вот экспоната это теперь операция....
Contributor
Author
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. а что это еще должно быть, как не операция? |
||
|
|
||
| vector<LazyBlobRef> Exp::grad(const Blob& grad, const vector<LazyBlobRef>& args) const { | ||
| args1(a); | ||
| return {grad * a.applying([](float x) { return std::exp(x); })}; | ||
| } | ||
|
|
||
| Shape Exp::computeDim(const vector<LazyBlobRef>& args) const { | ||
| args1(a); | ||
| return a.shape(); | ||
| } | ||
|
|
||
| Blob Entropy::compute(const vector<LazyBlobRef>& args) const { | ||
| args2(a, b); | ||
| return -a.entropy(b, classCount); | ||
| } | ||
|
|
||
| vector<LazyBlobRef> Entropy::grad(const Blob& grad, const vector<LazyBlobRef>& args) const { | ||
| args2(a, b); | ||
| return {grad.lazy().fill(a.shape()) * a.entropyDerivative(b, classCount), zeroBlob(b.shape())}; | ||
| } | ||
|
|
||
| Shape Entropy::computeDim(const vector<LazyBlobRef>& args) const { | ||
| args2(a, b); | ||
| (void)a; | ||
| return b.shape(); | ||
| } | ||
|
|
||
| Blob MaxPoolOp::compute(const vector<LazyBlobRef>& args) const { | ||
| args1(a); | ||
| return a.maxPool(); | ||
| } | ||
|
|
||
| vector<LazyBlobRef> MaxPoolOp::grad(const Blob& grad, const vector<LazyBlobRef>& args) const { | ||
| args1(a); | ||
| return {a.maxPoolDerivative(grad.lazy())}; | ||
| } | ||
|
|
||
| Shape MaxPoolOp::computeDim(const vector<LazyBlobRef>& args) const { | ||
| args1(a); | ||
| return {{a.shape().dim4(), a.shape().dim3(), a.shape().rows() / 2, a.shape().cols() / 2}, a.shape().dimsCount}; | ||
| } | ||
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.
даа, ну совсем понесло, теперь уже и производную запихиваем в, вообще то подразумевавшиеся как элементарные операции
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.
а производную по-другому не посчитать, очень тяжелая операция