深度学习与神经网络-吴恩达(Part1Week3)-单隐层神经网络编程实现(python)

来源:互联网 发布:浙江网络作家协会主席 编辑:程序博客网 时间:2024/06/06 01:12

一、神经网络的表示


上一个教程中已经详细介绍了Logistic Regression模型,神经网络其实就是多个Logistic Regression模型的组合,每个功能层(含有激活函数的层)中的每个神经元都对应一个Logistic Regression模型。在下面的例子中,神经网络只含有一个隐层,单个输入样本 x 经过第一层的线性处理和非线性映射,得到了z1和 a1,随后将 a1 作为第二层(输出层)的输入,依次计算 z2 和 a2 ,a2即为我们最终的输出,最后计算损失函数,这就是一个完整的正向传播过程。我们可以看到这里有两次激活函数的使用,两个激活函数可以相同也可以不同。



接下来通过另一个例子具体来表示单隐层的神经网络,依次分别计算各层各个神经元的输出:




从上面的例子中可以看出,我们针对某一层分别计算单个神经元的输出是非常低效的,在具体的编程中需要通过for循环来实现,那么我们尝试将上述方程组转堆叠到一起来计算:


最终我们将单层的计算过程向量化(需要特别注意的是每个向量的shape,因为向量乘法对两个向量的shape有要求,不熟悉的可以顺着推导下),得到如下的表达形式:



二、向量化加速


上面只是对单层进行了向量化,但实际上我们的输入的样本不只一个,依次计算每个样本的输出也是一个for循环过程,因此我们考虑将所有样本 x 堆叠到一个向量 X 里作为输入,后续各个中间向量z,a和最终结果向量的shape也会相应变化,下面例子中大写字母均为向量。




三、激活函数


常用的激活函数有sigmoid函数,tanh函数,relu函数等。对于二分类问题,一般在中间各层采用tanh函数或者relu函数,而在输出层采用sigmoid函数,其他非二分类的情况绝对不要用。如果不采用激活函数,那么神经网络只是把输入数据进行线性组合再输出,对于深度神经网络,如果使用线性激活函数(梯度为固定值)或者没有激活函数,那么无论你的神经网络有多少层,它所在做的只是计算线性激活函数,所以添加再多的隐层也都是在做无用功。








四、神经网络的梯度下降






五、随机初始化


对于Logistic Regression我们可以以零作为初始值,但是对于神经网络则不能,因为权重参数设置为零时,所有的隐藏单元都是对称的,不管你跑多久梯度下降,它们都在计算完全一样的函数。我们实际建立神经网络模型时,希望隐层的每个神经单元都是不同的,这样才能保证我们能去计算不同的函数。一般采用如下方式来初始化权重向量:


这里所乘的0.01是一个经验参数(可以自己试验确定),只是用来将权重参数初始化成非常小非常小的随机值。因为如果你用的tanh或者sigmoid激活函数,当权重太大,所计算的激活函数值极有可能落在tanh或者sigmoid函数的平缓部分(接近饱和),这也意味着梯度下降法会非常慢,所以学习会很慢。

六、实现代码


这次测试的数据和上次Logistic Regression一样,也是对猫图像进行分类识别的,数据为RGB三通道图像,大小为64*64,训练集209张,验证集50张。这里设计了一个单隐层的神经网络,隐层神经单元为20个,激活函数为tanh,输出层神经单元个数为1,激活函数为sigmoid。

