w1_用神经网络思想实现Logistic回归_cat判断实例


这一部分内容是跟着 吴恩达《深度学习》L1W2作业2 做的

一、环境熟悉

1. 安装包

首先遇见一个问题,给定的问题概述的安装包中给出的语句是这样的:

import numpy as np
import matplotlib.pyplot as plt
import h5py
import scipy
from PIL import Image
from scipy import ndimage
from lr_utils import load_dataset

%matplotlib inline

这里有两个问题:

  1. 前面搭建环境时候的解释器选择的是torch那个,这里会疯狂报错因为没有那些数据包…
    解决方案:ctrl+shif+p选择python:解释器选项后,选择非base的那个解释器就可以了。如下图在这里插入图片描述

但问题是这样后torch好像就不行了…可能是我操作理解的问题?有无好心人帮助一下sos

  1. 在最后一个语句%matplotlib inline 时候一直报错SyntaxError: invalid syntax
    解决方案:把这个语句换成plt.show()应该就可以了,原因是%matplotlib inline这个语句是jupyter notebook用的语句。我下面做下去康康对不对验证一下✍

  2. 在作业中的数据需要下载,然后放入同级目录下,如下图:在这里插入图片描述

2. 问题概述

给定:两个数据集分别是test_catvnoncat.h5和train_catnoncat.h5

  • train_catnoncat.h5:标记为cat(y = 1)或非cat(y = 0)的训练图像集
  • test_catvnoncat.h5:标记为cat或non-cat的测试图像集
  • 图像维度为(num_px,num_px,3),其中3表示3个通道(RGB)。 因此,每个图像都是正方形(高度= num_px)和(宽度= num_px)。

实现数据集输入的文件为lr_utils.py:

import numpy as np
import h5py
    
    
def load_dataset():
    train_dataset = h5py.File('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('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

对于数据集的内容,利用下面的语句进行展开康康可以。这里实现了两个功能:

  1. 对输入的train数据中的第30个数据的信息,包括图像内容、是否是猫等,进行了显示
    在这里插入图片描述2. 对总体的train、test数量进行显示;对图像的像素大小维度进行显示。
    在这里插入图片描述
# Loading the data (cat/non-cat)
train_set_x_orig, train_set_y, test_set_x_orig, test_set_y, classes = load_dataset()
# Example of a picture
index = 30
plt.imshow(train_set_x_orig[index])
print ("y = " + str(train_set_y[:, index]) + ", it's a '" + classes[np.squeeze(train_set_y[:, index])].decode("utf-8") +  "' picture.")
plt.show()
### START CODE HERE ### (≈ 3 lines of code)
m_train = train_set_x_orig.shape[0]
m_test = test_set_x_orig.shape[0]
num_px = test_set_x_orig.shape[1]
### END CODE HERE ###
print ("Number of training examples: m_train = " + str(m_train))
print ("Number of testing examples: m_test = " + str(m_test))
print ("Height/Width of each image: num_px = " + str(num_px))
print ("Each image is of size: (" + str(num_px) + ", " + str(num_px) + ", 3)")
print ("train_set_x shape: " + str(train_set_x_orig.shape))
print ("train_set_y shape: " + str(train_set_y.shape))
print ("test_set_x shape: " + str(test_set_x_orig.shape))
print ("test_set_y shape: " + str(test_set_y.shape))

3. 数据集处理(标准化和向量化)

预处理数据集的常见步骤是:

  • 找出数据的尺寸和维度(m_train,m_test,num_px等)
  • 重塑数据集,以使每个示例都是大小为(num_px \ num_px \ 3,1)的向量
  • “标准化”数据

在这里具体而言:

  1. 数据集向量化:对于维度为(a,b,c,d)维度数据向量化的小技巧为
    X_flatten = X.reshape(X.shape [0],-1).T # 其中X.T是X的转置矩阵
  2. 数据集标准化:由于给定的是RGB值,为了让数据范围在[-1,1]之间,采用/255的标准化方式

最终代码如下:

#vector
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
#Standardization
train_set_x = train_set_x_flatten/255.
test_set_x = test_set_x_flatten/255.

二、算法架构实现

2.1 算法复习

让我们再来一起梳理一下logistics回归对于二分类问题的实现:

  • 首先明确输入输出:
    对于输入而言给定了一个训练数据集,这个数据集的内容包括了RGB三个矩阵。在前面的预处理中我们已经向量化了,所以输入就是一个[n,1]的向量X。
    对于输出而言,要给出的就是单个y值,1表示是猫,0表示不是猫。
  • 对于每个输入我们会用logistic进行预测得到 y ^ \hat{y} y^,这里预测的公式分为两步走:
    z ( i ) = θ T x ( i ) + b y ^ ( i ) = s i g m o i d ( z ( i ) ) = 1 1 + e − z ( i ) z^{(i)} = \theta^Tx^{(i)}+b\\\hat{y}^{(i)}=sigmoid(z^{(i)}) =\frac{1}{1+e^{-z^{(i)}}} z(i)=θTx(i)+by^(i)=sigmoid(z(i))=1+ez(i)1
  • 在上述获得 y ^ \hat{y} y^后,就可以在训练级中利用实际 y y y对参数进行更新。参数更新时,涉及到两个方面:
    损失函数(向前传播): C o s t ( y ^ ( i ) , y ( i ) ) = − y ( i ) l o g ( z ( i ) ) − ( 1 − y ( i ) ) l o g ( 1 − z ( i ) ) J = 1 m ∑ i = 1 m ( C o s t ( y ^ ( i ) , y ( i ) ) Cost(\hat{y}^{(i)},y^{(i)})=-y^{(i)}log(z^{(i)})-(1-y^{(i)})log(1-z^{(i)})\\J=\frac{1}{m}\sum_{i=1}^{m}(Cost(\hat{y}^{(i)},y^{(i)}) Cost(y^(i),y(i))=y(i)log(z(i))(1y(i))log(1z(i))J=m1i=1m(Cost(y^(i),y(i))
    梯度下降(向后传播): θ j = θ j − 1 m ∑ i = 1 m ( y ^ j ( i ) − y j ( i ) ) x j ( i ) \theta_j=\theta_j-\frac{1}{m}\sum_{i=1}^{m}(\hat{y}_j^{(i)}-y_j^{(i)})x^{(i)}_j θj=θjm1i=1m(y^j(i)yj(i))xj(i)

最后,对于整体的实现引用作业中的图来表达一下这个算法的简单程度:
在这里插入图片描述

2.2 代码落地

建立神经网络的主要步骤是:

  1. 定义模型结构(例如输入特征的数量)
  2. 初始化模型的参数
  3. 循环:
    -计算当前损失(正向传播)
    -计算当前梯度(向后传播)
    -更新参数(梯度下降)

2.2-1 辅助函数(sigmoid)

之前就实现过,跟着上面的公式来就行

#sigmoid function
def sigmoid(x):
    return 1/(1 + np.exp(-x))
# test if sigmoid function is correct 
print ("sigmoid([0, 2]) = " + str(sigmoid(np.array([0,2]))))

2.2-2 参数初始化

开始把所有参数都设置为0

def initialize_with_zeros(dim):
    w = np.zeros((dim, 1))
    b = 0
    assert(w.shape == (dim, 1))
    assert(isinstance(b, float) or isinstance(b, int))
    return w, b
# test if initialize function is correct
dim = 2
w, b = initialize_with_zeros(dim)
print ("w = " + str(w))
print ("b = " + str(b))

2.2-3 前向和后向传播

对于梯度

2.2-4 优化函数

おすすめ

転載: blog.csdn.net/weixin_44986601/article/details/119088800