Logistics回归算法预测猫(吴恩达深度学习第一周视频知识点+作业总结)
视频知识点:
一、基本命名方法
:训练集样本数目:{(x1,y1),(x2,y2),……}
:测试集样本数目
x:nx维的特征向量 y∈{0,1}
输入X :m列,nx行 : X.shape=(nx,m)
输出Y:m列 ,1行 : Y.shape=(1,m)
二、激活函数
常见的激活函数有四种:
sigmoi函数:通常只适用于二分类问题的输出层

其公式为:
tanh函数:在很多情况下比sigmoid函数更加优越

相对于sigmoid函数,tanh函数中心点在原点处
ReLU函数:适用于大部分情况

ReLU函数适用性很强,且速度快
leaky ReLU函数:
leaky ReLU函数相对于ReLU函数,在z<0时,是一条过原点且有倾斜度的直线
注:在这个模型中我们使用sigmoid函数,因为输出层是一个二分类问题,即为“cat” or "no cat"
三、损失函数、成本函数
损失函数是“一个样本”的误差,成本函数是“整个数据集”的平均误差
我们的目标就是:找到更好的w和b使这个成本函数得到的值更小
损失函数:

成本函数:
注意:这里的log相当于是ln
四、梯度下降法
通过沿着函数梯度(下降最快)的方向逐步调整参数,以最小化损失函数的优化算法

这里,先放在二维坐标系里面计算w:

同理,b也是一样:

五、反向传播

如图,前面通过正向传播(黑色线),我们得到损失函数L的值,然后我们可以反向(红色线)求得dw,db,从而更新w和b的值,使损失函数的值更小
这里,各处的求导即在图中
下图是具体更新w,b的方法:J+上单个训练样本的损失值;在for循环之后,对求得的j和m求平均值;最后,对w和b的值进行更新

