首页
论坛
课程
招聘
[原创]使用神经网络拟合数学函数
2022-11-23 09:44 2841

[原创]使用神经网络拟合数学函数

2022-11-23 09:44
2841

说明

这是一份练习代码,但感觉有点意思。

代码

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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
import numpy as np
 
'''
使用神经网络拟合数学函数
能用数学函数,或者确定的算法解决的事情,自然是最精确的,往往也是最省力的,但是,对于复杂的函数、系统,很难找到一条漂亮的数学函数或者算法,这时候可以考虑数据拟合,而神经网络可以做这个事情。
'''
 
class Dot(object):
    def forward(self, X, W):
        self.X=X
        self.W=W
        return np.dot(X, W)
 
    def backward(self, dout):
        return np.dot(dout, self.W.T), np.dot(self.X.T, dout)  # dX, dW
 
class Add(object):
    def forward(self, D, B):
        return D+B
 
    def backward(self, dout):
        return np.sum(dout, axis=0#纵向求和
 
class Affine(object):
    def __init__(self):
        self.dot=Dot()
        self.add=Add()
 
    def forward(self, X, W, B):
        T=self.dot.forward(X, W)
        return self.add.forward(T, B)
 
    def backward(self, dout):
        dB = self.add.backward(dout)
        dX, dW = self.dot.backward(dout)
 
        return dX, dW, dB
 
class Sigmoid(object):
    def forward(self, A):
        self.out=1/(1+np.exp(-A))
        return self.out
 
    def backward(self, dout):
        return dout*(1.0-self.out)*self.out
 
class Relu(object):
    def forward(self, A):
        self.mask=(A<=0)
        A[self.mask]=0     #会破坏原参数,但是这次使用之后后面就没用了,所以破坏就破坏了,还能省点空间
        return A
 
    def backward(self, dout):
        dout[self.mask]=0
        return dout
 
class SoftmaxWithLoss(object):
    def softmax(self, A):
        A=A-A.max(axis=1, keepdims=True)
        T=np.exp(A)
        return T/np.sum(T, axis=1, keepdims=True)
 
    def crossEntropyError(self, Z, Label):
        delta=0.000000001
        return -np.sum(np.log(Z+delta)*Label)/Z.shape[0]
 
    def forward(self, A, Label):
        self.Z=self.softmax(A)
        self.Label=Label
        return self.Z, self.crossEntropyError(self.Z, Label)
 
    def backward(self, dout=1):
        return (self.Z-self.Label)*dout/self.Z.shape[0]
 
class MSELoss(object):
    def forward(self, A, Label):
        self.A=A
        self.Label=Label
        # ∑( ∑(yi-xi)^2 )/batch_size
        return np.sum((A-Label)*(A-Label))/A.shape[0]    # A.shape[0] 为样本数,batch_size
 
    def backward(self, dout=1):
        return 2*(self.A-self.Label)*dout/self.A.shape[0]
 
class MyNN(object):
    def __init__(self):
        self.lr=0.01
        self.MAX_NUM=1000000
 
    def buildThreeLayerNet(self, input_dim, output_dim):
        N0=input_dim
        N1=10             #超参,为什么设置程这个数值,没啥理由,感觉
        N2=10
        N3=output_dim
 
        self.W1=np.random.randn(N0, N1)
        self.B1=np.random.randn(N1)
 
        self.W2=np.random.randn(N1, N2)
        self.B2=np.random.randn(N2)
 
        self.W3=np.random.randn(N2, N3)
        self.B3=np.random.randn(N3)
 
        self.affine1=Affine()
        self.activation1=Sigmoid()  #对于浅层的简单网络,相对于 Relu ,激活函数使用 Sigmoid 似乎表达能力更强一些
        self.affine2=Affine()
        self.activation2=Sigmoid()
        self.affine3=Affine()
        self.mseloss=MSELoss()
 
    def getMaxAbsValue(self, X):
        a=np.max(X)
        b=np.min(X)
        if b<0:
            b=-b
 
        ret=max(a,b)
        if ret==0:
            ret=0.0000001
        return ret
 
    def learn(self, X, Y):
        input_dim=len(X[0])
        output_dim=len(Y[0])
 
        self.MAX_X=self.getMaxAbsValue(X)
        self.MAX_Y=self.getMaxAbsValue(Y)
        X=np.array(X)/self.MAX_X
        Y=np.array(Y)/self.MAX_Y
 
        self.buildThreeLayerNet(input_dim, output_dim)
 
        for i in range(0, self.MAX_NUM):
            A1= self.affine1.forward(X, self.W1, self.B1)
            Z1=self.activation1.forward(A1)
            A2= self.affine2.forward(Z1, self.W2, self.B2)
            Z2=self.activation2.forward(A2)
            A3= self.affine3.forward(Z2, self.W3, self.B3)
            l = self.mseloss.forward(A3, Y)
 
            if i%10000==0:
                print(l)
 
                if l<0.0001:
                    #print(Y)
                    #print(A3)
                    #print(self.predict(X))
                    break
 
            dA3 = self.mseloss.backward(dout=1)
            dZ2, dW3, dB3 = self.affine3.backward(dA3)
            dA2 = self.activation2.backward(dZ2)
            dZ1, dW2, dB2 = self.affine2.backward(dA2)
            dA1 = self.activation1.backward(dZ1)
            dX, dW1, dB1 = self.affine1.backward(dA1)
 
            #根据梯度调整权重与偏置
            self.W1-=self.lr*dW1
            self.B1-=self.lr*dB1
            self.W2-=self.lr*dW2
            self.B2-=self.lr*dB2
            self.W3-=self.lr*dW3
            self.B3-=self.lr*dB3
 
    def predict(self, X):
        X=np.array(X)/self.MAX_X
 
        A1= self.affine1.forward(X, self.W1, self.B1)
        Z1=self.activation1.forward(A1)
        A2= self.affine2.forward(Z1, self.W2, self.B2)
        Z2=self.activation2.forward(A2)
        A3= self.affine3.forward(Z2, self.W3, self.B3)
        return A3*self.MAX_Y
 
class FitFx(object):
    def fx1(self, x):
        # f(x)=x-5
        return x-5
 
    def fx2(self, x):
        # f(x)=(x-5)^2
        return (x-5)**2
 
    def fx3(self, x):
        # f(x)=(x-5)^3+1
        return (x-5)**3
 
    def fx4(self, x):
        # f(x)=(x-5)^3+1
        return (x-5)**4
 
    def fx_xor(self, x1, x2):
        return x1^x2    # 异或
 
    def fit11(self, fx):
        print(fx)
        X=[[i] for i in range(0, 11)]
        print(X)
        Y=[[fx(a[0])] for a in X]
        print(Y)
 
        nn=MyNN()
        nn.learn(X,Y)
        print(nn.predict(X))
        #print(nn.predict([[1.2],[8.5]]))
 
    def fit21(self, fx):
        print(fx)
        X=[[d1,d2] for d1,d2 in [(0,0), (0,1), (1,0), (1,1)]]
        print(X)
        Y=[[fx(*a)] for a in X]
        print(Y)
 
        nn=MyNN()
        nn.learn(X,Y)
        print(nn.predict(X))
 
 
def main():
    m=FitFx()
    #m.fit11(m.fx1)
    m.fit11(m.fx2)
    #m.fit11(m.fx3)
    #m.fit11(m.fx4)
 
    #m.fit21(m.fx_xor)
 
if "__main__"==__name__:
    main()

效果
图片描述
图片描述


[2022冬季班]《安卓高级研修班(网课)》月薪两万班招生中~

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (5)
雪    币: 102
活跃值: 活跃值 (2108)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
DirtyAngle 活跃值 2022-11-23 10:46
2
0
wtf?
雪    币: 1111
活跃值: 活跃值 (1714)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
Jtian 活跃值 1 2022-11-24 10:25
3
0
DirtyAngle wtf?
虽说是个粗糙的轮子,但表现的却是人工智能的核心概念。
雪    币: 102
活跃值: 活跃值 (2108)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
DirtyAngle 活跃值 2022-11-24 10:38
4
0
Jtian 虽说是个粗糙的轮子,但表现的却是人工智能的核心概念。
我们是安全论坛啊.. 搞全连接网络,撸个svm瞅瞅
雪    币: 1111
活跃值: 活跃值 (1714)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
Jtian 活跃值 1 2022-11-24 14:44
5
0
DirtyAngle 我们是安全论坛啊.. 搞全连接网络,撸个svm瞅瞅
海纳百川有容乃大,不要把自己的视野锁死了,安全和人工智能并不矛盾,实际上也有很多相结合的案例。一千个读者有一千个哈姆雷特,有人喜欢,有人讨厌很正常。对我而言,实际上我只是把我觉得有趣的代码记录下来并分享出来而已(其实这样的机会可能不多了,工作压力是真的越来越大了),本身也是些基础的、不太严谨的东西,但是又有什么关系呢,你觉得无趣的话划走便是,论坛里的优秀、精华文章很多,应该有你感兴趣的内容。
雪    币: 102
活跃值: 活跃值 (2108)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
DirtyAngle 活跃值 2022-11-25 09:58
6
0
Jtian 海纳百川有容乃大,不要把自己的视野锁死了,安全和人工智能并不矛盾,实际上也有很多相结合的案例。一千个读者有一千个哈姆雷特,有人喜欢,有人讨厌很正常。对我而言,实际上我只是把我觉得有趣的代码记录下来并分 ...
开个玩笑而已 
游客
登录 | 注册 方可回帖
返回