import numpy as npimport matplotlib.pyplot as pltimport h5pyimport scipyfrom PIL import Imagefrom scipy import ndimagefrom lr_utils import load_dataset# Input datatrain_set_x_orig, train_set_y, test_set_x_orig, test_set_y, classes = load_dataset()train_num = train_set_x_orig.shape[0]test_num = test_set_x_orig.shape[0]pix_num = train_set_x_orig.shape[1]chanel_num = train_set_x_orig.shape[3]print('\n' + '---------------Input information---------------' + '\n')print('train_set_x_orig.shape = ' + str(train_set_x_orig.shape))print('train_set_y.shape = ' + str(train_set_y.shape))print('test_set_x_orig.shape = ' + str(test_set_x_orig.shape))print('test_set_y.shape = ' + str(test_set_y.shape))print('train_num = ' + str(train_num))print('test_num = ' + str(test_num))print('pix_num = ' + str(pix_num))print('chanel_num = ' + str(chanel_num))# Reshape datatrain_set_x_flat = train_set_x_orig.reshape(train_num,-1).Ttest_set_x_flat = test_set_x_orig.reshape(test_num,-1).Tprint('\n' + '---------------After reshaping---------------' + '\n')print('train_set_x_flat = ' + str(train_set_x_flat.shape))print('test_set_x_flat = ' + str(train_set_x_flat.shape))# Standarize datatrain_set_x = train_set_x_flat/255.0test_set_x = test_set_x_flat/255.0print('\n' + '---------------After Standaring---------------' + '\n')print('Check for traindata = ' + str(train_set_x[0:5,0]))print('Check for testdata = ' + str(test_set_x[0:5,0])) def tanh(x):    s = (np.exp(x)-np.exp(-x))/((np.exp(x)+np.exp(-x)))    return sdef tanh_prime(x):    s = 1 - np.power(tanh(x), 2)    return sdef sigmoid(x):    s = 1/(1+ np.exp(-x))    return sdef sigmoid_prime(x):    s = sigmoid(x)*(1 - sigmoid(x))    return sdef relu(Z):    s = np.maximum(0,Z)    return sdef relu_prime(Z):    s = Z    s[Z <= 0] = 0    s[Z>0]=1    return s    def initial_weights(input, hidden, output, m):    np.random.seed(3)    w1 = np.random.randn(hidden,input)* 0.01    b1 = np.zeros((hidden,1))    w2 = np.random.randn(output,hidden)* 0.01    b2 = np.zeros((output,1))    return w1,b1,w2,b2def train(X,y,hidden=20,learning_rate=0.01,itr_num=3000,isprint=True):    h_i = X.shape[0]    m = X.shape[1]    h_o = y.shape[0]    h_h = hidden    w1,b1,w2,b2 = initial_weights(h_i, h_h, h_o, m)    costs = []    for i in range(itr_num):        # Forward        A1 = tanh(np.dot(w1, X) + b1)  # h_h * m        A2 = sigmoid(np.dot(w2,A1) + b2)                 # h_o * m        cost =  -(1.0/m)*np.sum(y*np.log(A2)+(1-y)*np.log(1-A2))            # Backword        dz2 = A2 - y        dw2 = (1.0/m)*np.dot(dz2 , A1.T)        db2 = (1.0/m)*np.sum(dz2, axis=1,keepdims=True)            dz1 = np.dot(w2.T,dz2)*tanh_prime(np.dot(w1, X) + b1)  # h_h * m        dw1 = (1.0/m)*np.dot(dz1, X.T)        db1 = (1.0/m)*np.sum(dz1, axis=1,keepdims=True)            # Update weights        w1 = w1 - learning_rate*dw1        b1 = b1 - learning_rate*db1        w2 = w2 - learning_rate*dw2        b2 = b2 - learning_rate*db2                if isprint and  i % 100 ==0:            print('cost after ' + str(i) + ' iteration is :' + str(cost))        if i%100 ==0:             costs.append(cost)    d = {"w1":w1,"b1":b1,"w2":w2,"b2":b2,"costs":costs,"learning_rate":learning_rate}    costs = np.squeeze(costs)    plt.plot(costs)    plt.ylabel('cost')    plt.xlabel('Iteration(per hundreds)')    plt.title("Learning rate=" + str(d["learning_rate"]))    plt.show()    return ddef predict(X,y,d):    w1 = d["w1"]     b1 =d["b1"]    w2 =d["w2"]    b2 =d["b2"]    nx = X.shape[0]    m = X.shape[1]    Y_prediction = np.zeros((1,m))    A1 = relu(np.dot(w1, X) + b1)      prob = sigmoid(np.dot(w2,A1) + b2)    for i in range(m):        if prob[0,i] > 0.5:            Y_prediction[0,i]  = 1        else:            Y_prediction[0,i] = 0    print("accuracy: {} %".format(100 - np.mean(np.abs(Y_prediction - y)) * 100))    return Y_predictionmodel = train(train_set_x,train_set_y,hidden=20,learning_rate=0.01,itr_num=3000)y = predict(test_set_x,test_set_y,model)





阅读全文
2 0
原创粉丝点击