吴恩达神经网络与深度学习第一课第二章作业-logistics回归

logistics实现判断猫

任务

给定数据是一些图片,其中有部分是猫的图片,需要做的是训练模型,判断图片是否猫的图片

导入第三方库

import numpy as np 
import matplotlib.pyplot as plt #画图工具
import h5py #处理h5文件工具包
from lr_utils import load_dataset #导入题目给出的数据读入代码

接下来开始一步步实现

第一步:认识数据

#导入数据,数据返回值与题目中同步
def loadData(): 
    """
    返回值
        train_set_x_orig:训练集图像数据

        train_set_y_orig:训练集的图像类别,0表示不是猫,1表示是猫

        test_set_x_orig: 测试集的图像数据

        test_set_y_orig: 测试集的图像类别

        classes :[b'non-cat' b'cat'],存储两个字符串,表示类别
    """
    train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes = load_dataset()
    return train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes
#测试,了解数据的维度信息,通过输出结果,可以看到,图片尺寸为(64,64),通道数为3,训练集图片数目209,测试集50张
train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes = loadData()
print("train_set_x_orig",train_set_x_orig.shape)
print("train_set_y_orig",train_set_y_orig.shape)
print("test_set_x_orig",test_set_x_orig.shape)
print("test_set_x_orig",test_set_y_orig.shape)
print("classes",classes.shape)
print(type(test_set_y_orig))
print(train_set_y_orig.shape[1])

输出如下,数据是图片数据,图片尺寸为(64,64),通道数为3,训练集图片数目209,测试集50张
在这里插入图片描述

第二步:数据预处理

数据预处理部分包括拉伸维度和数据标准化,将数据维度变为下图
在这里插入图片描述
假设有m个样本,在本题中即为209个样本图片,对图片进行拉伸后,由三维到一维,即每一列为一张图片数据,图片特征数为(64643),即为像素点。则处理后的训练集的维度为(64643,m)

def predata(train_set_x_orig,test_set_x_orig):
    """
        参数
        train_set_x_orig 训练集,(209,64,64,3)
        test_set_x_orig 测试集 (50,64,64,3)
        
        返回值
        train_x (64*64*3,209)
        test_x  (64*64*3,50)
    
    """
    #以训练集为例,原始为(209,64,64,3),第一步变换为(209,64*64*3),参数 -1,自动计算图片矩阵的像素点个数,第二步,对其进行转置
    train_x = train_set_x_orig.reshape(train_set_x_orig.shape[0],-1).T  
    test_x = test_set_x_orig.reshape(test_set_x_orig.shape[0],-1).T 

    return train_x,test_x
#归一化处理,图片像素值在0~255之间 
def normalization(train_x,test_x ):
    train_x = train_x/255.0
    test_x = test_x/255.0
    return train_x,test_x

第三步:模型实现

1、模型初始化
对w和b进行初始化,采用随机初始化,乘0.01必须要有,让w刚开始尽可能小点,因为最开始没有加,导致损失值一直为NaN

def initialize(dim):
    
    w = np.random.randn(dim,1)*0.01
    b = 0
    
    assert(w.shape == (dim,1))
    
    return w,b

2、前向传播
首先对一个样本处理,
目标函数:
z ( i ) = w T x ( i ) + b z^{(i)}=w^{T} x^{(i)}+b z(i)=wTx(i)+b
通过sigmoid函数将目标结果映射到0到1之间
y ^ ( i ) = a ( i ) = sigmoid ⁡ ( z ( i ) ) \hat{y}^{(i)}=a^{(i)}=\operatorname{sigmoid}\left(z^{(i)}\right) y^(i)=a(i)=sigmoid(z(i))
计算出损失值
L ( a ( i ) , y ( i ) ) = − y ( i ) log ⁡ ( a ( i ) ) − ( 1 − y ( i ) ) log ⁡ ( 1 − a ( i ) ) \mathcal{L}\left(a^{(i)}, y^{(i)}\right)=-y^{(i)} \log \left(a^{(i)}\right)-\left(1-y^{(i)}\right) \log \left(1-a^{(i)}\right) L(a(i),y(i))=y(i)log(a(i))(1y(i))log(1a(i))

