第一次实现单层神经网络

看了吴恩达的课程,按他的公式做了一下编程练习。

第一次实现单层神经网络_第1张图片第一次实现单层神经网络_第2张图片第一次实现单层神经网络_第3张图片

题目是训练209*64*64*3的209张图片,再预测50*64*64*3的50张图片。

代码如下:

import numpy as np
import h5py
    
#加载数据集
def load_dataset():
    train_dataset = h5py.File('datasets/train_catvnoncat.h5', "r")
    train_set_x_orig = np.array(train_dataset["train_set_x"][:]) # your train set features
    train_set_y_orig = np.array(train_dataset["train_set_y"][:]) # your train set labels

    test_dataset = h5py.File('datasets/test_catvnoncat.h5', "r")
    test_set_x_orig = np.array(test_dataset["test_set_x"][:]) # your test set features
    test_set_y_orig = np.array(test_dataset["test_set_y"][:]) # your test set labels

    classes = np.array(test_dataset["list_classes"][:]) # the list of classes
    
    train_set_y_orig = train_set_y_orig.reshape((1, train_set_y_orig.shape[0]))
    test_set_y_orig = test_set_y_orig.reshape((1, test_set_y_orig.shape[0]))
    
    return train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes

#激活函数activition function
def ReLU(z):
    mz,nz = z.shape
    zero = np.zeros((mz,nz))
    return np.maximum(zero,z)
#RuntimeWarning: overflow encountered in exp
def sigmoid(z):
    return 1.0/(1+np.exp(-z))

#将4维数组转换为2维
def transformArray(inX):
    shape = inX.shape
    shape1 = shape[1]*shape[2]*shape[3]
    transformedX = np.mat(np.zeros((shape1,shape[0])))
    for i,item in enumerate(inX):
        transformedItem = item.flatten().reshape(-1,1)
        transformedX[:,i] = transformedItem
    return transformedX

#损失函数
def lossFunc(A,y_train):
    pass
    
#单层神经网络
class myOneLNN:
    def __init__(self,W1,b1,alpha,af,iterNum):
        self.W = W1
        self.b = b1
        self.af = af
        self.iterNum = iterNum
        self.alpha = alpha
        
    def trainFunc(self,X_train,y_train):
        m = X_train.shape[1]
        X = X_train
        Y = y_train
        Z = self.W*X + self.b
        for i in range(iterNum):        
            Z = self.W*X + self.b
#            Z1 = np.dot(self.W,X)+b
#            print(Z1.shape)
            A = self.af(Z)  
            dZ = A - Y
            dW =  dZ*X.T/m
            db = np.sum(dZ)/m
            self.W -= self.alpha*dW
            self.b -= self.alpha*db
        return self.W,self.b
    
    def predictFunc(self,X_test):
        Z_pred = self.W*X_test + self.b
        '''此处为什么A_pred和y_pred是一样的?'''
        A_pred = self.af(Z_pred)
#        print(A_pred)
        y_pred = np.zeros(A_pred.shape)
        y_pred[0,np.nonzero(A_pred>0.5)[1]] = 1.0
        return y_pred
    
    def testErrors(self,y_test,y_pred):
        m = y_test.shape[1]
        errors = len(np.nonzero(y_test!=y_pred)[0])
        errorRate = errors*1.0/m
#        print('the total error number is: %d'%errors)
#        print('the error rate is: %.2f'%errorRate)
        return errorRate
X_train,y_train,X_test,y_test,classes = load_dataset()
#将数据集转换为2维:是否有更好的方法?
X_train_transformed = transformArray(X_train)
X_test_transformed = transformArray(X_test)
L = 1       #1 layers
n0 = X_train_transformed.shape[0]      #输入样本的维度
m = X_train_transformed.shape[1]        #训练样本个数为m
n1 = 1                                  #输出层单元数为1个
W1 = np.random.randn(n1,n0)*0.001            #随机初始化W
'''按公式,此处b和m有关,但测试集的m和训练集的m不相等,运行会出错
个人觉得b的shape应该是(ni*1),ni为第i层单元的个数'''
#b1 = np.zeros((n1,m))                   #b可以初始化为0
b1 = 0
iterNum = 500

#交叉验证
errList = []
for i in range(10):
    oneLNN = myOneLNN(W1,b1,alpha=0.001,af=sigmoid,iterNum=iterNum)
    W,b = oneLNN.trainFunc(X_train_transformed,y_train)
    y_pred = oneLNN.predictFunc(X_test_transformed)
    errorRate = oneLNN.testErrors(y_test,y_pred)
    errList.append(errorRate)
print(errList)
print(np.mean(errList))
单层神经网络的错误率为28%,遇到np.exp计算溢出的问题,暂时找不到好的解决方案。有任何问题欢迎交流。

你可能感兴趣的:(Python,机器学习)