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
%matplotlib inline
np.random.seed(1)
#加载数据集
X, Y = load_planar_dataset()
#数据可视化
plt.scatter(X[0, :], X[1, :], c=Y[0, :], s=40, cmap=plt.cm.Spectral);
#查看数据集
shape_X = X.shape
shape_Y = Y.shape
m = X.shape[1]
clf = sklearn.linear_model.LogisticRegressionCV();
clf.fit(X.T, Y[0, :].T);
plot_decision_boundary(lambda x: clf.predict(x), X, Y[0, :])
plt.title("Logistic Regression")
LR_predictions = clf.predict(X.T)
print ('Accuracy of logistic regression: %d ' % float((np.dot(Y,LR_predictions) + np.dot(1-Y,1-LR_predictions))/float(Y.size)*100) +
'% ' + "(percentage of correctly labelled datapoints)")
结果:Accuracy of logistic regression: 47 % (percentage of correctly labelled datapoints)
输入层,中间层,输出层神经元个数
def layer_sizes(X, Y):
n_x = X.shape[0]
n_h = 4
n_y = Y.shape[0]
return (n_x, n_h, n_y)
初始化化模型参数 W1,b1,W2,b2,采用parameters(字典)保存
def initialize_parameters(n_x, n_h, n_y):
W1 = np.random.randn(n_h,n_x)*0.01
b1 = np.zeros((n_h,1))
W2 = np.random.randn(n_y,n_h)*0.01
b2 = np.zeros((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
正向传播过程,获取预测值A2和保存有Z1、Z2、A1、A2的cache(字典,梯度更新需要用)
def forward_propagation(X, parameters):
W1 = parameters['W1']
b1 = parameters['b1']
W2 = parameters['W2']
b2 = parameters['b2']
Z1 = W1.dot(X) + b1
A1 = np.tanh(Z1)
Z2 = W2.dot(A1) + b2
A2 = sigmoid(Z2)
assert(A2.shape == (1, X.shape[1]))
cache = {"Z1": Z1,
"A1": A1,
"Z2": Z2,
"A2": A2}
return A2, cache
计算代价函数,采用以下公式:
(np.sum(-Y*np.log(A2) - (1-Y)*np.log(1-A2))/m
最终参数一样,cost就是不对)
def compute_cost(A2, Y, parameters):
m = Y.shape[1]
cost = np.sum(-np.multiply(np.log(A2),Y)-np.multiply(np.log(1-A2),1-Y))/m
# cost = np.sum(-Y*np.log(A2) - (1-Y)*np.log(1-A2))/m
cost = np.squeeze(cost)
assert(isinstance(cost, float))
return cost
反向传播,需要用到parameters(字典)中的W1,W2,b1,b2,和cache中的(Z1,A1,Z2,A2)
def backward_propagation(parameters, cache, X, Y):
m = X.shape[1]
W1 = parameters['W1']
W2 = parameters['W2']
A1 = cache['A1']
A2 = cache['A2']
dZ2 = A2 - Y
dW2 = dZ2.dot(A1.T)/m
db2 = 1/m * np.sum(dZ2,axis=1,keepdims=True)
dZ1 = W2.T.dot(dZ2)*(1 - np.power(A1,2))
dW1 = dZ1.dot(X.T)/m
db1 = 1/m*np.sum(dZ1,axis=1,keepdims=True)
grads = {"dW1": dW1,
"db1": db1,
"dW2": dW2,
"db2": db2}
return grads
梯度更新返回,更新过的parameters(字典),保存更新后的W1,W2,b1,b2
def update_parameters(parameters, grads, learning_rate = 1.2):
W1 = parameters['W1']
b1 = parameters['b1']
W2 = parameters['W2']
b2 = parameters['b2']
dW1 = grads['dW1']
db1 = grads['db1']
dW2 = grads['dW2']
db2 = 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
建立一个nn_model
def nn_model(X, Y, n_h, num_iterations = 10000, print_cost=False):
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']
#参数初始化后便不断计算cost,W1,W2,b1,b2导数,更新W1,W2,b1,b2
for i in range(0, 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=1.2)
if print_cost and i % 1000 == 0:
print ("Cost after iteration %i: %f" %(i, cost))
return parameters
预测,即用前向传播在最新parameters的A2值
def predict(parameters, X):
A2, cache = forward_propagation(X, parameters)
predictions = np.where(A2>0.5,1,0)
return 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[0, :])
plt.title("Decision Boundary for hidden layer size " + str(4))
predictions = predict(parameters, X)
print ('Accuracy: %d' % float((np.dot(Y,predictions.T) + np.dot(1-Y,1-predictions.T))/float(Y.size)*100) + '%')
结果:
Cost after iteration 0: 0.693162
Cost after iteration 1000: 0.258625
Cost after iteration 2000: 0.239334
Cost after iteration 3000: 0.230802
Cost after iteration 4000: 0.225528
Cost after iteration 5000: 0.221845
Cost after iteration 6000: 0.219094
Cost after iteration 7000: 0.220660
Cost after iteration 8000: 0.219408
Cost after iteration 9000: 0.218485
Accuracy: 90%
修改中间层神经元个数,查看准确率
plt.figure(figsize=(16, 32))
hidden_layer_sizes = [1, 2, 3, 4, 5, 10, 20]
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[0, :])
predictions = predict(parameters, X)
accuracy = float((np.dot(Y,predictions.T) + np.dot(1-Y,1-predictions.T))/float(Y.size)*100)
print ("Accuracy for {} hidden units: {} %".format(n_h, accuracy))
结果:
Accuracy for 1 hidden units: 67.5 %
Accuracy for 2 hidden units: 67.25 %
Accuracy for 3 hidden units: 90.75 %
Accuracy for 4 hidden units: 90.5 %
Accuracy for 5 hidden units: 91.25 %
Accuracy for 10 hidden units: 91.25 %
Accuracy for 20 hidden units: 91.0 %