文章目录
这一部分内容是跟着 吴恩达《深度学习》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
这里有两个问题:
- 前面搭建环境时候的解释器选择的是torch那个,这里会疯狂报错因为没有那些数据包…
解决方案:ctrl+shif+p选择python:解释器选项后,选择非base的那个解释器就可以了。如下图
但问题是这样后torch好像就不行了…可能是我操作理解的问题?有无好心人帮助一下sos
-
在最后一个语句
%matplotlib inline
时候一直报错SyntaxError: invalid syntax
解决方案:把这个语句换成plt.show()
应该就可以了,原因是%matplotlib inline这个语句是jupyter notebook用的语句。我下面做下去康康对不对验证一下✍ -
在作业中的数据需要下载,然后放入同级目录下,如下图:
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
对于数据集的内容,利用下面的语句进行展开康康可以。这里实现了两个功能:
- 对输入的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)的向量
- “标准化”数据
在这里具体而言:
- 数据集向量化:对于维度为(a,b,c,d)维度数据向量化的小技巧为
X_flatten = X.reshape(X.shape [0],-1).T # 其中X.T是X的转置矩阵
- 数据集标准化:由于给定的是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+e−z(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))−(1−y(i))log(1−z(i))J=m1i=1∑m(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=θj−m1i=1∑m(y^j(i)−yj(i))xj(i)
最后,对于整体的实现引用作业中的图来表达一下这个算法的简单程度:
2.2 代码落地
建立神经网络的主要步骤是:
- 定义模型结构(例如输入特征的数量)
- 初始化模型的参数
- 循环:
-计算当前损失(正向传播)
-计算当前梯度(向后传播)
-更新参数(梯度下降)
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 前向和后向传播
对于梯度