首页 > 其他分享 >深度学习项目拆解:识别猫的项目

深度学习项目拆解:识别猫的项目

时间:2023-06-08 14:03:04浏览次数:33  
标签:set parameters 项目 拆解 np train str test 识别



识别猫的项目

  • 神经网络训练步骤
  • 数据准备
  • 定义神经网络结构
  • 解析神经网络、初始化参数(w、b)
  • 输入数据,前向传播
  • 得到本轮迭代的损失值
  • 求最末层误差,反向传播计算各层梯度
  • 根据各层的w、b梯度,使用梯度下降更新一次参数
  • 重复以上步骤,直到损失值低于设定阈值,模型收敛
  • 神经网络的探索
  • 梯度检验,检测反向传播是否有问题
  • 探索各种权重初始化
  • 探索各种优化算法
  • 批量归一化



神经网络训练步骤

数据准备


import h5py                                                      # 数据是 H5 文件,需要 h5 模块
import matplotlib.pyplot as plt                                  # 绘图库,之后会查看图片
import numpy as np

train_dataset = h5py.File('./我的数据集/train_catvnoncat.h5','r') # 读取训练集(创建了一个字典格式的对象)
test_dataset = h5py.File('./我的数据集/test_catvnoncat.h5','r')   # 读取测试集(创建了一个字典格式的对象)

# 因为对象是字典,所以用数据之前,还需要键名
for key1 in train_dataset.keys():
	print( train_dataset[key1].name )                           # 查看训练集键名(标签类别list_classes、图片特征train_set_x、图片标签train_set_y)
	
for key2 in test_dataset.keys():
	print( test_dataset[key2].name )                            # 查看测试集键名(标签类别list_classes、图片特征test_set_x、图片标签test_set_y)

train_set_x = np.array(train_dataset["train_set_x"][:])         # 通过键名,访问所有数据,并保存到数组里
train_set_y = np.array(train_dataset["train_set_y"][:])         # 通过键名,访问所有数据,并保存到数组里

test_set_x = np.array(test_dataset["test_set_x"][:])            # 通过键名,访问所有数据,并保存到数组里
test_set_y = np.array(test_dataset["test_set_y"][:])            # 通过键名,访问所有数据,并保存到数组里


print("train_set_x.shape = ",train_set_x.shape)                 # 查看训练集数组维度( (209, 64, 64, 3) 意思是,209张图片,尺寸是 64*64*3,64x64x3 = 12288个特征 )
print("test_set_x.shape = ",test_set_x.shape)                   # 查看测试集数组维度( (50, 64, 64, 3) 意思是,50张图片,尺寸是 64*64*3,64x64x3 = 12288个特征 )

深度学习项目拆解:识别猫的项目_数据


一张图片是一个三维数组 64 * 64 * 3,64 是长和宽,3 是 RGB 三个通道,因为这是一张彩色图片,每个像素点必须用三个数来代表,一张图片就要用 1 万多个数来描述。

209 张图片,是一个四维数组 209 * 64 * 64 * 3,而神经元的输入是二维的列矩阵 209 * 1,所以我们要转换一下。

# 图片特征 xx_set_x:(209, 64, 64, 3) -> (12288,209)
train_set_x = train_set_x.reshape(train_set_x.shape[0], -1).T    # (209, 64, 64, 3) 变成 (12288,209)
test_set_x = test_set_x.reshape(test_set_x.shape[0], -1).T       # (209, 64, 64, 3) 变成 (12288,50)

# 图片标签 xx_set_y:(209,) -> (1,209)
train_set_y = train_set_y.reshape(1,train_set_y.shape[0])        # (209,) 变成 (1,209)
test_set_y = test_set_y.reshape(1,test_set_y.shape[0])           # (50,) 变成 (1,50)

# P.S. 标签类别list_classes 非0即1,0即非猫,1即是猫。

最后归一化,我们要把数据经过处理后使之限定在一定的范围内。比如通常限制在区间 [0, 1]

train_set_x = train_set_x/255.0       
test_set_x = test_set_x/255.0
# 除以255.0是为了使数据的取值范围在sigmoid激励函数的取值范围内
#【注:灰度图像素取值为0-255,相除后取值在0-1之间,符合激励函数的输出范围】

好,现在我们把数据准备这部分封装为一个函数。

import h5py                                                      # 数据是 H5 文件,需要 h5 模块
import matplotlib.pyplot as plt                                  # 绘图库,之后会查看图片
import numpy as np

def load_dataset():
    # 创建文件对象
    train_dataset = h5py.File('./我的数据集/train_catvnoncat.h5','r')
    test_dataset = h5py.File('./我的数据集/test_catvnoncat.h5','r')
    
    # 读取数据
    train_set_x = np.array(train_dataset["train_set_x"][:])
    train_set_y = np.array(train_dataset["train_set_y"][:])
    test_set_x = np.array(test_dataset["test_set_x"][:])
    test_set_y = np.array(test_dataset["test_set_y"][:])

	# 查看第 110 张图片
    plt.figure(figsize=(2,2))
    plt.imshow(train_set_x[110])
    plt.show()
    
    # 变化维度以适应神经网络输入
    train_set_x = train_set_x.reshape(train_set_x.shape[0],-1).T  
    test_set_x = test_set_x.reshape(test_set_x.shape[0],-1).T  
    train_set_y = train_set_y.reshape(1,train_set_y.shape[0]) 
    test_set_y = test_set_y.reshape(1,test_set_y.shape[0]) 

	# 数据归一化
    train_set_x = train_set_x/255.0       
    test_set_x = test_set_x/255.0
    
    return train_set_x,train_set_y,test_set_x,test_set_y

if __name__ == '__main__':
    train_set_x, train_set_y, test_set_x, test_set_y = load_dataset()
    # 加载数据

 


定义神经网络结构

加载数据后,定义神经网络结构。

if __name__ == '__main__':
    load_dataset()
    # 加载数据
   
	fc_net = [12288, 4, 3, 2, 1] 
	# 用数组定义神经网络结构,输入层(12288个神经元)->第1层->第2层->第3层->第4层->a,有多少层、一层多少神经元,都取决于工程师的直觉,差不多就行   
	# 输出值a,a>0.5 ? 1:0

 


解析神经网络、初始化参数(w、b)

定义神经网络结构之后,解析神经网络

if __name__ == '__main__':
    train_set_x, train_set_y, test_set_x, test_set_y = load_dataset()
    # 加载数据
    
    fc_net = [12288, 4, 3, 2, 1] 
	# 用数组定义神经网络结构,输入层(12288个神经元)->第1层->第2层->第3层->第4层->a  
	# 输出值a,a>0.5 ? 1:0
    
    parameters = init_parameters(fc_net)
    # 解析神经网络,初始化权值

现在我们来实现初始化权值 init_parameters 的实现。

# 初始化参数
def init_parameters(fc_net):  
    parameters = {}               
    # 定义一个字典,存放参数矩阵W1,b1,W2,b2,W3,b3,W4,b4
    Layer_num = len(fc_net)       
    # 神经网络的层数,通过获取数组长度可得
    
    for L in range(1, Layer_num):  # 遍历层数,从第一层开始,但忽略输入层(第 0 层)
        parameters["W"+str(L)] = np.random.randn(fc_net[L], fc_net[L-1])*0.01   
        # 从标准正态分布中(取值范围[-3,3])选取值,为方便激活函数(取值范围[-1,1]),乘以0.01后,再赋值给创建的键值对(W1、W2、W3···)
        parameters["b"+str(L)] = np.zeros((fc_net[L], 1))
        
    for L in range(1, Layer_num):
        print("W"+str(L)+" = ", parameters["W"+str(L)].shape)
        print("b"+str(L)+" = ",  parameters["b"+str(L)].shape)
        
    return parameters

 


输入数据,前向传播

if __name__ == '__main__':
    train_set_x, train_set_y, test_set_x, test_set_y = load_dataset()
    # 加载数据
    
    fc_net = [12288, 4, 3, 2, 1] 
	# 输入层->第1层->第2层->第3层->第4层->a    
	# 输出值a,a>0.5 ? 1:0
    
    parameters = init_parameters(fc_net)
    # 初始化权值
    
    AL, cache = forward_pass(train_set_x, parameters, active_func = "tanh")
    # 最后一层激活值AL = train_set_x 输入数据、parameters W、b 保存位置、激活函数是 tanh

现在我们来实现激活函数。

def sigmoid(Z):
    return 1 / (1 + np.exp(-Z)) 

def tanh(Z): 
    return np.tanh(Z)

def ReLU(Z):    
    return np.maximum(0,Z)

再来实现前向传播 forward_pass

def forward_pass(A0, parameters, active_func = "ReLU"):
    Layer_num = len(parameters) // 2  # 因为 parameters 是由 W、b 组成,所以除 2
    A = A0
    cache = {}        				  # 缓存 A 的字典
    cache["A0"] = A0  				  # 先缓存A0
     
    for L in range(1,Layer_num):      
        A_prev = A
        Z = np.dot(parameters["W"+str(L)],A_prev) + parameters["b"+str(L)]  # Z = WX + b
        cache["Z"+str(L)] = Z         # 缓存Z1 Z2 Z3 Z4
        
        if active_func == "sigmoid":  
            A = sigmoid(Z)            # sigmoid函数,适合用于深度网络
        elif active_func == "tanh":
            A = tanh(Z)               # tanh函数激活
        else:
            A = ReLU(Z)               # 1~3层用 ReLU 函数激活     
        cache["A"+str(L)] = A         # 继续缓存 A1 A2 A3 A4
    
    # 最末层采用sigmoid函数激活
    ZL = np.dot(parameters["W" + str(Layer_num)], A) + parameters["b" + str(Layer_num)]    #  1,2   2,209
    cache["Z" + str(Layer_num)] = ZL  # 缓存最末层的Z4
    AL = sigmoid(ZL)                  # sigmoid函数激活
    cache["A"+str(Layer_num)]=AL      # 继续缓存最末层的A4   
    
    return AL, cache

对比《深度学习食用指南》识别猫的项目,这里多了一个要缓存 A,这是为啥?

其实是一种算法策略:空间换时间,因为前向传播过程如下所示:

深度学习项目拆解:识别猫的项目_数据_02


一般的前向传播过程,我们是一个一个计算的,处理完一个样本再处理下一个样本,等所有样本都处理完了,才能反向传播,求参数的梯度。

能不能同时计算呢?

  • 深度学习项目拆解:识别猫的项目_数据_03 是输入样本,是不需要计算就可以得到的,我们把上面的 深度学习项目拆解:识别猫的项目_数据_03
  • 深度学习项目拆解:识别猫的项目_数据_05 也堆叠起来,后面的输出值 深度学习项目拆解:识别猫的项目_数据_06
  • 深度学习项目拆解:识别猫的项目_数据_07

深度学习项目拆解:识别猫的项目_h5_08

就把多个样本中用 for 循环实现的多步串行计算,改成了用矩阵实现的一步完成的并行计算。

 


得到本轮迭代的损失值

if __name__ == '__main__':
    train_set_x, train_set_y, test_set_x, test_set_y = load_dataset()
    # 加载数据
    
    fc_net = [12288, 4, 3, 2, 1] 
	# 输入层->第1层->第2层->第3层->第4层->a    
	# 输出值a,a>0.5 ? 1:0
    
    parameters = init_parameters(fc_net)
    # 初始化权值
    
    AL,cache= forward_pass(train_set_x, parameters)
    # 最后一层激活值AL = train_set_x 输入数据、parameters W、b 保存位置

	cost = compute_cost(AL, train_set_y)

使用损失函数计算,预测值与标签值(真实值)的差距。

