【中文】【吴恩达课后编程作业】Course 1 - 神经网络和深度学习 - 第二周编程作业

感谢源码的博客;https://hekuan.blog.csdn.net/article/details/79639509
最近在学习深度学习,第一次构建简单的神经网络,这篇博客给了我很多帮助,我在这里只记录了自己在写代码过程中的一些想法 ,上面的博主写的更清楚,请移步过去。
下面是自己的一些笔记(其中很多参考了上面博主的其实,再次感谢https://hekuan.blog.csdn.net/article/details/79639509)
在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201109202539346.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2RyZWFtbHB4,size_16,color_FFFFFF,t_70#pic_center
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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"][:])
    train_set_y_orig=np.array(train_dataset["train_set_y"][:])
    test_dataset=h5py.File('datasets/test_catvnoncat.h5',"r")
    test_set_x_orig=np.array(test_dataset["test_set_x"][:])
    test_set_y_orig=np.array(test_dataset["test_set_y"][:])

    train_set_y_orig=train_set_y_orig.reshape(1,train_set_y_orig.shape[0])#将训练集变成确定形式的1行209列的一维数组
    test_set_y_orig=test_set_y_orig.reshape(1,test_set_y_orig.shape[0])
    classes=np.array(test_dataset["list_classes"][:])


    return train_set_x_orig,train_set_y_orig,test_set_x_orig,test_set_y_orig,classes

import numpy as np
import matplotlib.pyplot as plt
from lr_utils2 import load_dataset
import pylab
train_set_x_orig, train_set_y, test_set_x_orig, test_set_y, classes = load_dataset()
m_train = train_set_y.shape[1]
m_test = test_set_y.shape[1]
num_px = train_set_x_orig.shape[1]
print("训练集的数量:m_train=", str(m_train))
print("测试集的数量:m_test=", str(m_test))
print("每张图片的宽、高:num_px=", num_px)
print("每张图片的大小:("+str(num_px)+","+str(num_px)+",3)")
print("训练集_图片的维数:", train_set_x_orig.shape)
print("训练集_标签的维数:", train_set_y.shape)
print("测试集_图片的维数:", test_set_x_orig.shape)
print("测试集_标签的维数:", test_set_y.shape)

#进行降维处理

train_set_x_flatten=train_set_x_orig.reshape(train_set_x_orig.shape[0],-1).T
test_set_x_flatten=test_set_x_orig.reshape(test_set_x_orig.shape[0],-1).T

print("训练集降维最后的维度:", train_set_x_flatten.shape)
print("训练集_标签的维数:", train_set_y.shape)
print("测试集降维最后的维度:", test_set_x_flatten.shape)
print("测试集_标签的维数:", test_set_y.shape)


#对数据集进行必要的数据处理,尽量的将数据的大小集中在【0,1】之间
train_set_x = train_set_x_flatten / 255
test_set_x = test_set_x_flatten / 255

#我们现在构建神经网络
# 第一步:确定模型结构(并将有关公式用函数表示出来)
def sigmoid(z):
    """
    :param z:任何大小的标量或者numpy数组
    :return: s:sigmoid(z)=1/(1+np.exp(-z))
    """
    s = 1/(1+np.exp(-z))
    return s
# 第二步:初始化模型的参数,在logistic模型中,我们只需要初始化w和b
def initialize_with_zeros(dim):
    """
       此函数为了初始化w和b,我们已经知道输入的每一个x是一个(12288,1)的这样一个形式,根据公式w.Tx可知道w应该是一个(dim,1)的向量,初始化用0填充即可
       :param dim: 我们想要的w矢量的大小(或者这种情况下的参数数量)
       :return: w ——维度为(dim,1)的初始化向量。
               b  ——初始化的标量
    """
    w = np.zeros((dim, 1))
    b = 0
    # Python 的 assert 语句,可以说是一个 debug 的好工具,主要用于测试一个条件是否满足。
    # 如果测试的条件满足,则什么也不做,相当于执行了 pass 语句;
    # 如果测试条件不满足,便会抛出异常 AssertionError,并返回具体的错误信息(optional)。
    assert(w.shape == (dim, 1))
    assert(isinstance(b, float) or isinstance(b, int))
    return (w,b)




#第三步就是循环
#3.1 正向传播:计算当前的损失,用损失函数的公式计算:L(a,y)=-[yloga+(1-y)log(1-a)]
#3.2 反向传播:计算当前的梯度
#备注:propagate:传播法则 因为我们使用正向传播计算损失(成本),用反向传播计算梯度,所以函数命名为propagate
def propagate(w, b, X, Y):
    """
    此函数用来实现向前传播和向后传播的成本函数以及梯度
    :param w: 权重,大小不等的数组(num_px*num_px*3,1)  所以说前面的那个dim=num_px*num_px*3
    :param b: 偏差,一个标量
    :param X:矩阵类型(num_px*num_px*3,训练数目)其实就是输入
    :param Y:真正的“标签”矢量,矩阵维度为(1,训练数目) 在前期我们是要输入这个参数的,然后以此训练样本,估算正确率
    :return:cost:逻辑回归的负对数似然成本
            dw:相对于w的损失梯度,因此与w有相同的形状
            db:相对于b的损失梯度,因此与b有相同的形状
    """
    m = X.shape[1]  #训练数目
    A = sigmoid(np.dot(w.T, X)+ b)
    cost = (- 1 / m) * np.sum(Y * np.log(A) + (1 - Y) * (np.log(1 - A)))
    #反向传播
    dw = (1 / m) * np.dot(X, (A-Y).T)
    db = (1 / m) * np.sum(A-Y)
    assert(dw.shape==w.shape)
    assert(db.dtype==float)
    cost=np.squeeze(cost)
    assert(cost.shape==())
    #创建一个字典将dw和db的值保存起来,也方便以后的更新,命名为grads:梯度
    grads = {
        "dw":dw,
        "db":db
    }
    return (grads , cost)

#3.3 以3.2的梯度为基础更新参数(梯度下降法)
#再次来复习一下公式:w:=w-αdw;   b:=b-αdb
#所以说我们定义的这个函数的输入参数要有w,b,X,Y,α(学习率),以及迭代的次数
#其实如果我不看别人的代码,可能有一个参数print_cost我是不会想到的,这个参数就是说每100步打印一下cost,并不是每次下降都打印
def optimize(w , b ,X , Y , num_iterations , learning_rate , print_cost=False):
    """
    此函数通过运行梯度下降算法来优化参数w和b
    :param w:
    :param b:
    :param X:
    :param Y:
    :param num_iterations: 优化循环的迭代次数
    :param learning_rate: 梯度下降更新规则的学习率
    :param print_cost: 每100步打印一次损失值
    :return: :包含权重w和偏差b的字典
            grads:包含权重和偏差相对于成本函数的梯度的字典:即dw和db
            成本:优化期间计算的所有成本列表,将用于绘制学习曲线

    提示:
    我们需要写两个步骤并遍历它们:
    (1)计算当前参数的成本和梯度,使用propagate()函数
    (2)使用w和b的梯度下降算法更新参数
    """
    costs = []
    for i in range(num_iterations):             #等会再来看看为啥是从i开始
        grads, cost = propagate(w, b, X, Y)
        dw = grads["dw"]
        db = grads["db"]
        w = w-learning_rate * dw
        b = b-learning_rate * db
        if i % 100 == 0:
             costs.append(cost)  #每100次迭代一次,即每100次将cost的值追加在costs数组末尾
        if (print_cost) and (i % 100 == 0):
             print("迭代的次数: %i , 误差值: %f" % (i, cost))
    params = {
        "w": w,
        "b": b
    }
    grads = {
            "dw": dw,
            "db": db
        }

    return (params , grads , costs)


def predict(w,b,X):
    """
    这个函数使用学习逻辑回归参数logistic(w,b)预测标签是0还是1,其实就是用的前面一直在提到的sigmoid公式
    :param w:
    :param b:
    :param X:
    :return:Y_predict:包含X中所有图片的所有预测【0/1】的一个numpy数组(向量)
    """
    m = X.shape[1]  #图片的数量
    Y_prediction = np.zeros((1,m))  #将Y_prediction的形状先表示出来,它和输入X有着一样的数量,但维度为1
    w = w.reshape(X.shape[0],1)   #w的形状应该与一个X0输入的一样
    A = sigmoid(np.dot(w.T, X)+b)  #A就是那个预测值,介于0到1之间
    for i in range(A.shape[1]):
        Y_prediction[0,i] = 1 if A[0,i] > 0.5 else 0
    assert (Y_prediction.shape == (1,m))
    return Y_prediction   #其实就是视频中的y帽

#最后一步,调用之前写好的函数来  构建逻辑回归模型

def model(X_train, Y_train, X_test, Y_test, num_iterations=2000, learning_rate=0.5, print_cost=False):
    """
    :param X_train: numpy数组,维度是(num_px*num_px*3,m_train)的训练集
    :param Y_train: numpy数组,维度是(1,m_train)的训练标签集
    :param X_test: numpy数组,维度数(num_px*num_px*3,m_test)的测试集
    :param Y_test: numpy数组,维度是(1,m_test)的测试标签集
    :param num_iterations: 迭代次数
    :param learning_rate: 学习速率的超参数
    :param print_cost:
    :return:
    d:包含有关模型信息的字典
    """
    w,b = initialize_with_zeros(X_train.shape[0])
    parameters, grads, costs = optimize(w, b, X_train, Y_train, num_iterations, learning_rate, print_cost)
# optimize:return: params:包含权重w和偏差b的字典
#                  grads:包含权重和偏差相对于成本函数的梯度的字典:即dw和db
#                  成本:优化期间计算的所有成本列表,将用于绘制学习曲线
    w, b = parameters["w"],parameters["b"]
    Y_prediction_test = predict(w, b, X_test)
    Y_prediction_train = predict(w, b, X_train)
#打印训练后的准确性
    print("训练集准确性:", format(100-np.mean(np.abs(Y_prediction_train - Y_train))*100), "%")
#备注:numpy.mean(a,axis=None,out=None)沿指定轴计算算术平均值
    print("测试集准确性:", format(100-np.mean(np.abs(Y_prediction_test - X_test))*100), "%")
    d = {
        "costs":costs,
        "Y_prediction_test":Y_prediction_test,
        "Y_prediction_train":Y_prediction_train,
        "w":w,
        "b":b,
        "learning_rate":learning_rate,
        "num_iterations":num_iterations
    }
    return d
d = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations=2000, learning_rate=0.5,print_cost=True)
#最后一步用图的方式将我们做的事情展示出来
costs = np.squeeze(d['costs'])
plt.plot(costs)
plt.ylabel('cost')
plt.xlabel('iterations(per hundreds)')
plt.title("Learning rate =" + str(d["learning_rate"]))
plt.show()

#第一次运行的时候不知道为什么我的图没有出啦,我之前
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值