-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.xml
50 lines (50 loc) · 27.5 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title><![CDATA[deeplearning 课后作业1]]></title>
<url>%2F%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%2F%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E5%AE%9E%E8%B7%B51%2F</url>
<content type="text"><![CDATA[deeplearning.ai官网地址:https://www.deeplearning.ai/coursera地址:https://www.coursera.org/specializations/deep-learning网易视频地址:https://163.lu/nPtn42课程一第二周课后作业1-1 使用numpy实现基本函数实现激活函数numpy是一个python中基础的科学计算包,以下练习中,将会实现一些数学中的基础函数,如np.log(),np.exp()等。 对于机器学习中的逻辑回归激活函数,表达式为$\delta = \frac{1}{1+e^{-z}}$,对于此公式,考虑到参数$z$是一个实数,可以简单的使用python中的math实现。 123import mathdef sigmoid(z): return 1/(1+math.exp(-z)) 以上实现中,实际能够传入的参数z只能是一个数字,而在机器学习或者深度学习中,实际需要传入的参数是一个向量,所以math.exp()并不适用,可以使用numpy.exp()实现,如下所示: 1234import numpy as npdef sigmoid(z): sigmoid = 1/(1+np.exp(-z)) return sigmoid 对于一个向量而言,np.exp()的实现过程就是对向量中的每一个元素计算np.exp(),可以如下图表示: 实现激活函数梯度在之前的学习中,需要计算梯度优化使用反向传播算法的损失函数,对于此梯度的计算公式可以如下表示:$\delta’(z) = \delta(z)*(1-\delta(z))$ 代码实如下所示: 1234def sigmoid_derivative(z): s = sigmoid(z) ds = s(1-s) return ds 改变矩阵(向量)形状关于深度学习中,numpy中最常用到的两个跟矩阵或者向量形状有关的函数是shape()和reshape()。 shape():返回当前矩阵或者向量的大小。 reshape():将当前数组转化为特定形状。 具体一些用法如下所示;将一个三维图像矩阵(shape=(length,height,depth)),转化为一维数组(shape = (lenght×height×depth,1))以便于处理,具体实现方法可以由以下代码所示: 123def image2vector(image): v = image.reshape(image.shape[0] * image.shape[1] * image.shape[2], 1) return v 按行标准化:机器学习或者深度学习中,常常用到的一个数据预处理技巧是标准化,标准化后的数据能够使得算法运行速度更快,关于数据标准化的公式如下所示: $normal = \frac{x}{||x||}$ 其中,$||x||$表示范数,对于一个向量$[x_1,x_2……x_n]$,其范数计 算公式为$\sqrt{x_1^{2}+x_2^{2}+···x_n^{2}}$。 numpy已经提供了用于计算范数的函数,所以其数据标准化的处理过程可以用以下代码实现: 1234def normalizeRows(x): x_norm = np.linalg.norm(x, axis = 1, keepdims = True) x = x / x_norm return x Python广播机制和$softmax$函数为了理解python中的广播机制,一种行之有效的方法是操作两个维数不同的矩阵。使用numpy中的softmax函数理解python中的广播机制,可以将softmax函数认为是你的算法需要实现二分类或者更多分类时的数据标准化函数,其数学表示如下所示: 其实现代码如下所示: 12345import numpy as npdef softmax(x): x_exp = np.exp(x) x_sum = np.sum(x_exp,axis=1,keepdims = True) return x_exp/x_sum 2.关于两个损失函数的实现在深度学习中,损失函数常用来评估模型性能,如果损失函数的值越大,代表着模型的预测值与真实值之间的差值越大,深度学习中常用梯度下降算法来优化算法以最小化损失函数。 L1损失函数L1损失函数的定义如下所示:$$\begin{align} & L_1(\hat{y}, y) = \sum_{i=0}^m|y^{(i)} - \hat{y}^{(i)}|\end{align}$$ 其代码实现如下所示: 123def L1(y,yhat): loss = np.sum(np.abs(y-yhat)) return loss L2损失函数L2损失函数的定义如下所示:$$\begin{align} & L_2(\hat{y},y) = \sum_{i=0}^m(y^{(i)} -\hat{y}^{(i)})^2 \end{align}$$注意:对于一个向量$[X] = [x_1,x_2,···x_n]$,np.dot()的计算过 程为:np.dot(x,x) =$\sum_{i=0}^{n}x_i^{2}$,所以L2损失函数的一种有效计算方式是利用dot()函数,具体实现代码如下所示: 123def L2(y,yhat): loss = np.sum(np.dot((y-yhat),(y-yhat).T)) return loss]]></content>
<categories>
<category>深度学习</category>
</categories>
<tags>
<tag>深度学习</tag>
<tag>神经网络</tag>
</tags>
</entry>
<entry>
<title><![CDATA[具有神经网络思维的逻辑回归算法]]></title>
<url>%2F%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%2F%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E5%AE%9E%E8%B7%B52%2F</url>
<content type="text"><![CDATA[本次作业,将会构建一个逻辑回归分类器用以识别猫, 通过完成这次作业,也能了解一些神经网络的思维,并且能够建立一个对神经网络的基本认识。 deeplearning.ai官网地址:https://www.deeplearning.ai/coursera地址:https://www.coursera.org/specializations/deep-learning网易视频地址:https://163.lu/nPtn42课程一第二周课后作业1-2 本次作业,将会构建一个逻辑回归分类器用以识别猫, 通过完成这次作业,也能了解一些神经网络的思维,并且能够建立一个对神经网络的基本认识。 1. 导入相关包首先,导入,本此作业实现中所需要的所有相关包,具体实现如下: 1234567import numpy as npimport matplotlib.pyplot as pltimport h5pyimport scipyfrom PIL import Imagefrom scipy import ndimagefrom lr_utils import load_dataset 一些库的简单介绍:h5py是一个处理h5文件的交互包scipy是一个科学计算库PIL是一个图像处理库 2.数据集的概述作业所用到的数据集存储在data.h5文件中,对于数据集,有以下介绍: 数据集中的训练集m_train图像,被标注为cat (y=1)和non-cat (y=0) 数据集中的测试集m_test图像,同样,被标注为cat和non-cat 每一幅图像的都是(num_px,num_px,3)的形式,其中3表示图像是3通道的RGB形式,而长和宽都是num_px和num_px的正方形图片。 加载数据前,可以利用python查看数据集的存储形式,具体实现代码如下所示. 123456f = h5py.File('dataset/train_catvnoncat.h5','r') #打开h5文件 #可以查看所有的主键 for key in f.keys(): print(f[key].name) #输出数据集标签值,train_set_x,train_set_y print(f[key].shape) #输出数据集train_set_x,train_set_y的形式 print(f[key].value) #输出数据集trian_set_x和train_set_y的具体值 根据以上数据形式,编写loadset()函数加载数据集的代码如下所示: 123456789101112131415def 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"][:]) #测试集数据标签 classes = np.array(test_dataset["list_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 简单的测试下加载好的数据集,可以看到相关的输出信息如下所示: 123index = 5plt.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.") 许多深度学习代码存在bug的原因之一就是矩阵或者向量维数不匹配,在算法实现之前,先进行数据集的维度输出是一个和明智的做法,具体实现算法如下代码所示: 12345678910111213m_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)) 上述代码实现结果如下所示: 在图像处理过程中,数据集中的图像数据是一个(num_px,num_px,3)的矩阵,需要将其转换为(num_px×num_px×3,1)的矩阵,在python中有一个实现技巧如下所示,可轻松实现矩阵形式的转化。 1X_flatten = X.reshape(X.shape[0], -1).T 综上所述,具体实现代码可以如下所示: 1234567train_set_x_flatten = train_set_x_orig.reshape(train_set_x_orig.shape[0], -1).Ttest_set_x_flatten = test_set_x_orig.reshape(test_set_x_orig.shape[0], -1).Tprint ("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 shape: " + 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])) 以上代码结果如下所示: 为了表示图片中的颜色,由RGB通道表示图片颜色,即每个像素的值实际上是由三个0-255的数组成的向量。 机器学习中一种通用的处理数据集的方法称之为标准化,对于图像数据集而言,一种简单而又方便的处理数据的方法是对每一行数据除以255,即其RGB的最大值。具体实现可以如以下代码所示: 12train_set_x = train_set_x_flatten/255.test_set_x = test_set_x_flatten/255. 3. 学习算法的一般体系架构有了如上的数据预处理流程,是时候构建一个具有神经网络思维的算法了,其算法实现过程基本如下图所示: 对于一个样本 $x^{(i)}$:$$z^{(i)} = w^T x^{(i)} + b \tag{1}$$$$\hat{y}^{(i)} = a^{(i)} = sigmoid(z^{(i)})\tag{2}$$$$ \mathcal{L}(a^{(i)}, y^{(i)}) = - y^{(i)} \log(a^{(i)}) - (1-y^{(i)} ) \log(1-a^{(i)})\tag{3}$$ 所有样本的损失可以由以下公式计算:$$ J = \frac{1}{m} \sum_{i=1}^m \mathcal{L}(a^{(i)}, y^{(i)})\tag{6}$$ 实现这个算法的关键步骤是: 初始化模型的学习参数 通过最小化损失函数得到模型的学习参数 根据模型的学习参数做出相关预测 分析预测结果并得出相关结论 4. 算法的构建过程构建分类算法的主要步骤可以如下步骤所示: 构建模型架构,例如特征的个数 初始化模型参数 循环: 计算当前损失 利用反向传播算法计算当前的梯度 通过梯度下降更新参数 4.1 sigmoid函数逻辑回归中的激活函数是sigmoid函数,其实现方式可以由以下代码所示: 123def sigmoid(z): s = 1 / (1 + np.exp(-z)) return s 4.2 初始化参数初始化权重参数$w$并使其为0,参数$b = 0$,具体实现代码如下所示: 12345678def initialize_with_zeros(dim): w = np.zeros((dim, 1)) b = 0 #确保参数w的维数和数据类型正确 assert(w.shape == (dim, 1)) assert(isinstance(b, float) or isinstance(b, int)) return w, b 4.3 前向和反向传播算法初始化参数之后,通过传播算法计算学习参数了,关于参数的计算其公式如下是所示:前向传播算法:通过输入变量$X$计算: $A = \sigma(w^T X + b) = (a^{(0)}, a^{(1)}, …, a^{(m-1)}, a^{(m)})\tag{7}$计算损失函数: $J = -\frac{1}{m}\sum_{i=1}^{m}y^{(i)}\log(a^{(i)})+(1-y^{(i)})\log(1-a^{(i)})\tag{8}$可以通过以下两个公式计算相关参数:$$ \frac{\partial J}{\partial w} = \frac{1}{m}X(A-Y)^T\tag{9}$$$$ \frac{\partial J}{\partial b} = \frac{1}{m} \sum_{i=1}^m (a^{(i)}-y^{(i)})\tag{10}$$ 根据以上公式,算法实现的代码如下所示: 123456789101112def 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) cost = np.squeeze(cost) assert(cost.shape == ()) grads = {"dw": dw, "db": db} return grads, cost 4.4 利用梯度下降优化算法有了前向传播算法对参数的计算,接下来需要做的就是利用反向传播算法中的梯度下降算法更新参数,具体实现代码如下所示: 1234567891011121314151617181920def optimize(w, b, X, Y, num_iterations, learning_rate, print_cost = False): 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) if print_cost and i % 100 == 0: print ("Cost after iteration %i: %f" %(i, cost)) params = {"w": w, "b": b} grads = {"dw": dw, "db": db} return params, grads, costs 有了通过反向传播算法得到的参数$w$和$b$,可以根据公式:$\hat{y} = \delta(w^Tx+b)\tag{11}$做出预测了,具体实现代码如下所示: 123456789101112def predict(w, b, X): m = X.shape[1] Y_prediction = np.zeros((1,m)) w = w.reshape(X.shape[0], 1) 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 5. 将所有函数合并在一起搭建模型通过以上,已经分模块实现了算法的所有部分,现在可以通过构建一个模型函数将所有的函数合并在一起,用以实现模型的参数更新和预测,具体实现代码如下所示: 1234567891011121314151617def model(X_train, Y_train, X_test, Y_test, num_iterations = 2000, learning_rate = 0.5, print_cost = False): 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) 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 可以简单绘制模型训练过程中损失函数和梯度的变化曲线,如下所示: 123456costs = 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() 如上图所示,可以看到,随着迭代次数的增加,模型的损失正在下降,当跌打次数增加,将会看到训练集的损失逐渐上升,而测试集的损失逐渐下降。 6.进一步的分析学习率的大小对于模型的训练也是至关重要的,当学习率的大小决定着参数更新的速度,当学习率过大时,模型不容易收敛,而当学习率过小时,模型的需要迭代很多次才能收敛,可以用以下代码验证学习率对模型训练的影响。 12345678910111213141516learning_rates = [0.01, 0.001, 0.0001]models = {}for i in learning_rates: print ("learning rate is: " + str(i)) models[str(i)] = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations = 1500, learning_rate = i, print_cost = False) print ('\n' + "-------------------------------------------------------" + '\n')for i in learning_rates: plt.plot(np.squeeze(models[str(i)]["costs"]), label= str(models[str(i)]["learning_rate"]))plt.ylabel('cost')plt.xlabel('iterations')legend = plt.legend(loc='upper center', shadow=True)frame = legend.get_frame()frame.set_facecolor('0.90') 综上,可以得到如下结论: 不同的学习率会得到不同的预测结果和损失 如果模型的学习率过大,可能会导致模型的损失上下振荡,如上图所示,学习率取0.001可能是一个不错的选择。 过小的损失不一定意味着该模型是一个好模型,能做出很好的预测,很可能是过拟合原因造成的。这种过拟合情况通常发生在训练集的精确度比测试集高很多的情况下。 对于深度学习,通常有如下建议: 为模型选择一个合适的学习率以得到更好的模型参数 如果模型过拟合,通常要采取其他措施消除这种过拟合,一种行之有效的方法是正则化方法。]]></content>
<categories>
<category>深度学习</category>
</categories>
<tags>
<tag>神经网络</tag>
<tag>逻辑回归</tag>
</tags>
</entry>
<entry>
<title><![CDATA[神经网络基础]]></title>
<url>%2F%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%2F%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E5%9F%BA%E7%A1%80%2F</url>
<content type="text"><![CDATA[假设有以下一张图片,要判断其输出是否为猫,若是,则可以用$y = 1$表示,否则用$y = 0$表示。 二元分类计算机保存一张图片通常使用3个独立矩阵,分别对应红、绿、蓝三个颜色通道。如果输入像素是64×64,则会有3个64×64的矩阵,即输入是一个3×64×64的高维度数据,而输出是$y=0 \ or\ 1$。 与机器学习之单变量线性回归一样,可以用$(x,y)$表示一个训练样本,其中$x \in R^n$,而$y = {0,1}$,通常用${(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)})……(x^{(m)},y^{(m)}) }$表示整个训练集,其中$m$表示训练样本的大小,以上,由$m$个训练样本可以组成输入矩阵$X$,且$X \in R^{n×m}$,$Y$是一个输出矩阵,且$Y \in R^{1×m}$。 逻辑回归对于以上分类问题,给定输入$x$,我们想知道$y$的输出概率,$\hat{y}$的输出概率代表着该分类问题的结果,$\hat{y}$的值表示是猫的概率可以简单表示为$\hat{y} = p{y=1|x}$,且$0 \le \hat{y} \le 1$。 对于线性回归,有$y = w^Tx+b$,而对于逻辑回归,采用激活函数,即:$ y = \delta(w^Tx+b) $表示,令$z = w^Tx+b$,则: $\delta(z) = \frac{1}{1+e^{-z}}$,其函数图像如下所示: 当$\delta(z) > 0.5$,即也就是$w^Tx+b > 0 $时,认为其输出$\hat{y} = 1$而$\delta(z) < 0.5$,即也就是$w^Tx+b < 0 $时,其输出$\hat{y} = 0$. 逻辑回归损失函数对于逻辑回归问题,给定训练样本:${(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)})……(x^{(m)},y^{(m)}) }$,我们希望得到$\hat{y} \approx y$。逻辑回归的损失函数$L(\hat{y},y)$可以由以下公式定义: $L(\hat{y},y) = -ylog(\hat{y}) -(1-y)log(1-\hat{y})$ 对于以上损失函数,有:若$y = 1$,则$L(y,\hat{y}) = -ylog(\hat{y})$,而想让损失函数$L(y,\hat{y})$尽可能小,意味着$\hat{y}$要尽可能大,又因为$0 \le\hat{y} \le 1$,所以$\hat{y} = 1$是,损失函数最小。 若$y = 0$,则$L(y,\hat{y}) = -log(1-\hat{y})$,损失函数要取得最小值,意味着$\hat{y}$需取得最大值,则需满足$\hat{y} = 0$。 以上损失函数只适用于单个样本,对于$m$个样本的损失函数可以有如下定义: $J(w,b) = \frac{1}{m}\sum_{i=1}^{m}L(y,\hat{y}) = \frac{1}{m}\sum_{i=1}^{m}-y^{(i)}log(\hat{y}^{(i)})-(1-y^{(i)})log(1-\hat{y}^{(i)})$ 梯度下降法对于以上损失函数,需要找到损失函数$J(w,b)$的最小值,最常用的算法就是梯度下降算法,即对于一个凸函数,总能通过梯度下降算法找到它的全局最优解,对于此损失函数的梯度下降算法,在机器学习之逻辑回归的算法介绍中已经做了较为详细的推导,在此不再过多叙述,梯度下降算法的简单实现步骤如下所示:$repeat \ \ {$$w: = w- \alpha \frac{\partial J(w,b)}{\partial w}$ $}$重复以上过程,直到损失函数收敛,以求得参数$w$的值,其中,$\alpha$代表学习率。 计算图计算图介绍:假设有一函数表达式为:$J(a,b,c) = 3(a+bc)$,其计算过程可以简单分为三个步骤,如下所示: $u = bc$ $v = a +u $ $J =3*v $对于以上三个步骤,用计算图可以有如下表示 计算图的导数:如上图所示,利用计算图从左向右的流程,一步步可以算出$J$的值,那么,依靠从右向左的反向传播就可以算出$J$对每个变量的导数,如下图所示: 其反向传播过程如图中红色箭头所示,根据导数定义以及链式计算法则,有如下计算: $\frac{\partial J}{\partial v} = 3$ $\frac{\partial J}{\partial u} =\frac{\partial J}{\partial v} \frac{\partial v}{\partial u} = 3×1 = 3$ $\frac{\partial J}{\partial a} =\frac{\partial J}{\partial v} \frac{\partial v}{\partial a} = 3×1 =3$ $\frac{\partial J}{\partial b} =\frac{\partial J}{\partial v} \frac{\partial v}{\partial u} \frac{\partial u}{\partial b} = 3×1×5 =15$ $\frac{\partial J}{\partial c} =\frac{\partial J}{\partial v} \frac{\partial v}{\partial u} \frac{\partial u}{\partial c} = 3×1×4 =12$ 逻辑回归中的梯度下降算法单个样本的逻辑回归梯度下降算法关于逻辑回归的损失函数,有如下公式:$z= w^Tx+b$$\hat{y} = a = \delta(z)$$L(a,y) = -ylog(a)-(1-y)log(1-a)$假设有两个输入特征$x_1,x_2$和两个参数$w_1,w_2$,则用计算图(流程图)表示其计算过程如下所示: 依照其计算图中的反向传播过程和链式法则,其导数计算如下所示: $\frac{\partial L(a,y)}{\partial a} = -\frac{y}{a}+\frac{1-y}{1-a}$ $\frac{\partial L(a,y)}{\partial z} = \frac{\partial L}{\partial a} \frac{\partial a}{\partial z} = a-y$ $\frac{\partial L(a,y)}{\partial w_1} =\frac{\partial L}{\partial a} \frac{\partial a}{\partial z} \frac{\partial z}{\partial w_1} =x_1dz = x_1*(a-y)$ $\frac{\partial L(a,y)}{\partial w_2} =\frac{\partial L}{\partial a} \frac{\partial a}{\partial z} \frac{\partial z}{\partial w_2} = x_2dz = x_2*(a-y)$ $\frac{\partial L(a,y)}{\partial b} =\frac{\partial L}{\partial a} \frac{\partial a}{\partial z} \frac{\partial z}{\partial b} = dz = (a-y)$··· 最后,参数$w_1,w_2,b$的更新规律为:$w_1 := w_1 - \alpha dw_1$$w_2 := w_2 - \alpha dw_2$$b := b - \alpha db$其中,$\alpha$表示学习率。 $m$个样本的逻辑回归$m$个样本的损失函数,如下所示: $J(w,b) = \frac{1}{m}\sum_{i=1}^{m}L(a^{(i)},y^{(i)}) $ $a^{(i)} = \hat{y}^{(i)} = \delta(z^{(i)}) = \delta(w^Tx^{(i)} +b)$ 其梯度计算公式,可以有如下表示:$\frac{\partial J(w,b)}{\partial w} = \frac{1}{m}\sum_{i=1}^{m}\frac{\partial }{\partial w}L(a^{(i)},y^{(i)}) $ 在实际计算过程中,需要计算每一个样本的关于$w$的梯度,最后求和取平均,在一个具体算法实现中,其为代码可以如下所示: 假设有2个特征向量,$m$个样本,则有:初始化:$J = 0, dw_1 = 0,dw_2 = 0$$for i =1 to \ \ m:$ $ \ \ \ \ \ \ z^{(i)} = w^Tx^{(i)} +b;$ $ \ \ \ \ \ \ a^{(i)} =\delta(z^{(i)});$ $ \ \ \ \ \ \ J+ = -y^{(i)}log(a^{(i)})-(1-y^{(i)})log(1-a^{(i)});$ $ \ \ \ \ \ \ dz^{(i)} =a^{(i)} - y^{(i)};$ $ \ \ \ \ \ \ dw_1 +=x_1*dz^{(i)};$ $ \ \ \ \ \ \ dw_2 +=x_2*dz^{(i)};$ $ \ \ \ \ \ \ db \ +=dz^{(i)};$ $J/=m,dw_1/=m,dw_2/=m,db/=m;$ 以上,是应用一次梯度下降的过程,应用多次梯度下降算法之后,其参数的更新如下所示:$w_1 := w_1 - \alpha dw_1$$w_2 := w_2 - \alpha dw_2$$b := b - \alpha db$ 注意:以上,算法实现过程中,有两个特征和参数,分别是$x_1,x_2$和$w_1,w_2$,当有$n$个特征和参数时,可以利用循环完成。 向量化向量化的简单示例:如以上算法表示,通过for循环来遍历$m$个样本和$n$个特征,当在整个算法运行过程中,需要考虑运行时间的问题,当样本数量和特征足够大时,采用传统的for循环不是一个明智的选择,为了减少算法运行时间,特地引入了向量化的实现。将一以下代码作为示例: 12345678910111213141516171819import numpy as npimport randomimport timea = np.random.rand(1000000)b = np.random.rand(1000000)ts = time.time()c = np.dot(a,b)te = time.time()print(c)print("向量化的代码实现花费时间:"+str((te-ts)*1000)+" ms")c = 0ts = time.time()for i in range(1000000): c += a[i]*b[i]te = time.time()print(c)print("for循环代码实现花费时间:"+str((te-ts)*1000)+" ms") 如上所示,同样实现两个数组(向量)相乘的过程,对于百万级别的数据,for循环的实现方式所花费的时间差不多是向量化的400倍左右,向量化的实现可以简单的理解为是一个并行的过程,而for循环可以简单理解为串行的过程,所以通过向量化的实现,大大节省了运行程序所耗费的时间。在算法实现过程中,应该尽量避免使用for循环。 用向量化实现逻辑回归:对于逻辑回归的算法,需要考虑输入向量$X$和权重参数$W$,其中,$X \in R^{n×m}$,$W \in R^{n×1}$,而根据矩阵乘法运算法则和逻辑回归的实现原理,有:$[z_1,z_2,……z_m] = [W^TX]+[b_1,b_2,……b_m]$ 在python中用numpy库,可以简单的用以下一行代码实现(一般认为$b$是一个R^{1×1}的偏置常量): 1z = np.dot(W.T,x)+b 根据之前的学习,对于逻辑回归利用反向传播算法计算导数,有: $ \ \ \ \ \ \ dz^{(i)} =a^{(i)} - y^{(i)};$$ \ \ \ \ \ \ dw_1 +=x_1dz^{(i)};$$ \ \ \ \ \ \ dw_2 +=x_2dz^{(i)};$$\ \ \ \ \ \ \ …$$ \ \ \ \ \ \ dw_n +=x_n*dz^{(i)};$$ \ \ \ \ \ \ db \ +=dz^{(i)};$$J/=m,dw_1/=m,dw_2/=m,db/=m;$ 对于以上,公式,有如下定义:$dZ = [dz^{(1)},dz^{(2)}……dz^{(m)}]$$A = [a^{(1)},a^{(2)},……a^{(m)}]$$Y = [y^{(1)},y^{(2)}……y^{(m)}]$$dZ = [A - Y]$对于以上过程,摈弃传统的for循环实现,采用向量化的实现方式可以简单表示为: 12dw = np.dot(X,dZ^T)db = 1/m*np.sum(dZ) 综合以上所有向量化的实现,可以得到利用python实现的一个高度向量化的逻辑回归梯度下降算法(a代表学习率): 1234567Z = np.dot(W^T,X)+bA = np.exp(Z)dZ = A-Ydw = np.dot(X,dZ^T)db = 1/m*np.sum(dZ)w = w-a*dwb = b-a*db 以上,只是实现一次梯度下降的伪代码,在实际算法运行过程中,我们仍然需要利用循环实现多次梯度下降。]]></content>
<categories>
<category>深度学习</category>
</categories>
<tags>
<tag>深度学习</tag>
<tag>神经网络</tag>
</tags>
</entry>
<entry>
<title><![CDATA[新的开始]]></title>
<url>%2F%E9%9A%8F%E7%AC%94%2F%E6%96%B0%E7%9A%84%E5%BC%80%E5%A7%8B%2F</url>
<content type="text"><![CDATA[一些说明花了一个国庆的时间,终于将这个博客搭建的差不多了,尽管还有很多不足,但是目前基本够用,也许在使用过程中还会出现很多bug,只能边用边解决了。搭建一个自己的博客是我一直想要做的事,但是之前由于被各种繁杂的事务耽搁,导致一直没有时间动手去做,趁着这个国庆假期终于做好了。整个博客是用hexo+github搭建完成的,倒也没什么难度,就是需要一些耐心,当然,如果有一些前端方面的知识,搭建起来会更加顺利,可定制化也会更高。以后,会慢慢的将自己的简书上的文章迁移过来,以后也会在简书平台和这个博客网站共同记录自己的学习笔记,除此之外,博客平台除了技术也会记录一些自己的生活经历等。在搭建博客的过程中,看到可好多大佬的博客非常漂亮,也受到了好多大佬的所写文章的指点,在此表示非常感谢。为此,附上几个教学链接,有需要搭建此类博客的同学,也可以了解一下。 博客搭建与优化教程 搭建教程1 搭建教程2 搭建教程3]]></content>
<categories>
<category>随笔</category>
</categories>
<tags>
<tag>Start</tag>
</tags>
</entry>
</search>