View difference between Paste ID: xjDJy9kP and xRTk297d
SHOW: | | - or go back to the newest paste.
1-
function  HelonMethod(x0, y0, N)
1+
import numpy as np
2-
x0 = 1;
2+
import csv
3-
y0 = 2;
3+
import Circle_data
4-
N = 100;
4+
import matplotlib.pyplot as plt
5-
TOL = 1e-7;
5+
6-
i = 1;
6+
class Data(): #這個類別協助我們把資料轉成向量以及上好標籤
7-
fprintf(1, '次數          x_k               y_k            |x_k - y_k|       |x_k - sqrt(2)|    |y_k - sqrt(2)|\n');
7+
    def __init__(self, x, z):
8-
fprintf('___________________________________________________________________________________________________________________\n');
8+
        self.x = self.setX(x)
9-
    while i <= N
9+
        self.z = self.setZ(z)
10-
        x_new = (x0 + y0)/2;
10+
11-
        y_new = (2*x0*y0)/(x0 + y0);
11+
    def setX(self, x):
12-
        fprintf('%2d        %10.9f       %10.9f        %10.9f        %10.9f        %10.9f\n', i, x_new, y_new, abs(x_new - y_new), abs(x_new - sqrt(2)), abs(y_new - sqrt(2)));
12+
        return np.array([x]).T
13-
        if abs(x_new - y_new) < TOL
13+
14-
            break
14+
    def setZ(self, z):
15-
        end
15+
        return np.array([z]).T
16-
        x0 = x_new;
16+
17-
        y0 = y_new;
17+
def readData(): #這個函數用來讀取資料
18-
        i = i +1;
18+
    data = []
19-
    end
19+
    with open("output.csv", newline = "") as csvfile:
20-
end
20+
        rows = csv.DictReader(csvfile)
21
        for row in rows:
22
            x = [float(row['x1']), float(row['x2'])]
23
            z = [float(row['z'])]
24
            data.append(Data(x, z))
25
    return data
26
27
def f(x, function_name = 'ReLU'):
28
    if function_name == 'ReLU':
29
        return np.maximum(x, 0)
30
    elif function_name == 'tanh':
31
        return np.tanh(x)
32
    elif function_name == 'sigmoid':
33
        return 1 / (1 + np.exp(-x))
34
35
def df(x, Hidden_nodes, function_name = 'ReLU'):
36
    if function_name == 'ReLU':
37
        return np.eye(Hidden_nodes, dtype = 'float')*(np.where(x > 0, 1, 0))
38
    elif function_name == 'tanh':
39
        return np.eye(Hidden_nodes, dtype = 'float')*(1 - f(x, function_name)*f(x, function_name))
40
    elif function_name == 'sigmoid':
41
        return np.eye(Hidden_nodes, dtype = 'float')*(f(x, function_name)*(1 - f(x, function_name)))
42
43
def loss(N, Layer, data, loss_name ='MSE'):
44
    if loss_name == 'MSE':
45
        result = 0
46
        for i in range(N):
47
            result = result + (Layer[2][i] - data[i].z)**2
48
        return result / (2*N)
49
50
def forward(W1, W2, b, N, data, function_name = 'ReLU'): #向前傳播
51
    Layer1_1 = []
52
    Layer1_2 = []
53
    output = []
54
    Layer = []
55
    for i in range(N):
56
        Layer1_1.append(W1.dot(data[i].x)+b)  #計算每一層的值,並存取下來
57
        Layer1_2.append(f(Layer1_1[i], function_name))
58
        output.append(W2.dot(Layer1_2[i]))
59
    Layer.append(Layer1_1)
60
    Layer.append(Layer1_2)
61
    Layer.append(output)
62
    return Layer
63
64
def backward(W2, N, Layer, data, Hidden_nodes, function_name = 'ReLU'): #反向傳播
65
    dW2 = np.zeros((1, Hidden_nodes)) #計算W2的梯度
66
    for i in range(N):
67
        dW2 = dW2 + (Layer[2][i] - data[i].z)*(Layer[1][i].T)
68
    dW2 = dW2 / N
69
70
    dW1 = np.zeros((Hidden_nodes, 2)) #計算W1和b的梯度
71
    db = np.zeros((Hidden_nodes, 1))
72
    for i in range(N):
73
        temp = (Layer[2][i] - data[i].z)*W2.dot(df(Layer[0][i], Hidden_nodes, function_name))
74
        db = db + temp.T
