一個嘗試在做C++計算引擎的更新(新增神經網路架構)
上一篇
最近自己嘗試做一個計算引擎 , 目前已經實現大部分矩陣介面
專案開始日期 : 2019/10/01
目前專案總程式碼 : 810 行
測試 : main。cpp | nerual_network。cpp | 新增全連線神經網路架構(新增全連線網路正向傳播和反向傳播的測試demo)
測試環境:
MacBook Pro
編譯器環境:
Configured with: ——prefix=/Applications/Xcode。app/Contents/Developer/usr ——with-gxx-include-dir=/Applications/Xcode。app/Contents/Developer/Platforms/MacOSX。platform/Developer/SDKs/MacOSX10。14。sdk/usr/include/c++/4。2。1
Apple LLVM version 10。0。1 (clang-1001。0。46。4)
Target: x86_64-apple-darwin18。7。0
Thread model: posix
ps : 前一段時間一些朋友給了我不少建議,我還沒來得及更新,打算先實現大部分主流功能,再做最佳化哈
目前介面(均已測試透過):
API:
Matrix read_csv(string &file_path)讀取格式化檔案(csv),返回一個自動計算長度的矩陣。
實現格式化檔案寫入介面。比較pandas。to_csv。
矩陣廣播機制,實現padding介面
全連線層前向傳播和反向傳播介面,支援自動求導
矩陣微分和自動求導介面封裝
int save_txt(Matrix mid1,string path = “。/”,string delimiter = “,”,string header=“。/”) 設計檔案流獲取檔案頭部介面 , 寫入格式化檔案 , 已設計支援矩陣型別資料寫入,支援自定義表頭,寫入檔案路徑 , 自定義分隔符,預設為“ , ”。
Create a matrix : create(row,cols)開闢一個矩陣結構的記憶體,元素初值為0;
Change the element for matrix void move_ele(int &ele1, int &ele2),修改某一個位置的元素的值。
Matrix1+Matrix2 : Matrix add(Matrix mid1,Matrix mid2,int flag=1),矩陣加和操作介面,可選位運算加速。
Flag is how to compete the ele ,default 1 ,bitwise operation(位運算加速)。
Matrix1-Matrix2 : Matrix subtract(Matrix mid1,Matrix mid2)
Matrix1*Matrix2 : Matrix mul(Matrix mid1,Matrix mid2)
Matrix1*n : Matrix times_mat(int times,Matrix mid1)
Matrix1‘s Transposition : Matrix get_T(Matrix mid1)矩陣轉置
Mul(matrix1,matrix2)矩陣乘積(完整數學定義)。
double* flatten(Matrix mid1) : Return a flattened array。矩陣展開
Matrix matrix_rs(Matrix mid1,int rs_row,int rs_col) 矩陣的結構壓縮
double matrix_sum(Matrix mid1)矩陣求和
double matrix_mean(Matrix mid1)均值
Matrix appply(Matrix mid1,Matrix mid2,int axis = 0)矩陣拼接
Matrix iloc(Matrix mid1,int start_x=0,int end_x=0,int start_y=0,int end_y=0)矩陣切片
Matrix mul_simple(Matrix mid1,Matrix mid2)為了貼合機器學習的需要,實現了矩陣對應元素相乘,請與傳統意義的矩陣乘法區分開。
Relu啟用函式矩陣介面
均方誤差矩陣介面
建立隨機權重矩陣介面
即將著手開發的是
卷積神經網路定義(包括但不限於卷積核,池化層定義,自定義損失介面)。
隨機森林演算法封裝。
主流網路架構實現。
新的demo程式實現5層全連線層,可自定義神經元和啟用函式,損失函式
#include
#include
#include
#include
#include
#include
#include
“。/autodiff/node。h”
#include
“。/matrix/matrix_def。h”
#include
“。/matrix/matrix_pro。h”
#include
“。/welcome/score_wel。cpp”
#include
“。/logistic/logistic_def。h”
#include
“。/file_pro/data_read。h”
#include
“。/grad_edge/matrix_grad。h”
using
namespace
std
;
clock_t
start
,
stop
;
double
duration
;
int
main
()
{
welcome
();
string
path
=
“。/data/new_data2。csv”
;
Matrix
data
=
read_csv
(
path
);
Matrix
bais
=
CreateMatrix
(
data
。
row
,
1
);
data
=
appply
(
data
,
bais
,
1
);
Matrix
y
=
iloc
(
data
,
0
,
0
,
3
,
4
);
Matrix
x_1
=
iloc
(
data
,
0
,
0
,
0
,
3
);
Matrix
x_2
=
get_T
(
x_1
);
double
alpha
=
0。002
;
int
max_epoch
=
1
;
Matrix
weight
=
CreateMatrix
(
3
,
1
);
change_va
(
weight
,
0
,
0
,
1
);
change_va
(
weight
,
1
,
0
,
1
);
change_va
(
weight
,
2
,
0
,
1
);
int
epoch
=
0
;
for
(
epoch
=
0
;
epoch
<=
max_epoch
;
epoch
++
)
{
cout
<<
“——————-split-line——————-”
<<
endl
;
Matrix
temp_mul
=
mul
(
x_1
,
weight
);
Matrix
h
=
e_sigmoid
(
temp_mul
);
Matrix
error
=
subtract
(
y
,
h
);
Matrix
temp_update
=
mul
(
x_2
,
error
);
Matrix
updata
=
add
(
weight
,
times_mat
(
alpha
,
temp_update
),
0
);
cout_mat
(
weight
);
cout
<<
“epoch: ”
<<
epoch
<<
“ error: ”
<<
matrix_sum
(
error
)
<<
endl
;
cout
<<
“——————-split-line——————-”
<<
endl
;
}
stop
=
clock
();
printf
(
“%f
\n
”
,
(
double
)(
stop
-
start
)
/
CLOCKS_PER_SEC
);
cout
<<
“——————autodiff for neraul network——————-”
<<
endl
;
Matrix
data_mine
=
CreateRandMat
(
2
,
1
);
Matrix
label
=
CreateMatrix
(
2
,
1
);
Matrix
weight1
=
CreateRandMat
(
2
,
2
);
Matrix
weight2
=
CreateRandMat
(
2
,
2
);
Matrix
weight3
=
CreateRandMat
(
2
,
2
);
Matrix
weight4
=
CreateRandMat
(
2
,
2
);
for
(
int
epoch
=
0
;
epoch
<
20
;
epoch
++
)
{
cout
<<
“————-epoch: ”
<<
epoch
<<
“——————”
<<
endl
;
// cout_mat(weight1);
edge_network
sequaltial
(
2
,
2
);
Matrix
output1
=
sequaltial
。
forward
(
data_mine
,
weight1
);
Matrix
output2
=
sequaltial
。
forward
(
output1
,
weight2
);
Matrix
output3
=
sequaltial
。
forward
(
output2
,
weight3
);
Matrix
output4
=
sequaltial
。
forward
(
output3
,
weight4
);
Matrix
output_end
=
sequaltial
。
end_layer_backward
(
label
,
output4
);
//get the forward
Matrix
backward1
=
sequaltial
。
backward
(
output_end
,
output3
,
weight4
);
Matrix
grad_w1w2
=
mul_simple
(
backward1
,
data_mine
);
Matrix
backward2
=
sequaltial
。
backward
(
backward1
,
output2
,
weight3
);
Matrix
grad_w3w4
=
mul_simple
(
backward2
,
data_mine
);
Matrix
backward3
=
sequaltial
。
backward
(
backward2
,
output1
,
weight2
);
Matrix
grad_w5w6
=
mul_simple
(
backward3
,
data_mine
);
Matrix
backward4
=
sequaltial
。
backward
(
backward3
,
output4
,
weight1
);
Matrix
grad_w7w8
=
mul_simple
(
backward4
,
data_mine
);
weight1
=
subtract
(
weight1
,
times_mat
(
0。0001
,
padding
(
grad_w1w2
,
2
,
2
)));
weight2
=
subtract
(
weight2
,
times_mat
(
0。0001
,
padding
(
grad_w3w4
,
2
,
2
)));
weight3
=
subtract
(
weight3
,
times_mat
(
0。0001
,
padding
(
grad_w5w6
,
2
,
2
)));
weight4
=
subtract
(
weight4
,
times_mat
(
0。0001
,
padding
(
grad_w7w8
,
2
,
2
)));
}
return
0
;
}
output
:
————-
epoch
:
0
——————
loss
:
4。65667
loss
:
3。28273
————-
epoch
:
1
——————
loss
:
4。65655
loss
:
3。28265
————-
epoch
:
2
——————
loss
:
4。65643
loss
:
3。28257
————-
epoch
:
3
——————
loss
:
4。65631
loss
:
3。28249
————-
epoch
:
4
——————
loss
:
4。65619
loss
:
3。2824
————-
epoch
:
5
——————
loss
:
4。65607
loss
:
3。28232
————-
epoch
:
6
——————
loss
:
4。65596
loss
:
3。28224
————-
epoch
:
7
——————
loss
:
4。65584
loss
:
3。28216
————-
epoch
:
8
——————
loss
:
4。65572
loss
:
3。28208
————-
epoch
:
9
——————
loss
:
4。6556
loss
:
3。282
————-
epoch
:
10
——————
loss
:
4。65548
loss
:
3。28192
————-
epoch
:
11
——————
loss
:
4。65536
loss
:
3。28184
————-
epoch
:
12
——————
loss
:
4。65524
loss
:
3。28176
————-
epoch
:
13
——————
loss
:
4。65512
loss
:
3。28168
————-
epoch
:
14
——————
loss
:
4。65501
loss
:
3。2816
————-
epoch
:
15
——————
loss
:
4。65489
loss
:
3。28152
————-
epoch
:
16
——————
loss
:
4。65477
loss
:
3。28144
————-
epoch
:
17
——————
loss
:
4。65465
loss
:
3。28136
————-
epoch
:
18
——————
loss
:
4。65453
loss
:
3。28128
————-
epoch
:
19
——————
loss
:
4。65441
loss
:
3。2812
目前實現的程式介面
API:
Matrix read_csv(string &file_path)讀取格式化檔案(csv),返回一個自動計算長度的矩陣。
實現格式化檔案寫入介面。比較pandas。to_csv。
矩陣廣播機制,實現padding介面
全連線層前向傳播和反向傳播介面,支援自動求導
矩陣微分和自動求導介面封裝
int save_txt(Matrix mid1,string path = “。/”,string delimiter = “,”,string header=“。/”) 設計檔案流獲取檔案頭部介面 , 寫入格式化檔案 , 已設計支援矩陣型別資料寫入,支援自定義表頭,寫入檔案路徑 , 自定義分隔符,預設為“ , ”。
Create a matrix : create(row,cols)開闢一個矩陣結構的記憶體,元素初值為0;
Change the element for matrix void move_ele(int &ele1, int &ele2),修改某一個位置的元素的值。
Matrix1+Matrix2 : Matrix add(Matrix mid1,Matrix mid2,int flag=1),矩陣加和操作介面,可選位運算加速。
Flag is how to compete the ele ,default 1 ,bitwise operation(位運算加速)。
Matrix1-Matrix2 : Matrix subtract(Matrix mid1,Matrix mid2)
Matrix1*Matrix2 : Matrix mul(Matrix mid1,Matrix mid2)
Matrix1*n : Matrix times_mat(int times,Matrix mid1)
Matrix1’s Transposition : Matrix get_T(Matrix mid1)矩陣轉置
Mul(matrix1,matrix2)矩陣乘積(完整數學定義)。
double* flatten(Matrix mid1) : Return a flattened array。矩陣展開
Matrix matrix_rs(Matrix mid1,int rs_row,int rs_col) 矩陣的結構壓縮
double matrix_sum(Matrix mid1)矩陣求和
double matrix_mean(Matrix mid1)均值
Matrix appply(Matrix mid1,Matrix mid2,int axis = 0)矩陣拼接
Matrix iloc(Matrix mid1,int start_x=0,int end_x=0,int start_y=0,int end_y=0)矩陣切片
Matrix mul_simple(Matrix mid1,Matrix mid2)為了貼合機器學習的需要,實現了矩陣對應元素相乘,請與傳統意義的矩陣乘法區分開。
Relu啟用函式矩陣介面
均方誤差矩陣介面
建立隨機權重矩陣介面 即將著手開發:
卷積神經網路定義(包括但不限於卷積核,池化層定義,自定義損失介面)。
隨機森林演算法封裝。
主流網路架構實現。
詳情見github,歡迎關注Star✨以及更好的建議: