看了吴恩达的课程,按他的公式做了一下编程练习。
题目是训练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计算溢出的问题,暂时找不到好的解决方案。有任何问题欢迎交流。