def compute_cost(AL, Y):
    m = Y.shape[1]                           # Y =(1,209)
    cost = (1/m)*np.sum((1/2)*(AL-Y)*(AL-Y)) # 代价函数
    return cost

 


求最末层误差,反向传播计算各层梯度

if __name__ == '__main__':
    train_set_x, train_set_y, test_set_x, test_set_y = load_dataset()
    # 加载数据
    
    fc_net = [12288, 4, 3, 2, 1] 
	# 输入层->第1层->第2层->第3层->第4层->a    
	# 输出值a,a>0.5 ? 1:0
    
    parameters = init_parameters(fc_net)
    # 初始化权值
    
    AL,cache= forward_pass(train_set_x, parameters)
    # 最后一层激活值AL = train_set_x 输入数据、parameters W、b 保存位置
    
    cost = compute_cost(AL, train_set_y)
    
    gradient = backward_pass(AL, parameters, cache, train_set_y)
    # 反向传播计算梯度

我们来实现反向传播 backward_pass

def backward_pass(AL, parameters, cache, Y):
    m = Y.shape[1]                         # 样本总数
    gradient = {}   					   # 保存各层参数梯度的字典
    Layer_num = len(parameters) // 2
    dZL = (AL-Y)*(AL*(1-AL))               # 获取最末层误差信号 dZL.shape = (1,209)  
    gradient["dW"+str(Layer_num)] = (1/m)*np.dot(dZL,cache["A"+str(Layer_num-1)].T)
    gradient["db"+str(Layer_num)] = (1/m)*np.sum(dZL,axis=1,keepdims = True)
    
    for L in reversed(range(1,Layer_num)): # 遍历[3,2,1],其中reversed函数[1,2,3]颠倒为[3,2,1]
        dZL = np.dot(parameters["W"+str(L+1)].T,dZL)*(AL*(1-AL))
        gradient["dW"+str(L)] = (1/m)*np.dot(dZL,cache["A"+str(L-1)].T)
        gradient["db"+str(L)] = (1/m)*np.sum(dZL,axis=1,keepdims = True)
        
    return gradient

 


根据各层的w、b梯度,使用梯度下降更新一次参数

if __name__ == '__main__':
    train_set_x, train_set_y, test_set_x, test_set_y = load_dataset()
    # 加载数据
    
    fc_net = [12288, 4, 3, 2, 1] 
	# 输入层->第1层->第2层->第3层->第4层->a    
	# 输出值a,a>0.5 ? 1:0
    
    parameters = init_parameters(fc_net)
    # 初始化权值
    
    AL,cache= forward_pass(train_set_x, parameters)
    # 最后一层激活值AL = train_set_x 输入数据、parameters W、b 保存位置
    
    cost = compute_cost(AL, train_set_y)
    
    gradient = backward_pass(AL, parameters, cache, train_set_y)
    # 反向传播计算梯度
    
    iterations = 500
    LearnRate = 0.01
    costs = []                               
    # 保存我们每次迭代计算得到的代价值
    parameters = update_parameters(gradient, parameters, LearnRate)
    # 根据梯度更新一次参数

得到梯度后,实现梯度下降。

def update_parameters(gradient,parameters,LearnRate):
    # w : =w-r*dw、b := b-r*db
    Layer_num = len(parameters) // 2
    for L in range(1,Layer_num+1): 
        parameters["W"+str(L)] = parameters["W"+str(L)] - LearnRate*gradient["dW"+str(L)]
        parameters["b"+str(L)] = parameters["b"+str(L)] - LearnRate*gradient["db"+str(L)]
    
    return parameters

 


重复以上步骤,直到损失值低于设定阈值,模型收敛