这里,我在看视频的时候会产生疑惑:为什么z上面要加一个i?
因为z是针对单个训练样本,所以要加上i,以便得知是针对哪个样本所求得的z
六、向量化
在向量化之前,我们需要弄懂np的几个函数:
np.sum(axis=0):每一列在竖直方向上求和
np.sum(axis=1):每一行在水平方向上求和
np.zeros:用于创建一个指定形状的数组,数组中的所有元素都被初始化为 0
np.log:求数组里面每个数的对数
np.abs:求数组里面每个数的绝对值
np.maximu(v,0): 把数组(或标量)v 里的每一个元素都和 0 比较,返回两者中的较大者,就是把 v 里所有负数截成 0,其余保留
np.array: 创建一个目标数组,例如arr = np.array([0, 2]),那么得到arr:[0,2]
np.dot:
| 输入 a | 输入 b | 函数行为 |
| 一维 `(N,)` | 一维 `(N,)` | 向量内积 `sum(a*b)` |
| 二维 `(M,N)` | 二维 `(N,K) | 矩阵乘法 `a @ b` 或 `a.matmul(b)` |
| 多维 `(…,M,N)` | 多维 `(…,N,K)` | 批量矩阵乘法(最后两维做乘,前面广播) |
| 多维/混合 | 任意 | 把 ≥1-D 的输入当成向量/矩阵,按广播规则做内积 |
七、广播
NumPy让不同形状的数组进行数学运算时自动扩展维度以匹配的机制。

举例子,如图中的列向量[1,2,3,4]需要加上100,那么广播会自动将100拓展成为[100,100,100,100],这样每个数都能加上100,其他例子也是一样
最后,具体传播过程:
正向传播,一次迭代完成:

反向传播:

L1W2作业:
一、建立学习算法的一般架构
1、初始化模型参数
2、通过最小化损失来学习模型的参数
3、使用学习到的参数进行预测(在测试集上)
4、分析结果并得出结论
二、引入头函数:
import numpy as np import matplotlib.pyplot as plt import h5py import scipy from PIL import Image from scipy import ndimage from Lr_utilss import load_dataset %matplotlib inline
注意:这里的%matplotlib inline:让 matplotlib 生成的图表直接嵌入在 Notebook 页面中显示
三、加载数据集
train_set_x_orig,train_set_y,test_set_x_orig,test_set_y,classes = load_dataset()#获取数据集
这里,train_set_x_orig和test_set_x_orig的每一行都是代表图像的数组,且在图像数据集(训练和测试)的末尾添加了"_orig",以便对其进行预处理。预处理后,我们将得到train_set_x和test_set_x(标签train_set_y和test_set_y不需要任何预处理)
这里还可以通过以下代码可视化示例。 还可以随意更改index值并重新运行以查看其他图像。
index = 5
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.imshow(train_set_x_orig[index]):显示第index个图片
np.squeeze(train_set_y[:,index]):移除多余的维度(长度为1的维度),得到标量值:
举个例子:
arr = np.array([[[1], [2], [3]]])
print("原来的形状:", arr.shape) # 输出:(1, 3, 1) 三维了
squeezed = np.squeeze(arr)
print("挤掉后的形状:", squeezed.shape) # 输出:(3,)
print("数组内容:", squeezed) # 输出:[1 2 3]
decode("utf-8"):将字节字符串解码为普通字符串
四、预处理数据集
步骤如下:
1、找出数据的尺寸和维度(m_train,m_test,num_px等)
2、重塑数据集,以使每个示例都是大小为(num_px \ num_px \ 3,1)的向量
3、“标准化”数据
1、找出数据的尺寸和维度
m_train = train_set_x_orig.shape[0]#找到训练集样本数量
m_test = test_set_x_orig.shape[0]#找到测试集样本数量
num_px = train_set_x_orig.shape[1]#每个图像的宽/高
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))
2、重塑数据集
为了便于后续矩阵乘法运算,这里需要以维度(num_px ∗ num_px ∗ 3, 1)的numpy数组重塑维度(num_px,num_px,3)的图像
当你想将维度为(a,b,c,d)的矩阵X展平为形状为(b∗c∗d, a)的矩阵X_flatten时的一个技巧是:
X_flatten = X.reshape(X.shape [0],-1).T # 其中X.T是X的转置矩阵
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: " + str(train_set_x_flatten.shape))
print ("train_set_y shape: " + str(train_set_y.shape))
print ("test_set_x_flatten: " + str(test_set_x_flatten.shape))
print ("test_set_y shape: " + str(test_set_y.shape))
print("sanity check after reshaping: "+str(train_set_x_flatten[0:5,0]))
注意:当我们将 (length, height, 3) 的图像转换为 (length*height*3, 1) 的向量时,每一行代表图像中的一个单独的通道值。第1行: 第一个像素的R通道值,第2行: 第一个像素的G通道值,第3行: 第一个像素的B通道值
3、标准化数据
图片数据集的标准化处理很简单,只需要将数据集的每一行除以255(像素通道的最大值)
train_set_x = train_set_x_flatten/255.0 test_set_x = test_set_x_flatten/255.0
五、构建神经网络
建立神经网络的主要步骤是:
1.定义模型结构(例如输入特征的数量)
2.初始化模型的参数
3.循环:
计算当前损失(正向传播)
计算当前梯度(向后传播)
更新参数(梯度下降)
一、初始化模型参数
这里需要对w,b进行初始化,将w初始化成一个二维数组,b初始化成float/int型常量
def initialize_with_zeros(dim):
w = np.zeros((dim,1))#Np.zeros:用于创建一个指定形状的数组,数组中的所有元素都被初始化为 0
b = 0
assert(w.shape==(dim,1))#assert:声明这个数组就是这样的形状
assert(isinstance(b,float) or isinstance(b,int))
return w, b
dim = 2
w, b = initialize_with_zeros(dim)
print("w = "+str(w))
print("b = "+str(b))
二、循环
1、计算当前损失(正向传播)
首先需要构建一个sigmoid函数:
def sigmoid(z): s = 1/(1+np.exp(-z)) return s print("sigmoid([0,2]):",str(sigmoid(np.array([0,2]))))
正向传播的步骤:

2、计算梯度(反向传播)

通过求出dw,db从而不断更新w,b的值
def propagate(w,b,X,Y): 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)#确保db的类型是float cost = np.squeeze(cost)#确保cost是一维 assert(cost.shape==()) grads = {"dw": dw, "db": db}#创建一个梯度字典,用于存储逻辑回归的梯度值 return grads,costdef optimize(w,b,X,Y,num_iterations,learning_rate,print_cost): costs = []#创建一个空的成本列表 for i in range(num_iterations): 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次,把cost添加进列表 if print_cost and i %100 ==0: print("Cost after iteration %i:%f"%(i,cost)) params = {"w":w,"b":b}#创建一个字典,用于存储w,b grads = {"dw": dw, "db": db}#创建一个梯度字典,用于存储逻辑回归的梯度值 return params,grads,costs params,grads,costs = optimize(w,b,X,Y,num_iterations=100,learning_rate=0.009,print_cost=True) print("w "+ str(params["w"])) print("b "+ str(params["b"])) print("dw " + str(grads["dw"])) print("db " + str(grads["db"])) print(costs)
六、预测函数
1.计算![]()
2.将a的项转换为0(如果激活<= 0.5)或1(如果激活> 0.5),并将预测结果存储在向量“ Y_prediction”中
def predict(w,b,X):
m = X.shape[1]
Y_prediction = np.zeros((1,m))
w = w.reshape(X.shape[0],1)#确保权重向量 w 的形状与输入特征矩阵 X 的维度匹配,这样才能进行后面的相乘
A = sigmoid(np.dot(w.T,X)+b)
for i in range(A.shape[1]):
if A[0, i] <=0.5:
Y_prediction[0,i] = 0
else:
Y_prediction[0,i] = 1
assert (Y_prediction.shape == (1,m))
return Y_prediction
七、合并所有的功能
将所有实现的功能以正确的顺序放在一起,从而得到整体的模型结构
def model(X_train,Y_train,X_test,Y_test,num_iterations=20000,learning_rate=0.005
,print_cost=True):
w,b = initialize_with_zeros(X_train.shape[0])#初始化w,b
parameters,grads,costs = optimize(w,b,X_train,Y_train,num_iterations,learning_rate,print_cost)#正向反向传播得到w,b,aw,ab
w = parameters["w"]
b = parameters["b"]
Y_prediction_test = predict(w,b,X_test)
Y_prediction_train = predict(w,b,X_train)
print("train accuracy: {} %".format(100-np.mean(np.abs(Y_prediction_train - Y_train)) * 100))
print("test accuracy: {} %".format(100-np.mean(np.abs(Y_prediction_test - Y_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
其中:
-
np.abs():取绝对值(确保差异都是正数) -
np.mean():计算平均误差 -
* 100:将误差转换为百分比形式 -
100 - ...:用100%减去误差率得到准确率
最后运行以下单元格训练模型:
d = model(train_set_x,train_set_y,test_set_x,test_set_y,num_iterations=20000,
learning_rate=0.005,print_cost=True)
八、对测试集预测
index = 1
plt.imshow(test_set_x[:,index].reshape((num_px,num_px,3)))
print("y = " + str(test_set_y[0,index]) + ", you predicted that it is a \"" + classes[int(d["Y_prediction_test"][0,index])].decode("utf-8")+ "\"picture.")
九、绘制损失函数和梯度
costs = np.squeeze(d['costs'])#从d中取出对应cost键的值,并确保是一维
plt.plot(costs)#绘制成本随迭代次数变化的曲线,costs是包含每次迭代成本的数组
plt.ylabel('cost')
plt.xlabel('iteration(per hundreds)')
plt.title("Learning rate = " + str(d["learning_rate"]))
plt.show
更多推荐



所有评论(0)