上一个博客已经对猫进行了基本的识别,图片分为是猫和不是猫两种类型,所以可以用logistic回归处理。
这里是看了吴恩达老师的视频进行的一个简单项目的实现。
项目是参考别人的,这里附上地址:https://blog.csdn.net/u013733326/article/details/79767169
该项目的流程还是很简单明了的,所以这里进行了记录,下面开始正式的项目流程:
步骤:
1 初始化网络参数
2 向前传播
2.1 计算一层中线性求和的部分
2.2 计算激活函数的部分
2.3 结合线性求和与激活函数
3 计算误差
4 反向传播
4.1 线性部分的反向传播公式
4.2 激活函数部分的反向传播公式
4.3 结合线性部分与激活函数的反向传播公式
5 更新参数
6 构建神经网络
7 预测
后面开始导入数据,进行训练和测试。
import numpy as np
import h5py
import matplotlib.pyplot as plt
np.random.seed(3)
#初始化网络参数
def initialize_parameters_deep(layers_dims):
np.random.seed(3)
parameters = {}
L = len(layers_dims)
for l in range(1, L):
parameters["W"+str(l)] = np.random.randn(layers_dims[l], layers_dims[l-1]) / np.sqrt(layers_dims[l - 1])
parameters["b"+str(l)] = np.zeros((layers_dims[l], 1))
assert(parameters["W"+str(l)].shape == (layers_dims[l],layers_dims[l-1]))
assert(parameters["b"+str(l)].shape == (layers_dims[l],1))
return parameters
#向前传播2.1
def linear_forward(A, W, b):
Z = np.dot(W, A) + b
assert(Z.shape == (W.shape[0], A.shape[1]))
cache = (A, W, b)
return Z, cache
def sigmoid(Z):
A = 1/(1 + np.exp(-Z))
cache = Z
return A, cache
def relu(Z):
A = np.maximum(0, Z)
cache = Z
return A, cache
#向前传播2.2
def activation_forward(A_prev, W, b, activation):
if activation == "sigmoid":
Z, linear_cache = linear_forward(A_prev, W, b)
A, activation_cache = sigmoid(Z)
elif activation == "relu":
Z, linear_cache = linear_forward(A_prev, W, b)
A, activation_cache = relu(Z)
assert(A.shape == (W.shape[0], A_prev.shape[1]))
cache = (linear_cache, activation_cache)
return A, cache
#向前传播2.3
def L_model_forward(X, parameters):
caches = []
A = X
L = len(parameters)//2 #参数保存了每层中的w与b,所以一半就是层的数目(隐藏层和输出层,不算输入层)
for l in range(1, L): #range(1, 11) # 从 1 开始到 11 #[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
A_prev = A
A, cache = activation_forward(A_prev, parameters["W"+str(l)], parameters["b"+str(l)], "relu")
caches.append(cache)
AL, cache = activation_forward(A_prev, parameters["W"+str(L)], parameters["b"+str(L)], "sigmoid")
caches.append(cache)
assert(AL.shape == (1, X.shape[1]))
return AL, caches
#计算成本函数3
def compute_cost(AL, Y):
m = Y.shape[1]
cost = -np.sum(np.multiply(Y, np.log(AL)) + np.multiply((1-Y), np.log(1-AL)))/m
cost = np.squeeze(cost)
assert(cost.shape ==())
return cost
#反向传播4.1
def linear_backward(dZ, cache):
A_prev, W, b = cache
m = A_prev.shape[1]
dW = np.dot(dZ, A_prev.T) / m
db = np.sum(dZ, axis=1, keepdims=True) / m
dA_prev = np.dot(W.T, dZ)
assert (dA_prev.shape == A_prev.shape)
assert (dW.shape == W.shape)
assert (db.shape == b.shape)
return dA_prev, dW, db
def sigmoid_backward(dA, cache):
Z = cache
A = 1/(1+np.exp(-Z))
dZ = dA * A * (1-A)
assert(dZ.shape == Z.shape)
return dZ
def relu_backward(dA, cache):
Z = cache
A = np.maximum(0,Z)
dZ = np.array(dA, copy = True)
dZ[Z<=0] = 0
assert(dZ.shape == Z.shape)
return dZ
#反向传播4.2
def activation_backward(dA, cache, activation = "relu"):
linear_cache, activation_cache = cache
if activation == "relu":
dZ = relu_backward(dA, activation_cache)
dA_prev, dw, db = linear_backward(dZ, linear_cache)
elif activation == "sigmoid":
dZ = sigmoid_backward(dA, activation_cache)
dA_prev, dw, db = linear_backward(dZ, linear_cache)
return dA_prev, dw, db
#反向传播4.3
def L_model_backward(AL, Y, caches):
grads = {}
L = len(caches)
m = AL.shape[1]
Y = Y.reshape(AL.shape)
dAL = -(np.divide(Y, AL) - np.divide(1 - Y, 1 - AL))
current_cache = caches[L-1]#有的内容是从0到L-1
grads["dA"+str(L)], grads["dW"+str(L)], grads["db"+str(L)] = activation_backward(dAL, current_cache, activation = "sigmoid")
for l in reversed(range(L - 1)):
current_cache = caches[l]
dA_prev_temp, dw_temp, db_temp = activation_backward(grads["dA"+str(l+2)], current_cache, activation = "relu")
grads["dA"+str(l+1)] = dA_prev_temp
grads["dW"+str(l+1)] = dw_temp
grads["db"+str(l+1)] = db_temp
return grads
#更新参数5
def update_parameters(parameters, grads, learning_rate):
L = len(parameters)//2
for l in range(L):
parameters["W"+str(l+1)] = parameters["W"+str(l+1)] - learning_rate * grads["dW"+str(l+1)]
parameters["b"+str(l+1)] = parameters["b"+str(l+1)] - learning_rate*grads["db"+str(l+1)]
return parameters
#构建神经网络6
def L_layer_model(X, Y, layers_dims, learning_rate = 0.0075, num_iterations = 3000, print_cost = False, isPlot = True):
np.random.seed(1)
costs = []
parameters = initialize_parameters_deep(layers_dims)
for i in range(num_iterations):
AL, caches = L_model_forward(X, parameters)
cost = compute_cost(AL, Y)
grads = L_model_backward(AL, Y, caches)
parameters = update_parameters(parameters, grads, learning_rate)
if i%100 == 0:
costs.append(cost)
if print_cost:
print("第", i ,"次迭代,成本值为:" ,np.squeeze(cost))
if isPlot:
plt.plot(np.squeeze(costs))
plt.ylabel("cost")
plt.xlabel('iterations (per tens)')
plt.title("Learning rate =" + str(learning_rate))
plt.show()
return parameters
#预测7
def predict(X, y, parameters):
m = X.shape[1]
n = len(parameters) // 2 # 神经网络的层数
p = np.zeros((1,m))
#根据参数前向传播
probas, caches = L_model_forward(X, parameters)
for i in range(0, probas.shape[1]):
if probas[0,i] > 0.5:
p[0,i] = 1
else:
p[0,i] = 0
print("准确度为: " + str(float(np.sum((p == y))/m)))
return p
#加载数据函数,这块不熟,但大致知道
def load_dataset():
train_dataset = h5py.File('/Users/weijinqian/Desktop/资料/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('/Users/weijinqian/Desktop/资料/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
train_set_x_orig , train_set_y , test_set_x_orig , test_set_y , classes = load_dataset()
train_x_flatten = train_set_x_orig.reshape(train_set_x_orig.shape[0], -1).T
test_x_flatten = test_set_x_orig.reshape(test_set_x_orig.shape[0], -1).T
train_x = train_x_flatten / 255
train_y = train_set_y
test_x = test_x_flatten / 255
test_y = test_set_y
layers_dims = [12288, 20, 7, 7, 1] # 5-layer model
parameters = L_layer_model(train_x, train_y, layers_dims, learning_rate = 0.0075, num_iterations = 5000, print_cost = True,isPlot=True)
pred_train = predict(train_x, train_y, parameters) #训练集
pred_test = predict(test_x, test_y, parameters) #测试集
def print_mislabeled_images(classes, X, y, p):
"""
绘制预测和实际不同的图像。
X - 数据集
y - 实际的标签
p - 预测
"""
a = p + y
mislabeled_indices = np.asarray(np.where(a == 1))
plt.rcParams['figure.figsize'] = (40.0, 40.0) # set default size of plots
num_images = len(mislabeled_indices[0])
for i in range(num_images):
index = mislabeled_indices[1][i]
#print(i)
plt.subplot(1, num_images, i + 1)
#plt.subplot(2,2,1) #要生成两行两列,这是第一个图plt.subplot('行','列','编号')
plt.imshow(X[:,index].reshape(64,64,3), interpolation='nearest')
plt.axis('off')
plt.title("Prediction: " + classes[int(p[0,index])].decode("utf-8") + " \n Class: " + classes[y[0,index]].decode("utf-8"))
plt.show()
print_mislabeled_images(classes, test_x, test_y, pred_test)
恩,以上就是项目的源代码,是可以运行出结果的。
本次结果为:
学过神经网络的同学不难发现,该学习模型存在过拟合的问题,后面需要用dropout之类的内容进行调整。这个也是我下面要进行的工作。会在后期的博客更新中进行展示,虽然现在还不会...
至于中间各种公式的推导,希望大家可以认真看看吴恩达老师深度学习视频,反正我是获益良多。
附上传送门:https://www.bilibili.com/video/av49445369?p=2 是B站的。
还有卷积神经网络可以应用,这些对一个学习模型的构建影响巨大。希望到后期我可以做出一个准确度较高的神经网络学习模型。同学们好好学习吧。