if __name__ == '__main__':
    train_set_x, train_set_y, test_set_x, test_set_y = load_dataset()
    # 加载数据
    
    fc_net = [12288, 4, 3, 2, 1] 
	# 输入层->第1层->第2层->第3层->第4层->a    
	# 输出值a,a>0.5 ? 1:0
    
    parameters = init_parameters(fc_net)
    # 初始化权值
    
    iterations = 500
    LearnRate = 0.01
    costs = []                                # 保存我们每次迭代计算得到的代价值

    for iteration in range(0, iterations):
        AL, cache = forward_pass(train_set_x, parameters) 
        # 计算代价值
        cost = compute_cost(AL, train_set_y) 
        
        if iteration%100 == 0:     # 每100个迭代周期打印一次代价值
            print("iteration = ", iteration,";    cost = ", cost)
            costs.append(cost)
            
        # 反向传播计算梯度
        gradient = backward_pass(AL, parameters, cache, train_set_y)
        
        # 根据梯度更新一次参数
        parameters = update_parameters(gradient, parameters, LearnRate)

封装为一个 model 函数,参数定义、数据加载并没有列入。

def model(fc_net, train_set_x, train_set_y, iterations=2000, LearnRate=0.01):
    # 初始化参数
    parameters = init_parameters(fc_net)   
    costs = []  # 保存我们每次迭代计算得到的代价值
    for iteration in range(0, iterations):
        AL,cache = forward_pass(train_set_x, parameters) 
        # 计算代价值
        cost = compute_cost(AL,train_set_y) 
        
        if iteration%500 == 0: # 每500个迭代周期打印一次代价值
            print("iteration = ",iteration,";    cost = ",cost)
            costs.append(cost)
            
        # 反向传播计算梯度
        gradient = backward_pass(AL, parameters, cache, train_set_y)
        
        # 根据梯度更新一次参数
        parameters = update_parameters(gradient, parameters, LearnRate)
    
    return parameters

 


神经网络的探索

梯度检验,检测反向传播是否有问题

代价值正常的走势:

深度学习项目拆解:识别猫的项目_神经网络_09


但迭代到一定程度时,后面已经停滞了:

深度学习项目拆解:识别猫的项目_h5_10


会不会是反向传播实现的有问题呢?那我们可以使用梯度检验来做检测。

梯度的求得有俩种方法:

  • 解析法:求得梯度解析表达式,通过表达式得到梯度(确切解,当前反向传播便是如此)
  • 数值逼近:近似解

对比俩种方法的值,只要近似,就说明我们的反向传播没有问题。

# 模型中添加梯度检验
def model(fc_net, train_set_x, train_set_y, check=False, iterations=2000, LearnRate=0.01, active_func="ReLU"):
    # 初始化参数
    parameters = init_parameters(fc_net)   
    costs = []  # 保存我们每次迭代计算得到的代价值
    for iteration in range(0, iterations):
        AL, cache = forward_pass(train_set_x, parameters) 
        # 计算代价值
        cost = compute_cost(AL, train_set_y) 
        
        if iteration%500 == 0: # 每500个迭代周期打印一次代价值
            print("iteration = ",iteration,";    cost = ",cost)
            costs.append(cost)
            
        # 反向传播计算梯度
        gradient = backward_pass(AL, parameters, cache, train_set_y)
        
        if check and iteration==2000:
            gradient_check(train_set_x, train_set_y, gradient, parameters)
            
        # 根据梯度更新一次参数
        parameters = update_parameters(gradient, parameters, LearnRate)
    
    return parameters
if __name__ == '__main__':
    # 加载数据
    train_set_x, train_set_y, test_set_x, test_set_y = load_dataset()
    
    # 定义全连接神经网络各层神经元个数,并初始化参数w和b
    fc_net = [12288,10,3,2,1]       # 四层网络(梯度消失)
    
    # 开始训练
    parameters = model(fc_net, train_set_x, train_set_y, iterations=8000, LearnRate=0.1, active_func="sigmoid")

gradient_check 函数实现:

def gradient_check(A0, Y, gradient, parameters, epsilon=1e-4):
    grad_vec = grad_dict_to_vector(gradient)    # 梯度字典转列向量
    param_vec = param_dict_to_vector(parameters)# 参数字典转列向量(49182,1)
    param_num = param_vec.shape[0]              # 49182
    grad_vec_approach = np.zeros(grad_vec.shape)
    
    for i in range(param_num):
        if i%1000==0:
            print("grad checking i=",i)
            
        param_vec_plus = np.copy(param_vec)
        param_vec_plus[i][0] = param_vec_plus[i][0] + epsilon
        AL,_ = forward_pass(A0,vector_to_param_dict(param_vec_plus,parameters))
        J_plus_epsilon = compute_cost(AL,Y)
        
        param_vec_minus = np.copy(param_vec)
        param_vec_minus[i][0] = param_vec_minus[i][0] - epsilon
        AL,_ = forward_pass(A0,vector_to_param_dict(param_vec_minus,parameters))
        J_minus_epsilon = compute_cost(AL,Y)

        grad_vec_approach[i][0]= (J_plus_epsilon-J_minus_epsilon)/(2*epsilon)
        
    # 在机器学习中,表征两个向量之间差异性的方法:L2范数(欧氏距离)、余弦距离
    # L2范数:主要用于表征两个向量之间数值的差异(适合现在的情况)
    # 余弦距离:主要用于表征两个向量之间方向的差异
    diff = np.sqrt(np.sum((grad_vec-grad_vec_approach)**2))/(np.sqrt(np.sum((grad_vec)**2))+np.sqrt(np.sum((grad_vec_approach)**2)))
    
    if diff > 1e-4:
        print("Maybe a mistake in your bakeward pass!!!  diff=",diff)
    else:
        print("No problem in your bakeward pass!!!  diff=",diff)

gradient_check 函数还需要几个辅助函数:

  • grad_dict_to_vector(parameters):梯度字典转向量
  • grad_dict_to_vector(gradient):梯度字典转列矩阵
  • vector_to_param_dict:列矩阵转参数字典
  • param_dict_to_vector:参数字典转列矩阵
def grad_dict_to_vector(gradient):                                   # 梯度字典转列矩阵
    Layer_num = len(gradient) // 2 
    count = 0
    for L in range(1,Layer_num+1):  
        dW_vector = np.reshape(gradient["dW"+str(L)], (-1,1))        # 将该层dW矩阵展平为一个列矩阵 (4,12288)->(49152,1)
        db_vector = np.reshape(gradient["db"+str(L)], (-1,1))        # 将该层db矩阵展平为一个列矩阵 (4,1)->(4,1)
        vec_L = np.concatenate((dW_vector, db_vector), axis=0)       # 先将该层W个b串联叠加
        if count == 0:
            vec_output = vec_L                                       # 叠加到输出列矩阵
        else:
            vec_output = np.concatenate((vec_output, vec_L), axis=0) # 逐层串联叠加
        count = count + 1
    return vec_output                                                # 返回列矩阵
# 参数字典转列矩阵,将我们所有的参数字典转换为满足我们特定所需形状的单个向量
def param_dict_to_vector(parameters):
    Layer_num = len(parameters) // 2 
    count = 0
    for L in range(1,Layer_num+1):  
        W_vector = np.reshape(parameters["W"+str(L)], (-1,1))        # 将该层W参数矩阵展平为一个列矩阵   
        b_vector = np.reshape(parameters["b"+str(L)], (-1,1))        # 将该层b参数矩阵展平为一个列矩阵 
        vec_L = np.concatenate((W_vector, b_vector), axis=0)         # 串联叠加	
        if count == 0:
            vec_output = vec_L
        else:
            vec_output = np.concatenate((vec_output, vec_L), axis=0) # 串联叠加
        count = count + 1
    return vec_output