对其进行向量化后
z = w T x + b z=w^{T} x+b z=wTx+b
y ^ = a = sigmoid ⁡ ( z ) \hat{y}=a=\operatorname{sigmoid}\left(z\right) y^=a=sigmoid(z)
L ( a , y ) = − y log ⁡ ( a ) − ( 1 − y ) log ⁡ ( 1 − a ) \mathcal{L}\left(a, y\right)=-y \log \left(a\right)-\left(1-y\right) \log \left(1-a\right) L(a,y)=ylog(a)(1y)log(1a)
在这里插入图片描述

def pry(w,b,X):
    """
    参数
      w: 权重参数(64*64*3,1)=(12288,1)
      X: (64*64*3,209)
      
    返回值
      y :(1,209)
    """
    y = np.dot(w.T , X) + b
    return y
def sigmoid(w,b,X):
    
    z = pry(w,b,X)
    
    y_m = 1/(1+np.exp(-z))
    
    return y_m
def getcost(w,b,X,y):
    """
    
    	y_m :(1,209)
    	y: (1,209)
    """
    
    y_m = sigmoid(w,b,X)  
    l = y*np.log(y_m) + (1-y)*np.log(1-y_m)
    
    
    m = X.shape[1]
    j = (-1/m)*np.sum(l)
    return j

3、后向传播
后向传播即要算出dw,db,确定参数w和b的更新方向,下面是手推过程,特别要理解计算图。
在这里插入图片描述
下面是向量化后的实现方式。

def derivation(w,b,X,Y):
    m = X.shape[1]
    A = sigmoid(w,b,X)
    dw = (1 / m) * np.dot(X, (A - Y).T)
    db = (1 / m) * np.sum(A - Y) 
    
    return dw,db

3、模型综合

def updata(w,b,X,Y,num_iterations,learning_rate):
    costs = []
    
    #设置num_iterations次迭代
    for i in range(num_iterations):
        
        cost = getcost(w,b,X,Y)
        
        dw ,db = derivation(w,b,X,Y)
        
        #更新w和b
        w = w - dw*learning_rate
        b = b - db*learning_rate
        #保存损失值
        costs.append(cost)
        
        if(i%100==0):
            print("迭代的次数: %i , 误差值: %f" % (i,cost))

    return w,b,costs

4、模型检验

模型预测函数,传入训练好的参数w,b

def predict(w,b,X):
    
    #y_pre = np.zero(1,x.shape[1])
    
    y_pre = sigmoid(w,b,X)
    #当预测概率大于等于0.5,将值改为1,小于0.5,改为0
    y_pre = np.where(y_pre < 0.5 , 0 , 1)
    return y_pre

统计预测和数据集中的类别值相同元素的个数

def accuracy_rate(y_pre,y_ori):
    #判断两个列表中值相同的
    num = y_ori.shape[1]
    y = y_pre-y_ori #元素对应位置相减
    num_0 = np.sum(y == 0)#统计值为0的个数
    return num_0/num
def showcosts(costs,learning_rate,num_iterations):
    
    plt.plot(costs)
    plt.ylabel('cost')
    plt.xlabel('iterations')
    plt.title("learning rate = " + str(learning_rate) + "," + 'num_iterations = ' + str (num_iterations))
    plt.show()
def model(num_iterations,learning_rate):
    
    
    #导入数据并进行预处理
    train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes = loadData()
    train_x,test_x = predata(train_set_x_orig,test_set_x_orig)
    train_x,test_x = normalization(train_x,test_x )
    train_y = train_set_y_orig
    test_y = test_set_y_orig
    
    #初始化参数
    w,b = initialize(train_x.shape[0])
    w , b ,costs = updata(w,b,train_x,train_y,num_iterations,learning_rate)
    
    showcosts(costs,learning_rate,num_iterations)
    
    #计算在训练集上的准确率
    y_pre = predict(w,b,train_x)
    acc = accuracy_rate(y_pre,train_y)
    print("训练集准确性:"  , acc*100 ,"%")
    
    
    #计算在测试集上的准确率
    y_pre = predict(w,b,test_x)
    acc = accuracy_rate(y_pre,test_y)
    print("测试集准确性:"  , acc * 100 ,"%")
def main():
    #定义超参数
    num_iterations = 2000
    learning_rate = 0.005
    model(num_iterations,learning_rate)

参考文章

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值