75
        dW1 = dW1 + np.kron(temp.T, data[i].x.T) 
76
    dW1 = dW1 / N
77
    db = db / N
78
    return dW1, dW2, db
79
80
def Train(W1, W2, b, data, Hidden_nodes, N, learning_rate = 0.3, beta = 0.1, gamma = 0.9, beta1 = 0.9, beta2 = 0.999, Method = 'Adam', function_name = 'ReLU', loss_name ='MSE', train_size = 20000): 
81
    TOL=1e-7
82
    k = 1
83
    Layer = forward(W1, W2, b, N, data)
84
    best_result = 0
85
    mW1 = sW1 = vW1 = np.zeros(W1.shape)
86
    mW2 = sW2 = vW2 = np.zeros(W2.shape)
87
    mb = sb = vb = np.zeros(b.shape)
88
    train = []
89
    test = []
90
    G = [[], [], []]
91
    dG = [np.zeros(W1.shape), np.zeros(W2.shape), np.zeros(b.shape)]
92
    y = []
93
    for i in range(train_size):
94
        train.append(data[i])
95
    for i in range(N-train_size):
96
        test.append(data[train_size+i])
97
    Layer = forward(W1, W2, b, train_size, data, function_name = 'ReLU')
98
    while k <= 200:
99
        dW1, dW2, db = backward(W2, train_size, Layer, train, Hidden_nodes, function_name = 'ReLU')
100
        if Method == 'GradientDescent':
101
            W1 = W1 - learning_rate*dW1
102
            W2 = W2 - learning_rate*dW2
103
            b = b - learning_rate*db
104
        elif Method == 'Momentum':
105
            mW1 = beta*dW1 + gamma*mW1
106
            mW2 = beta*dW2 + gamma*mW2
107
            mb = beta*db + gamma*mb
108
            W1 = W1 - learning_rate*mW1
109
            W2 = W2 - learning_rate*mW2
110
            b = b - learning_rate*mb
111
        elif Method == 'Adagrad':
112
            G[0].append(dW1)
113
            G[1].append(dW2)
114
            G[2].append(db)
115
            for i in range(k):
116
                dG[0] += G[0][i]**2
117
                dG[1] += G[1][i]**2
118
                dG[2] += G[2][i]**2
119
            dG[0] = dG[0]**(1/2)
120
            dG[1] = dG[1]**(1/2)
121
            dG[2] = dG[2]**(1/2)
122
            W1 = W1 - (learning_rate/(dG[0] + TOL))*dW1
123
            W2 = W2 - (learning_rate/(dG[1] + TOL))*dW2
124
            b = b - (learning_rate/(dG[2] + TOL))*db
125
        elif Method == 'RMSProp':
126
            G[0].append(dW1)
127
            G[1].append(dW2)
128
            G[2].append(db)
129
            for i in range(k):
130
                dG[0] += G[0][i]**2
131
                dG[1] += G[1][i]**2
132
                dG[2] += G[2][i]**2
133
            dG[0] = (1/k)*dG[0]
134
            dG[1] = (1/k)*dG[1]
135
            dG[2] = (1/k)*dG[2]
136
            dG[0] = dG[0]**(1/2)
137
            dG[1] = dG[1]**(1/2)
138
            dG[2] = dG[2]**(1/2)
139
            W1 = W1 - (learning_rate/(dG[0] + TOL))*dW1
140
            W2 = W2 - (learning_rate/(dG[1] + TOL))*dW2
141
            b = b - (learning_rate/(dG[2] + TOL))*db
142
            
143
        elif Method == 'Adam':
144
            vW1 = beta1*vW1 + (1 - beta1)*dW1
145
            vW2 = beta1*vW2 + (1 - beta1)*dW2
146
            vb = beta1*vb + (1 - beta1)*db
147
            sW1 = beta2*sW1 + (1 - beta2)*dW1*dW1
148
            sW2 = beta2*sW2 + (1 - beta2)*dW2*dW2
149
            sb = beta2*sb + (1 - beta2)*db*db
150
            vW1_hat = vW1/(1 - beta1**k)
151
            vW2_hat = vW2/(1 - beta1**k)
152
            vb_hat = vb/(1 - beta1**k)
153
            sW1_hat = sW1/(1 - beta2**k)
154
            sW2_hat = sW2/(1 - beta2**k)
155
            sb_hat = sb/(1 - beta2**k)
156
            new_dW1 = learning_rate*vW1_hat/(np.sqrt(sW1_hat)+TOL)