# 参数字典转列矩阵,将所有的参数字典转换为满足我们特定所需形状的单个向量
def param_dict_to_vector(parameters):                                
    Layer_num = len(parameters) // 2 
    count = 0
    for L in range(1,Layer_num+1):    
        W_vector = np.reshape(parameters["W"+str(L)], (-1,1))        # 将该层W参数矩阵展平为一个列矩阵   
        b_vector = np.reshape(parameters["b"+str(L)], (-1,1))        # 将该层b参数矩阵展平为一个列矩阵 
        vec_L = np.concatenate((W_vector, b_vector), axis=0)         # 串联叠加	
        if count == 0:
            vec_output = vec_L
        else:
            vec_output = np.concatenate((vec_output, vec_L), axis=0) # 串联叠加
        count = count + 1
    return vec_output
# 列矩阵转参数字典,第一个输入为列矩阵,第二个输入为保存 W 和 b 的参数字典
def vector_to_param_dict(vec, param_src):   
    Layer_num = len(param_src) // 2  
    param_epsilon = param_src  
    idx_start = 0
    idx_end = 0
    for L in range(1,Layer_num+1):     
        row = param_src["W"+str(L)].shape[0]
        col = param_src["W"+str(L)].shape[1]
        idx_end = idx_start + row*col  # 该W参数矩阵元素个数
        param_epsilon["W"+str(L)] = vec[idx_start:idx_end].reshape((row,col))
        idx_start = idx_end
      
        row = param_src["b"+str(L)].shape[0]
        col = param_src["b"+str(L)].shape[1]
        idx_end = idx_start+row*col   # 该b参数矩阵元素个数
        param_epsilon["b"+str(L)] = vec[idx_start:idx_end].reshape((row,col))
        idx_start = idx_end
    return param_epsilon              # 返回添加了epsilon的参数字典

调用形式:

if __name__ == '__main__':
    # 加载数据
    train_set_x,train_set_y, test_set_x, test_set_y = load_dataset()
    # 对输入像素值做归一化(0~255)->(0~1)
    train_set_x = train_set_x/255.
    test_set_x = test_set_x/255.
    # 定义全连接神经网络各层神经元个数,并初始化参数w和b
    fc_net = [12288,4,3,2,1]
    parameters = model(fc_net, train_set_x, train_set_y, iterations=8000, LearnRate=0.01)

而后,我们看看预测结果。

if __name__ == '__main__':
    # 加载数据
    train_set_x, train_set_y, test_set_x, test_set_y = load_dataset()
    
    # 定义全连接神经网络各层神经元个数,并初始化参数w和b
    fc_net = [12288,10,3,2,1]       # 四层网络(梯度消失)
    
    # 开始训练
    parameters = model(fc_net, train_set_x, train_set_y, iterations=8000, LearnRate=0.1, active_func="sigmoid") 
    
    # 开始预测
    Predict(test_set_x, test_set_y, parameters)
def Predict(A0, Y, parameters):
    AL, _ = forward_pass(A0, parameters)
    m = AL.shape[1]
    p = np.zeros(AL.shape)
    for i in range(0,AL.shape[1]):
        if AL[0,i] > 0.5:
            p[0,i] = 1
        else:
            p[0,i] = 0           
    accuracy = (1/m)* np.sum(p==Y)
    print("accuracy =", accuracy)

 


探索各种权重初始化

def init_parameters(fc_net):
    #1.定义一个字典,存放参数矩阵W1,b1,W2,b2,W3,b3,W4,b4
    parameters = {}
    Layer_num = len(fc_net) #Layer_num=5
    
    for L in range(1,Layer_num):
        #parameters["W"+str(L)] = np.random.randn(fc_net[L],fc_net[L-1])*0.01  # 原来是 0.01
        #parameters["W"+str(L)] = np.random.randn(fc_net[L],fc_net[L-1])*np.sqrt(1/fc_net[L-1]) # Xavier初始化,针对tanh函数
        parameters["W"+str(L)] = np.random.randn(fc_net[L],fc_net[L-1])*np.sqrt(2/fc_net[L-1]) # He初始化(MSRA),针对ReLU函数
        parameters["b"+str(L)] = np.zeros((fc_net[L],1))   
        
    for L in range(1,Layer_num):
        print("W"+str(L)+"=",parameters["W"+str(L)].shape)
        print("b"+str(L)+"=",parameters["b"+str(L)].shape)
                        
    return parameters

 


