-
Notifications
You must be signed in to change notification settings - Fork 0
/
第三周编程作业
338 lines (278 loc) · 10.2 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
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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
import numpy as np
import matplotlib.pyplot as plt
from testCases import *
import sklearn
import sklearn.datasets
import sklearn.linear_model
from planar_utils import plot_decision_boundary,sigmoid,load_planar_dataset,load_extra_datasets
np.random.seed(1)
X,Y=load_planar_dataset()#加载数据集
#绘制散点图
plt.scatter(X[0,:],X[1,:],c=np.squeeze(Y),s=40,cmap=plt.cm.Spectral)
#数据看起来像一朵红色(y=0)和一些蓝色(y=1)的数据点的花朵的图案
shape_X=X.shape
shape_Y=Y.shape
m=Y.shape[1]
print("X的维度是:"+str(shape_X))
print("Y的维度是:"+str(shape_Y))
print("数据集里面的数据有:"+str(m)+"个")
def layer_sizes(X,Y):
"""
参数:
X - 输入数据集,维度为(输入的数量,训练/测试的数量)
Y - 标签,维度为(输出的数量,训练/测试数量)
返回:
n_x - 输入层的数量
n_h - 隐藏层的数量
n_y - 输出层的数量
"""
n_x=X.shape[0] #输入层
n_h=4 #隐藏层,硬编码为4
n_y=Y.shape[0]
return(n_x,n_h,n_y)
print("=========================测试layer_sizes=========================")
X_asses , Y_asses = layer_sizes_test_case()
(n_x,n_h,n_y) = layer_sizes(X_asses,Y_asses)
print("输入层的节点数量为: n_x = " + str(n_x))
print("隐藏层的节点数量为: n_h = " + str(n_h))
print("输出层的节点数量为: n_y = " + str(n_y))
#初始化模型的参数
def initialize_parameters(n_x,n_h,n_y):
"""
参数:
n_x - 输入层节点的数量
n_h - 隐藏层节点的数量
n_y - 输出层节点的数量
返回:
parameters - 包含参数的字典:
W1:权重矩阵,维度为(n_h,n_x)
b1:偏向量,维度为(n_h,1)
W2:权重矩阵,维度为(n_y,n_h)
b1:偏向量,维度为(n_y,1)
"""
np.random.seed(2)#指定一个随机种子
W1=np.random.randn(n_h,n_x)*0.01
b1=np.zeros(shape=(n_h,1))
W2=np.random.randn(n_y,n_h)*0.01
b2=np.zeros(shape=(n_y,1))
#使用断言确保数据格式是正确的
assert(W1.shape==(n_h,n_x))
assert(b1.shape==(n_h,1))
assert(W2.shape==(n_y,n_h))
assert(b2.shape==(n_y,1))
parameters={
"W1":W1,
"b1":b1,
"W2":W2,
"b2":b2
}
return parameters
print("=========================测试initialize_parameters=========================")
n_x , n_h , n_y = initialize_parameters_test_case()
parameters = initialize_parameters(n_x , n_h , n_y)
print("W1 = " + str(parameters["W1"]))
print("b1 = " + str(parameters["b1"]))
print("W2 = " + str(parameters["W2"]))
print("b2 = " + str(parameters["b2"]))
#前向传播
def forward_propagation(X,parameters):
"""
参数:
X - 维度为(n_x,m)的输入数据
parameters - 初始化函数initialize_parameters的输出
返回:
A2 - 使用sigmoid()函数计算的第二次激活后的数值
cache - 包含“Z1” “A1” “Z2” “A2”的字典类型变量
"""
W1=parameters["W1"]
b1=parameters["b1"]
W2=parameters["W2"]
b2=parameters["b2"]
#前向传播计算A2
Z1=np.dot(W1,X)+b1
A1=np.tanh(Z1)
Z2=np.dot(W2,A1)+b2
A2=sigmoid(Z2)
assert(A2.shape==(1,X.shape[1]))
cache={
"Z1":Z1,
"A1":A1,
"Z2":Z2,
"A2":A2
}
return (A2,cache)
print("=========================测试forward_propagation=========================")
X_assess, parameters = forward_propagation_test_case()
A2, cache = forward_propagation(X_assess, parameters)
print(np.mean(cache["Z1"]),np.mean(cache["A1"]),np.mean(cache["Z2"]),np.mean(cache["A2"]))
def compute_cost(A2,Y,parameters):
"""
计算交叉熵
参数:
A2 - 使用sigmoid()函数计算的第二次激活后的数值
Y- "True"标签向量,维度为(1,数量)
parameters - 包含W1,B1,W2,B2的字典类型变量
返回:
成本
"""
m=Y.shape[1]
#计算成本
logprobs=np.multiply(np.log(A2),Y)+np.multiply(np.log(1-A2),(1-Y))
cost=-np.sum(logprobs)/m
cost=float(np.squeeze(cost))
assert (isinstance(cost,float))
return cost
print("=========================测试compute_cost=========================")
A2 , Y_assess , parameters = compute_cost_test_case()
print("cost = " + str(compute_cost(A2,Y_assess,parameters)))
#构建反向传播
def backward_propagation(parameters,cache,X,Y):
"""
参数:
X- 输入数据,维度为(2,数量)
Y- "True"标签,维度为(1,数量)
返回:
grads- 包含w和b的导数的一个字典类型的变量
"""
m = X.shape[1]
W1=parameters["W1"]
W2=parameters["W2"]
A1=cache["A1"]
A2=cache["A2"]
dZ2=A2-Y
dW2=(1/m)*np.dot(dZ2,A1.T)
db2=(1/m)*np.sum(dZ2,axis=1,keepdims=True)
dZ1=np.multiply(np.dot(W2.T,dZ2),1-np.power(A1,2))
dW1=(1/m)*np.dot(dZ1,X.T)
db1=(1/m)*np.sum(dZ1,axis=1,keepdims=True)
grads={
"dW1":dW1,
"db1":db1,
"dW2":dW2,
"db2":db2
}
return grads
print("=========================测试backward_propagation=========================")
parameters, cache, X_assess, Y_assess = backward_propagation_test_case()
grads = backward_propagation(parameters, cache, X_assess, Y_assess)
print ("dW1 = "+ str(grads["dW1"]))
print ("db1 = "+ str(grads["db1"]))
print ("dW2 = "+ str(grads["dW2"]))
print ("db2 = "+ str(grads["db2"]))
#更新参数
def update_parameters(parameters,grads,learning_rate=1.2):
"""
参数:
parameters - 包含参数的字典类型的变量。
grads - 包含导数值的字典类型的变量。
learning_rate - 学习速率
返回:
parameters - 包含更新参数的字典类型的变量。
"""
W1,W2=parameters["W1"],parameters["W2"]
b1,b2=parameters["b1"],parameters["b2"]
dW1,dW2=grads["dW1"],grads["dW2"]
db1,db2=grads["db1"],grads["db2"]
W1=W1-learning_rate*dW1
b1=b1-learning_rate*db1
W2=W2-learning_rate*dW2
b2=b2-learning_rate*db2
parameters={
"W1":W1,
"b1":b1,
"W2":W2,
"b2":b2
}
return parameters
print("=========================测试update_parameters=========================")
parameters, grads = update_parameters_test_case()
parameters = update_parameters(parameters, grads)
print("W1 = " + str(parameters["W1"]))
print("b1 = " + str(parameters["b1"]))
print("W2 = " + str(parameters["W2"]))
print("b2 = " + str(parameters["b2"]))
#将以上函数整合到nn_model()中,使神经网络模型以正确的顺序使用先前的功能
def nn_model(X,Y,n_h,num_iterations,print_cost=False):
"""
参数:
X - 数据集,维度为(2,示例数)
Y - 标签,维度为(1,示例数)
n_h - 隐藏层的数量
num_iterations - 迭代次数
print_cost - 如果为True,则每下降1000次迭代打印一次成本数值
返回:
parameters- 模型学习的参数,它们可以用来进行预测
"""
np.random.seed(3)#指定随机种子
n_x=layer_sizes(X,Y)[0]
n_y=layer_sizes(X,Y)[2]
parameters=initialize_parameters(n_x,n_h,n_y)
W1=parameters["W1"]
b1=parameters["b1"]
W2=parameters["W2"]
b2=parameters["b2"]
for i in range(num_iterations):
A2,cache=forward_propagation(X,parameters)
cost=compute_cost(A2,Y,parameters)
grads=backward_propagation(parameters,cache,X,Y)
parameters=update_parameters(parameters,grads,learning_rate=0.5)
if print_cost:
if i%1000==0:
print("第",i,"次循环,成本为:"+str(cost))
return parameters
print("=========================测试nn_model=========================")
X_assess, Y_assess = nn_model_test_case()
parameters = nn_model(X_assess, Y_assess, 4, num_iterations=10000, print_cost=False)
print("W1 = " + str(parameters["W1"]))
print("b1 = " + str(parameters["b1"]))
print("W2 = " + str(parameters["W2"]))
print("b2 = " + str(parameters["b2"]))
#预测,使用向前传播来预测结果
def predict(parameters,X):
"""
使用学习的参数,为X中每个示例预测一个类
参数:
parameters- 包含学习的参数的字典类型的变量
X- 输入数据(n_x,m)
返回:
predictions- 我们模型预测的向量(红色:0,蓝色:1)
"""
A2,cache=forward_propagation(X,parameters)
predictions=np.round(A2)
return predictions
print("=========================测试predict=========================")
parameters, X_assess = predict_test_case()
predictions = predict(parameters, X_assess)
print("预测的平均值 = " + str(np.mean(predictions)))
#现在把所有的东西都做完了,开始正式运行
parameters=nn_model(X,Y,n_h=4,num_iterations=10000,print_cost=True)
#绘制边界
plot_decision_boundary(lambda x: predict(parameters,x.T), X, Y) #绘制决策边界
plt.title("Decision Boundary for hidden layer size"+str(4)) #图标题
predictions=predict(parameters,X)
print('准确率:%d' % float((np.dot(Y,predictions.T)+np.dot(1-Y,1-predictions.T))/float(Y.size)*100)+'%')
#更改隐藏层节点数量
plt.figure(figsize=(16,32))
hidden_layer_sizes=[1,2,3,4,5,20,50]#隐藏层数量
for i,n_h in enumerate(hidden_layer_sizes):
plt.subplot(5,2,i+1)
plt.title('Hidden Layer of size %d' % n_h)
parameters=nn_model(X,Y,n_h,num_iterations=5000)
plot_decision_boundary(lambda x: predict(parameters,x.T), X, Y)
predictions=predict(parameters,X)
accuracy = float((np.dot(Y,predictions.T)+np.dot(1-Y,1-predictions.T))/float(Y.size)*100)
print("隐藏层节点数量:{},准确率:{}%".format(n_h,accuracy))
#探索
#改变数据集
noisy_circles, noisy_moons, blobs, gaussian_quantiles, no_structure = load_extra_datasets()
datasets = {
"noisy_circles": noisy_circles,
"noisy_moons": noisy_moons,
"blobs": blobs,
"gaussian_quantiles": gaussian_quantiles}
dataset = "noisy_moons"
X, Y = datasets[dataset]
X, Y = X.T, Y.reshape(1, Y.shape[0])
if dataset == "blobs":
Y = Y % 2
plt.scatter(X[0, :], X[1, :], c=np.squeeze(Y), s=40, cmap=plt.cm.Spectral)