157
            new_dW2 = learning_rate*vW2_hat/(np.sqrt(sW2_hat)+TOL)
158
            new_db = learning_rate*vb_hat/(np.sqrt(sb_hat)+TOL)
159
            W1 = W1 - new_dW1
160
            W2 = W2 - new_dW2
161
            b = b - new_db
162
        Layer = forward(W1, W2, b, train_size, train, function_name = 'ReLU')
163
        result = ANN(W1, W2, b, test, function_name = 'ReLU')
164
        y.append(float(loss(train_size, Layer, train, loss_name ='MSE')))
165
        print(k)
166
        print(y[k-1])
167
        if result[1] > best_result:
168
            best_result = result[1]
169
            bestW1 = W1
170
            bestW2 = W2
171
            bestb = b
172
        k = k + 1
173
    return bestW1, bestW2, bestb, y
174
175
def ANN(W1, W2, b, data, function_name = 'ReLU'):
176
    M = len(data)
177
    output = forward(W1, W2, b, M, data, function_name)
178
    ans = []
179
    correct = 0
180
    for i in range(M):
181
        if output[2][i] < 0:
182
            ans.append(-1)
183
        else:
184
            ans.append(1)
185
186
        if ans[i] == data[i].z:
187
            correct = correct + 1
188
    return [ans, correct / M]
189
190
def GenerateWeight(Hidden_nodes):
191
    W1 = np.random.rand(Hidden_nodes, 2) #權重矩陣W1和W2
192
    W2 = np.random.rand(1,Hidden_nodes)
193
    b = np.random.rand(Hidden_nodes,1) #偏置向量b
194
    return W1, W2, b
195
    
196
def GenerateTestData(M):
197
    temp = []
198
    test_data = []
199
    for i in range(M):
200
        r = np.random.randint(0, 2)
201
        if r == 1:
202
            temp.append(Circle_data.Data("blue"))
203
        else:
204
            temp.append(Circle_data.Data("red"))
205
        test_data.append(Data(temp[i].x, temp[i].z))
206
    return test_data
207
208
def main():
209
    data = readData() #把資料讀進來
210
    N = len(data)  #取得資料的個數
211
    Hidden_nodes = 4
212
    t = np.arange(100)
213
    """
214
    learning_rate = 0.3
215
    beta = 0.1
216
    gamma = 0.9
217
    beta1 = 0.9
218
    beta2 = 0.999
219
    Method = 'Adam'
220
    function_name = 'ReLU' 
221
    loss_name ='MSE' 
222
    train_size = 20000
223
    """
224
    W1, W2, b = GenerateWeight(Hidden_nodes)
225
    W1_1, W2_1, b_1, y_1 = Train(W1, W2, b, data, Hidden_nodes, N, learning_rate = 0.01, Method = 'GradientDescent')
226
    W1_2, W2_2, b_2, y_2 = Train(W1, W2, b, data, Hidden_nodes, N, learning_rate = 0.01, Method = 'Momentum')
227
    W1_3, W2_3, b_3, y_3 = Train(W1, W2, b, data, Hidden_nodes, N, learning_rate = 0.01, Method = 'Adagrad')
228
    W1_4, W2_4, b_4, y_4 = Train(W1, W2, b, data, Hidden_nodes, N, learning_rate = 0.01, Method = 'RMSProp')
229
    W1_5, W2_5, b_5, y_5 = Train(W1, W2, b, data, Hidden_nodes, N, learning_rate = 0.01, Method = 'Adam')
230
    
231
    plt.plot(t, y_1, 'b-', t, y_2, 'r-', t, y_3, 'g-', t, y_4, 'k-', t, y_5, 'y-')
232
    plt.show()
233
    plt.savefig('plot1.png')
234
    
235
    M = 1000
236
    test_data = GenerateTestData(M)
237
    
238
    result = ANN(W1_1, W2_1, b_1, test_data)
239
    print("命中率=",100*result[1],'%')
240
    result = ANN(W1_2, W2_2, b_2, test_data)
241
    print("命中率=",100*result[1],'%')
242
    result = ANN(W1_3, W2_3, b_3, test_data)
243
    print("命中率=",100*result[1],'%')
244
    result = ANN(W1_4, W2_4, b_4, test_data)
245
    print("命中率=",100*result[1],'%')
246
    result = ANN(W1_5, W2_5, b_5, test_data)
247
    print("命中率=",100*result[1],'%')
248
    
249
250
if __name__ == "__main__":
251
    main()