探索各种优化算法

 


批量归一化


标签:set,parameters,项目,拆解,np,train,str,test,识别
From: https://blog.51cto.com/u_13937572/6439516

相关文章

  • PowerDesigner(二)-项目和框架矩阵(转)
    项目和框架矩阵项目是PowerDesigner15的新概念,通过项目系统分析/设计人员可以对模型以及各类文档进行分组。项目也可以包含框架矩阵,以表格的形式体现各个模型之间的关系。项目和框架矩阵解决了如何对模型进行统一管理的问题。1.创建框架矩阵(FEAF-联邦企业架构框架)打开PowerDesig......
  • maven 打包时将 jar 也导入jar项目
    在pom.xml中添加代码<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><version>2.8</version>......
  • 部署springboot项目到linux服务器,端口访问不了
    部署springboot项目到服务器,端口访问不了看一看之前有没有端口已经占用了ps-ef|grepjava 例如,8000,有项目已经在后台了(例如nohup设置springboot项目系统后台不挂断地运行命令)如果你的新项目的端口是8020或者8030也是不能使用的(这里是我遇到的问题)这时候关......
  • nohup设置springboot项目不挂断地运行错误
    你的linux服务器当前文件夹下之前设置过就需要后面加& 例如 你需要nohupjava-jar***********.jar&命令来将项目挂到后台......
  • 解决Vue项目在刷新页面时出现404错误的问题
    使用HTML5的history模式的问题在本地运行Vue项目时,可以直接点击路由跳转,并且刷新页面也没有问题。这是因为VueRouter默认使用HTML5的history模式,它通过修改浏览器历史记录来控制页面跳转,而不发送实际的HTTP请求。然而,当将Vue项目发布到服务器上时,服务器会根据实际的HTTP请求来......
  • docker启动node.js项目
    原文链接:https://www.cnblogs.com/yalong/p/17463847.html这里使用koa2做为演示项目,使用Dockerfile构建Docker镜像,项目Git地址:仓库地址安装Docker网上都有教程可以自行查找,这里演示的环境是在mac下进行的在node项目根目录下创建Dockerfile文件项目目录如下:Docke......
  • 敏捷项目管理及敏捷管理工具
    ​在了解敏捷项目管理之前,我们先看下敏捷和传统项目管理有什么区别。传统项目管理:阶段式项目管理模式。制定详细的计划和步骤,按计划执行,直到所有的计划执行全部结束。咖​ 敏捷项目管理模式,从愿景和高价值的目标出发,它将整个项目过程拆分为若干个迭代,每个迭代交付一个完整可......
  • #yyds干货盘点#用Python实现简单的图像识别
    在这篇文章中,我们将使用Python和TensorFlow来实现一个简单的图像识别系统。我们将使用经典的MNIST数据集,这是一个包含手写数字的数据集,用于训练和测试图像识别系统。一、准备环境首先,我们需要安装所需的库。在这里,我们将使用TensorFlow和Keras。您可以使用以下命令安装这些库:pip......
  • 1.3OpenDaylight SFC项目基础
    OpenDaylightSFC项目基础任务目的1、了解OpenDaylightSFC项目。2、掌握手动配置SFC的基本操作。任务环境设备名称软件环境(镜像)硬件环境主机Ubuntu14.04桌面版OpenDaylightCarbonCPU:2核内存:4G磁盘:20G注:系统默认的账户为:管理员权限用户名:root,密码:root@......
  • 本地项目推送至 Gitee
    本地项目推送至Gitee【一】使用git本地上传(1)登陆Gitee并新建仓库官网:工作台-Gitee.com成功创建仓库后,复制从仓库地址(上传项目时需要)(2)在本地新建一个空白文件夹,用来上传项目(3)在电脑本地安装git,在新建的这个文件目录右键点击GitBashHere打开后的面板(4)输入......