From 3a5bf0c2ae6b8af4937c22573ca460fefa21c00a Mon Sep 17 00:00:00 2001 From: yester31 Date: Sat, 24 Jul 2021 21:17:11 +0900 Subject: [PATCH] add pooling (max&avg) --- Calc_Validation/compare.py | 4 +- Calc_Validation/conv2d.py | 2 +- Calc_Validation/conv2d_with_padding.py | 2 +- Calc_Validation/pooling.py | 26 ++++ Pooling/Pooling.sln | 31 +++++ Pooling/Pooling/Pooling.cpp | 177 ++++++++++++++++++++++++ Pooling/Pooling/Pooling.vcxproj | 159 +++++++++++++++++++++ Pooling/Pooling/Pooling.vcxproj.filters | 22 +++ Pooling/Pooling/Pooling.vcxproj.user | 4 + README.md | 20 +++ output/C_Tensor_avg_p | Bin 0 -> 64 bytes output/C_Tensor_max_p | Bin 0 -> 64 bytes output/C_Tensor_maxp | Bin 0 -> 64 bytes 13 files changed, 443 insertions(+), 4 deletions(-) create mode 100644 Calc_Validation/pooling.py create mode 100644 Pooling/Pooling.sln create mode 100644 Pooling/Pooling/Pooling.cpp create mode 100644 Pooling/Pooling/Pooling.vcxproj create mode 100644 Pooling/Pooling/Pooling.vcxproj.filters create mode 100644 Pooling/Pooling/Pooling.vcxproj.user create mode 100644 output/C_Tensor_avg_p create mode 100644 output/C_Tensor_max_p create mode 100644 output/C_Tensor_maxp diff --git a/Calc_Validation/compare.py b/Calc_Validation/compare.py index fb86906..a5d30fc 100644 --- a/Calc_Validation/compare.py +++ b/Calc_Validation/compare.py @@ -18,9 +18,9 @@ def compare_two_tensor(output, output_c): max_idx = idx r0 = output[idx] r = output_c[idx] - print("%6d output=%10.6f output_c=%10.6f diff=%.6f" % (idx, output[idx], output_c[idx], diff)) + print("%6d output_py=%10.6f output_c=%10.6f diff=%.6f" % (idx, output[idx], output_c[idx], diff)) if max_diff > 0: - print("cnt_total=%d cnt_diff=%d max_idx=%6d output=%10.6f output_c=%10.6f diff=%.6f" % ( + print("cnt_total=%d cnt_diff=%d max_idx=%6d output_py=%10.6f output_c=%10.6f diff=%.6f" % ( len(output), cnt_diff, max_idx, r0, r, max_diff)) else: print("prefect match and done!") \ No newline at end of file diff --git a/Calc_Validation/conv2d.py b/Calc_Validation/conv2d.py index 49000db..f220ca5 100644 --- a/Calc_Validation/conv2d.py +++ b/Calc_Validation/conv2d.py @@ -1,4 +1,4 @@ -import torch # v1.8.0 +import torch # torch 1.9.0+cu111 import numpy as np from compare import * diff --git a/Calc_Validation/conv2d_with_padding.py b/Calc_Validation/conv2d_with_padding.py index 59b9728..bf59767 100644 --- a/Calc_Validation/conv2d_with_padding.py +++ b/Calc_Validation/conv2d_with_padding.py @@ -1,4 +1,4 @@ -import torch # v1.8.0 +import torch # torch 1.9.0+cu111 import numpy as np from compare import * diff --git a/Calc_Validation/pooling.py b/Calc_Validation/pooling.py new file mode 100644 index 0000000..cafae44 --- /dev/null +++ b/Calc_Validation/pooling.py @@ -0,0 +1,26 @@ +import torch # torch 1.9.0+cu111 +import numpy as np +from compare import * + +IN = 2 +IC = 2 +IH = 4 +IW = 4 +PW = 3 +PS = 1 + +input_np = np.arange(1, IN * IC * IH * IW + 1).reshape(IN, IC, IH, IW) +input = torch.from_numpy(input_np).type(torch.FloatTensor) +print(input) + +#pooling = torch.nn.AvgPool2d((PW, PW), stride=(PS, PS)) # avg pooling 사용시 +pooling = torch.nn.MaxPool2d((PW, PW), stride=(PS, PS)) # max pooling 사용시 + +output = pooling(input) +print(output) + +#output_c = np.fromfile("../output/C_Tensor_avg_p", dtype=np.float32) +output_c = np.fromfile("../output/C_Tensor_max_p", dtype=np.float32) +output_py = output.detach().numpy().flatten() + +compare_two_tensor(output_py, output_c) \ No newline at end of file diff --git a/Pooling/Pooling.sln b/Pooling/Pooling.sln new file mode 100644 index 0000000..160cb38 --- /dev/null +++ b/Pooling/Pooling.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.1209 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Pooling", "Pooling\Pooling.vcxproj", "{6A4C01E1-366B-485A-9994-B6EAD66E9613}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6A4C01E1-366B-485A-9994-B6EAD66E9613}.Debug|x64.ActiveCfg = Debug|x64 + {6A4C01E1-366B-485A-9994-B6EAD66E9613}.Debug|x64.Build.0 = Debug|x64 + {6A4C01E1-366B-485A-9994-B6EAD66E9613}.Debug|x86.ActiveCfg = Debug|Win32 + {6A4C01E1-366B-485A-9994-B6EAD66E9613}.Debug|x86.Build.0 = Debug|Win32 + {6A4C01E1-366B-485A-9994-B6EAD66E9613}.Release|x64.ActiveCfg = Release|x64 + {6A4C01E1-366B-485A-9994-B6EAD66E9613}.Release|x64.Build.0 = Release|x64 + {6A4C01E1-366B-485A-9994-B6EAD66E9613}.Release|x86.ActiveCfg = Release|Win32 + {6A4C01E1-366B-485A-9994-B6EAD66E9613}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {94BE9491-2126-4B38-BF86-5D2A9416C610} + EndGlobalSection +EndGlobal diff --git a/Pooling/Pooling/Pooling.cpp b/Pooling/Pooling/Pooling.cpp new file mode 100644 index 0000000..3a2e176 --- /dev/null +++ b/Pooling/Pooling/Pooling.cpp @@ -0,0 +1,177 @@ +// 2021-7-24 by YH PARK + +#include +#include +#include +#include +#include +#include +#include +using namespace std; +using namespace chrono; + +/*************************************************************************** + Pooling algotirhm (avg & max) +****************************************************************************/ + +void avgPooling(vector& avgPoolingOutput, vector& avgPoolingInput, int input_n, int input_c, int input_h, int input_w, int poolingWindow, int poolingStride, int poolingOutputHeight, int poolingOutputWidth) { + //cout << "===== AvgPooling ===== \n"; + //avgPoolingOutput.resize(input_n*input_c*poolingOutputHeight*poolingOutputWidth); + float poolingWindowAreaInverse = 1.f / (poolingWindow * poolingWindow); + int temp1i = input_h * input_w * input_c; + int temp1o = poolingOutputHeight * poolingOutputWidth * input_c; + for (int ⁠n_idx = 0; ⁠n_idx < input_n; ⁠n_idx++) + { + int temp2i = ⁠n_idx * temp1i; + int temp2o = ⁠n_idx * temp1o; + for (int ⁠c_idx = 0; ⁠c_idx < input_c; ⁠c_idx++) + { + int temp3i = ⁠c_idx * input_w * input_h + temp2i; + int temp3o = ⁠c_idx * poolingOutputHeight * poolingOutputWidth + temp2o; + for (int rowStride = 0; rowStride < poolingOutputHeight; rowStride++) { + int temp4o = rowStride * poolingOutputWidth + temp3o; + for (int colStride = 0; colStride < poolingOutputWidth; colStride++) { + float sum = 0; + int g_idx_o = colStride + temp4o; + for (int x = rowStride * poolingStride; x < rowStride * poolingStride + poolingWindow; x++) { + int temp4i = x * input_w + temp3i; + for (int y = colStride * poolingStride; y < colStride * poolingStride + poolingWindow; y++) { + int ⁠g_idx_i = y + temp4i; + sum += avgPoolingInput[⁠g_idx_i]; + } + } + avgPoolingOutput[g_idx_o] = sum * poolingWindowAreaInverse; + } + } + } + } +} + +void maxPooling(vector& maxPoolingOutput, vector& maxPoolingInput, int input_n, int input_c, int input_h, int input_w, int poolingWindow, int poolingStride, int poolingOutputHeight, int poolingOutputWidth) { + cout << "===== maxPooling ===== \n"; + + int temp1i = input_h * input_w * input_c; + int temp1o = poolingOutputHeight * poolingOutputWidth * input_c; + for (int ⁠n_idx = 0; ⁠n_idx < input_n; ⁠n_idx++) + { + int temp2i = ⁠n_idx * temp1i; + int temp2o = ⁠n_idx * temp1o; + for (int ⁠c_idx = 0; ⁠c_idx < input_c; ⁠c_idx++) + { + int temp3i = ⁠c_idx * input_w * input_h + temp2i; + int temp3o = ⁠c_idx * poolingOutputHeight * poolingOutputWidth + temp2o; + for (int rowStride = 0; rowStride < poolingOutputHeight; rowStride++) + { + int temp4o = rowStride * poolingOutputWidth + temp3o; + for (int colStride = 0; colStride < poolingOutputWidth; colStride++) + { + float maxValue = 0; + int g_idx_o = colStride + temp4o; + for (int x = rowStride * poolingStride; x < rowStride * poolingStride + poolingWindow; x++) + { + int temp4i = x * input_w + temp3i; + for (int y = colStride * poolingStride; y < colStride * poolingStride + poolingWindow; y++) + { + int ⁠g_idx_i = y + temp4i; + if (maxValue < maxPoolingInput[⁠g_idx_i]) + { + maxValue = maxPoolingInput[⁠g_idx_i]; + } + } + } + maxPoolingOutput[g_idx_o] = maxValue; + } + } + } + } +} + + + +void valueCheck(vector& Input, int IN, int IC, int IH, int IW, bool one = false) { + std::cout << "===== valueCheck func =====" << std::endl; + if (one) IN = 1; + int N_offset = IC * IH * IW; + int C_offset, H_offset, W_offset, g_idx; + for (int ⁠n_idx = 0; ⁠n_idx < IN; ⁠n_idx++) { + C_offset = ⁠n_idx * N_offset; + for (int ⁠c_idx = 0; ⁠c_idx < IC; ⁠c_idx++) { + H_offset = ⁠c_idx * IW * IH + C_offset; + for (int ⁠h_idx = 0; ⁠h_idx < IH; ⁠h_idx++) { + W_offset = ⁠h_idx * IW + H_offset; + for (int w_idx = 0; w_idx < IW; w_idx++) { + g_idx = w_idx + W_offset; + std::cout << setw(5) << Input[g_idx] << " "; + }std::cout << std::endl; + }std::cout << std::endl; std::cout << std::endl; + } + } +} + +void scalarTensor(vector& output, int OC, int IC, int KH, int KW, float start = 1.f, int step = 0) { + std::cout << "===== scalarTensor func =====" << std::endl; + std::cout << "Tensor[" << OC << "][" << IC << "][" << KH << "][" << KW << "]" << std::endl << std::endl; + int N_offset = IC * KH * KW; + int C_offset, H_offset, W_offset, g_idx; + for (int ⁠n_idx = 0; ⁠n_idx < OC; ⁠n_idx++) { + C_offset = ⁠n_idx * N_offset; + for (int ⁠c_idx = 0; ⁠c_idx < IC; ⁠c_idx++) { + H_offset = ⁠c_idx * KH * KW + C_offset; + for (int ⁠h_idx = 0; ⁠h_idx < KH; ⁠h_idx++) { + W_offset = ⁠h_idx * KW + H_offset; + for (int w_idx = 0; w_idx < KW; w_idx++) { + g_idx = w_idx + W_offset; + start += step; + output[g_idx] = start; + } + } + } + } +} + +void tofile(vector &Buffer, string fname = "../../output/C_Tensor") { + std::ofstream fs(fname, ios::binary); + if (fs.is_open()) + fs.write((const char*)Buffer.data(), Buffer.size() * sizeof(float)); + fs.close(); + std::cout << "the output file produced in output folder." << std::endl; +} + +int main() +{ + int IN = 2; + int IC = 2; + int IH = 4; + int IW = 4; + + // d[IN][IC][IH][IW] + // 임시 input 값 + vector input(IN * IC * IH * IW); + scalarTensor(input, IN, IC, IH, IW, 0, 1); + valueCheck(input, IN, IC, IH, IW, 1); + + int poolingWindow = 3; + int poolingStride = 1; + int poolingOutputHeight = ((IH - poolingWindow) / poolingStride) + 1; + int poolingOutputWidth = ((IW - poolingWindow) / poolingStride) + 1; + int poolingOutputSize = IN * IC * poolingOutputHeight * poolingOutputWidth; + vector poolingOutput(poolingOutputSize); + + long long start_usec = duration_cast(system_clock::now().time_since_epoch()).count(); + + maxPooling(poolingOutput, input, IN, IC, IH, IW, poolingWindow, poolingStride, poolingOutputHeight, poolingOutputWidth); + //avgPooling(poolingOutput, input, IN, IC, IH, IW, poolingWindow, poolingStride, poolingOutputHeight, poolingOutputWidth); + + long long end_usec = duration_cast(system_clock::now().time_since_epoch()).count(); + int frame_sec = int(end_usec - start_usec); + + valueCheck(poolingOutput, IN, IC, poolingOutputHeight, poolingOutputWidth, 1); + + std::cout << "======================================================" << std::endl; + std::cout << "dur time :: " << frame_sec << " [micro sec]" << std::endl; + + tofile(poolingOutput, "../../output/C_Tensor_max_p"); // max pooling 사용시 + //tofile(poolingOutput, "../../output/C_Tensor_avg_p"); // avg pooling 사용시 + +} + diff --git a/Pooling/Pooling/Pooling.vcxproj b/Pooling/Pooling/Pooling.vcxproj new file mode 100644 index 0000000..f7626b8 --- /dev/null +++ b/Pooling/Pooling/Pooling.vcxproj @@ -0,0 +1,159 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {6A4C01E1-366B-485A-9994-B6EAD66E9613} + Win32Proj + Pooling + 10.0.17763.0 + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + Disabled + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + + + Level3 + Disabled + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + + + Level3 + MaxSpeed + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + Level3 + MaxSpeed + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/Pooling/Pooling/Pooling.vcxproj.filters b/Pooling/Pooling/Pooling.vcxproj.filters new file mode 100644 index 0000000..7c3f8fc --- /dev/null +++ b/Pooling/Pooling/Pooling.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 소스 파일 + + + \ No newline at end of file diff --git a/Pooling/Pooling/Pooling.vcxproj.user b/Pooling/Pooling/Pooling.vcxproj.user new file mode 100644 index 0000000..be25078 --- /dev/null +++ b/Pooling/Pooling/Pooling.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/README.md b/README.md index 4c042a1..4f91650 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,30 @@ DL_Layer ============= 딥러닝 프레임워크 만들기 +아키텍쳐 설계 +------------ + + + + 기능 ------------- + +## 완성 - Conservertive_Convolution - Zero Padding +- Pooling (Avg, Max) + +## 예정 +- Eltwise (Prod, Sum) +- Activation (Tan, Sigmoid, ReLU, Swish) +- Reshape +- Dense +- Softmax +- BatchNorm +- Transformer +- GlobalAvgPooling +- DataLoader 검증 ------------- diff --git a/output/C_Tensor_avg_p b/output/C_Tensor_avg_p new file mode 100644 index 0000000000000000000000000000000000000000..92ef23e748cb74c77f37741f8290dd5293345016 GIT binary patch literal 64 zcmZQzIN-p*@BoMv92po4fOrEC?*QTpKzsv;C7c)-WPn%$h;@KC0*GUPI0J}toB)8~ B3nu^o literal 0 HcmV?d00001 diff --git a/output/C_Tensor_max_p b/output/C_Tensor_max_p new file mode 100644 index 0000000000000000000000000000000000000000..52437ad7503d88caa1b7bdcfc12caf183ae5498b GIT binary patch literal 64 zcmWN=F%bYD36KnU!ow&SLZM@=+lT8Yi8};%3JOTi6QP literal 0 HcmV?d00001 diff --git a/output/C_Tensor_maxp b/output/C_Tensor_maxp new file mode 100644 index 0000000000000000000000000000000000000000..92ef23e748cb74c77f37741f8290dd5293345016 GIT binary patch literal 64 zcmZQzIN-p*@BoMv92po4fOrEC?*QTpKzsv;C7c)-WPn%$h;@KC0*GUPI0J}toB)8~ B3nu^o literal 0 HcmV?d00001