-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathNumSharpRegression.cs
More file actions
125 lines (116 loc) · 4.04 KB
/
Copy pathNumSharpRegression.cs
File metadata and controls
125 lines (116 loc) · 4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
using BenchmarkDotNet.Attributes;
using NumSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LinearRegression
{
public class NumSharpRegressionTest
{
public NDArray data;
public NDArray label;
public static double splitRate = 0.8;
public static int recordInterval = 10;
Model model;
[GlobalSetup]
public void Setup()
{
(data, label) = IrisLoader.Load(@"");
model = new Model(BenchmarkParam.FeatureCount);
model.InitializeParameters();
}
[Benchmark]
public void TrainNumSharp()
{
model.Train(data, label, BenchmarkParam.TrainEpochs, 0.001, recordInterval);
}
public static class IrisLoader
{
public static Dictionary<string, double> mapping;
static IrisLoader()
{
mapping = new Dictionary<string, double>();
mapping.Add("Iris-setosa", 0);
mapping.Add("Iris-versicolor", 1);
mapping.Add("Iris-virginica", 2);
}
public static (NDArray, NDArray) Load(string path)
{
NDArray data = np.random.normal(0, 2, new int[] { BenchmarkParam.FeatureCount, BenchmarkParam.DataLength });
NDArray label = np.random.normal(0, 1, new int[] { 1, BenchmarkParam.DataLength });
return (data, label);
}
}
public static class Sigmoid
{
public static NDArray Run(NDArray src)
{
return 1 / (1 - src);
}
}
public class Model
{
private int _dataDim;
public NDArray w;
public double b;
public Model(int dataDim)
{
_dataDim = dataDim;
InitializeParameters();
}
public (NDArray, double) InitializeParameters()
{
w = np.random.normal(0, 0.01f, new int[] { _dataDim, 1 }).astype(typeof(double));
b = 0;
return (w, b);
}
public (NDArray, NDArray, NDArray) ForwardAndBackwardPropagate(NDArray data, NDArray label)
{
var dataNum = data.shape[0];
// forward propagation
var z = w.transpose(new int[] { 0, 1 }) * data + b;
var predict = Sigmoid.Run(z);
var diff = predict - label;
var cost = np.mean((label * np.log2(predict) + (1 - label) * np.log2(1 - predict)) * (-1));
// back propagation
var dw = data * diff.transpose(new int[] { 0, 1 }) / dataNum;
var db = Sum(diff) / dataNum;
return (cost, dw, db);
}
private double Sum(NDArray src)
{
double res = 0;
for (int i = 0; i < src.shape[0]; i++)
{
for (int j = 0; j < src.shape[1]; j++)
{
res += src.GetDouble(i, j);
}
}
return res;
}
public NDArray UpdataParameters(NDArray data, NDArray label, double lr)
{
var (cost, gradW, gradB) = ForwardAndBackwardPropagate(data, label);
w -= lr * gradW;
b -= lr * gradB.GetDouble(0);
return cost;
}
public List<double> Train(NDArray data, NDArray label, int epochs, double lr, int recordInterval = 5)
{
var costs = new List<double>();
for (int i = 1; i <= epochs; i++)
{
var cost = UpdataParameters(data, label, lr);
if (i % recordInterval == 0)
{
costs.Add(cost.GetDouble(0));
}
}
return costs;
}
}
}
}