吴恩达作业2 利用两层神经网络实现不同颜色点的分类,可更改隐藏层数量

任务:将400个两种颜色的点用背景色分为两类。

前面的还是建议重点学神经网络知识,至于数据集怎么做的后面在深究,首先先看看数据集,代码如下:

def load_planar_dataset():
    np.random.seed(1)
    m = 400 # number of examples
    N = int(m/2) # number of points per class
    D = 2 # dimensionality
    X = np.zeros((m,D)) # data matrix where each row is a single example
    Y = np.zeros((m,1), dtype='uint8') # labels vector (0 for red, 1 for blue)
    a = 4 # maximum ray of the flower

    for j in range(2):
        ix = range(N*j,N*(j+1))
        t = np.linspace(j*3.12,(j+1)*3.12,N) + np.random.randn(N)*0.2 # theta
        r = a*np.sin(4*t) + np.random.randn(N)*0.2 # radius
        X[ix] = np.c_[r*np.sin(t), r*np.cos(t)]
        Y[ix] = j
    X = X.T
    Y = Y.T
    return X, Y

打印看看返回的X,Y

由于X太多不方便粘贴,只打印了shape,可看出X是2行400列的矩阵(2,400),Y是1行400列矩阵(1,400)。

然后用X的数据作为二维的坐标点,Y的0,1作为分类点,比如0代表红色点,1代表蓝色点,这样400个两种颜色的点就可以显示出来,代码如下:

"""
测试函数:实现数据集的显示
"""
def test():
    X,Y=planar_utils.load_planar_dataset()
    plt.scatter(X[0,:],X[1,:],c=np.squeeze(Y),s = 80,cmap=plt.cm.Spectral)
    plt.show()

显示结果如下:

利用两层神经网络,一层隐藏层,一层输出层,400个点,所以有400个样本,两种特征(两种颜色),所以输入层节点是2个,隐藏层定义4个节点,输出层1个节点,脑海里就有神经网络的结构图了,故W1(4,2),b1(4,1),W2(1,4),b2(1,1)简单的演示一遍。Z1=W1*X=(4,400),Z2=W2*Z1=(1,400),就对应Y的维度了。中间加激活函数和b值不影响维度

具体公式推导如下,右上角是神经网络:


下面看代码:

def sigmoid(z):
    s=1.0/(1+np.exp(-z))
    return s
"""
返回输入层节点和输出层节点
"""
def lay_sizer(X,Y):
    n_x = X.shape[0]
    n_y = Y.shape[0]
    return n_x,n_y
"""
初始化Wb,n_h就是隐藏层节点
"""
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))
    parameters={'W1':W1,
                'b1':b1,
                'W2':W2,
                'b2':b2}
    return parameters
"""
前向传播,返回中间量Z1 A1 Z2 A2 最后一层加sigmoid因为要实现二分类
"""
def forward_propagation(X,parameters):
    W1 = parameters['W1']
    W2 = parameters['W2']
    b1 = parameters['b1']
    b2 = parameters['b2']
    Z1 = np.dot(W1, X) + b1
    A1 = np.tanh(Z1)#Relu(Z1)
    Z2 = np.dot(W2, A1) + b2
    A2 = sigmoid(Z2)
    cache={'Z1':Z1,
           'Z2':Z2,
           'A1':A1,
           'A2':A2}
    return cache,A2
"""
利用交叉熵函数计算损失值
"""
def compute_cost(A2,Y):
    m=Y.shape[1]
    cost=-1 / m *(np.dot(Y,np.log(A2).T)+np.dot((1-Y),np.log(1-A2).T))
    cost=np.squeeze(cost)
    return cost
"""
后向传播:注意维度
"""
def back_propagation(parameters,cache,X,Y):
    m = Y.shape[1]
    A2 = cache['A2']
    A1 = cache['A1']
    W2 = parameters['W2']
    dZ2 = A2-Y
    dW2 = 1/m*(np.dot(dZ2,A1.T))
    db2 = 1/m*(np.sum(dZ2,axis=1,keepdims=True)) #db2(n_y,1) 按行相加 保持二维性
                                               # [[1,2],[3,4]] [[3],[7]]
    dA1 = np.dot(W2.T,dZ2)
    dZ1 = dA1*(1-np.power(A1,2))
    dW1 = 1/m*np.dot(dZ1,X.T)
    db1 = 1/m*(np.sum(dZ1,axis=1,keepdims=True))  #db1(n_h,1) 按行相加 保持二维性
    grads={'dW2':dW2,
           'dW1':dW1,
           'db2':db2,
           'db1':db1}
    return grads
"""
更新参数 Wb
"""
def update_parameters(grads,parameters,learning_rate):
    dW2=grads['dW2']
    dW1=grads['dW1']
    db2=grads['db2']
    db1=grads['db1']
    W2=parameters['W2']
    W1= parameters['W1']
    b2 = parameters['b2']
    b1 = parameters['b1']
    W2 = W2 - learning_rate*dW2
    W1 = W1 - learning_rate * dW1
    b2 = b2 - learning_rate * db2
    b1 = b1 - learning_rate * db1
    parameters = {'W1': W1,
                  'b1': b1,
                  'W2': W2,
                  'b2': b2}
    return parameters
"""
构建模型
"""
def nn_model(X,Y,num_iterations,learning_rate,print_cost,n_h):
    n_x,n_y = lay_sizer(X, Y)
    parameters = initialize_parameters(n_x, n_h, n_y)
    #costs=[]
    for i in range(num_iterations):
        cache, A2 = forward_propagation(X, parameters)
        cost = compute_cost(A2, Y)
        #costs.append(cost)
        grads = back_propagation(parameters, cache, X,Y)
        parameters = update_parameters(grads, parameters, learning_rate)
        if print_cost and i%100==0:
            print('Cost after iterations {}:{}'.format(i,cost))
    return parameters  #,costs
"""
用更新好的参数预测Y
"""
def prediction(X,parameters):
    cache,A2=forward_propagation(X,parameters)
    predictions=np.around(A2)
    return predictions
def train_accuracy():
     X, Y = planar_utils.load_planar_dataset()
     parameters = nn_model(X, Y, num_iterations=10000, learning_rate=1.2, print_cost=True,n_h=8)
     # print('parameters W1', parameters['W1'])
     # print('parameters W2', parameters['W2'])
     # print('parameters b1', parameters['b1'])
     # print('parameters b2', parameters['b2'])
     predictions = prediction(X, parameters)
     print(predictions)
     planar_utils.plot_decision_boundary(lambda x: prediction(x.T, parameters), X, np.squeeze(Y))
     plt.show()
     ###########二分类精度求解
     result = np.dot(np.squeeze(Y), np.squeeze(predictions.T)) + np.dot(np.squeeze(1 - Y), np.squeeze(1 - predictions.T))
     print('The accuracy is {}%'.format((result) / Y.size * 100))

if __name__=='__main__':
    #test()
    train_accuracy()

结果:

更改隐藏层个数:

def Different_Hidden_Size():
    X, Y = planar_utils.load_planar_dataset()
    hidden_layer_sizes=[1,2,3,4,5,10,20]
    plt.figure(figsize=(16,16))
    for i,n_h in enumerate(hidden_layer_sizes):
        print('n_h=',n_h)
        plt.subplot(3,3,i+1)
        plt.title('hidden_layer_sizes{}'.format(n_h))
        parameters = nn_model(X, Y, num_iterations=2000, learning_rate=1.2, print_cost=False,n_h=n_h)
        planar_utils.plot_decision_boundary(lambda x: prediction(x.T, parameters), X, np.squeeze(Y))
        predictions = prediction(X, parameters)
        ###########二分类精度求解
         result = np.dot(np.squeeze(Y), np.squeeze(predictions.T)) + np.dot(np.squeeze(1 - Y),
                                                                           np.squeeze(1 - predictions.T))
        print('The accuracy hidden_layer_sizes{} is {}%'.format(n_h,(result) / Y.size * 100))
    plt.savefig('1.png')
    plt.show()
if __name__=='__main__':
    #test()
    #train_accuracy()
    Different_Hidden_Size()

结果:


猜你喜欢

转载自blog.csdn.net/fanzonghao/article/details/81015599
今日推荐