扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
1.基本概念
我们提供的服务有:成都网站制作、成都网站建设、微信公众号开发、网站优化、网站认证、新密ssl等。为1000+企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的新密网站制作公司
多项式回归(Polynomial Regression)是研究一个因变量与一个或多个自变量间多项式的回归分析方法。如果自变量只有一个 时,称为一元多项式回归;如果自变量有多个时,称为多元多项式回归。

1.在一元回归分析中,如果依变量y与自变量x的关系为非线性的,但是又找不到适当的函数曲线来拟合,则可以采用一元多项式回归。
2.多项式回归的最大优点就是可以通过增加x的高次项对实测点进行逼近,直至满意为止。
3.事实上,多项式回归可以处理相当一类非线性问题,它在回归分析 中占有重要的地位,因为任一函数都可以分段用多项式来逼近。

2.实例
我们在前面已经根据已知的房屋成交价和房屋的尺寸进行了线 性回归,继而可以对已知房屋尺寸,而未知房屋成交价格的实例进行了成 交价格的预测,但是在实际的应用中这样的拟合往往不够好,因此我们在 此对该数据集进行多项式回归。
目标:对房屋成交信息建立多项式回归方程,并依据回归方程对房屋价格进行预测

import matplotlib.pyplot as plt
import numpy as np
from sklearn import linear_model
#导入线性模型和多项式特征构造模块
from sklearn.preprocessing import PolynomialFeatures
datasets_X =[]
datasets_Y =[]
fr =open('prices.txt','r')
#一次读取整个文件。
lines =fr.readlines()
#逐行进行操作,循环遍历所有数据
for line in lines:
#去除数据文件中的逗号
items =line.strip().split(',')
#将读取的数据转换为int型,并分别写入datasets_X和datasets_Y。
datasets_X.append(int(items[0]))
datasets_Y.append(int(items[1]))
#求得datasets_X的长度,即为数据的总数。
length =len(datasets_X)
#将datasets_X转化为数组, 并变为二维,以符合线性回 归拟合函数输入参数要求
datasets_X= np.array(datasets_X).reshape([length,1])
#将datasets_Y转化为数组
datasets_Y=np.array(datasets_Y)
minX =min(datasets_X)
maxX =max(datasets_X)
#以数据datasets_X的最大值和最小值为范围,建立等差数列,方便后续画图。
X=np.arange(minX,maxX).reshape([-1,1])
#degree=2表示建立datasets_X的二 次多项式特征X_poly。
poly_reg =PolynomialFeatures(degree=2)
X_ploy =poly_reg.fit_transform(datasets_X)
lin_reg_2=linear_model.LinearRegression()
lin_reg_2.fit(X_ploy,datasets_Y)
#查看回归方程系数
print('Cofficients:',lin_reg_2.coef_)
#查看回归方程截距
print('intercept',lin_reg_2.intercept_)
plt.scatter(datasets_X,datasets_Y,color='red')
plt.plot(X,lin_reg_2.predict(poly_reg.fit_transform(X)),color='blue')
plt.xlabel('Area')
plt.ylabel('Price')
plt.show()
运行结果:
Cofficients: [0.00000000e+00 4.93982848e-02 1.89186822e-05]
intercept 151.8469675050044
通过多项式回归拟合的曲线与 数据点的关系如下图所示。依据该 多项式回归方程即可通过房屋的尺 寸,来预测房屋的成交价格。

文章知识点与官方知识档案匹配
Python入门技能树人工智能基于Python的监督学习
194396 人正在系统学习中
打开CSDN,阅读体验更佳
基于Python的多项式拟合方法_飘羽的博客_python 多项式...
基于Python的多项式拟合方法 1. 直接上代码进行介绍 __author__ ='Administrator' # coding=utf8 # 导入相关包 importmatplotlib.pyplotasplt importnumpyasnp frompandasimportread_csv fromsklearn.metricsimportr2_score...
继续访问
python机器学习 | 多项式回归和拟合_Claire_chen_jia的博客...
多项式回归中,加入了特征的更高次方(例如平方项或立方项),也相当于增加了模型的自由度,用来捕获数据中非线性的变化。 多项式拟合lm_sklearn之多项式回归 weixin_34419561的博客 601 '''多项式回归:若希望回归模型更好的拟合训练样本...
继续访问
最新发布 Python回归预测建模实战-多项式回归预测房价(附源码和实现效果)
Python回归预测建模实战-多项式回归预测房价(附源码和实现效果)
继续访问

sklearn实现非线性回归模型
sklearn实现非线性回归模型 前言: sklearn实现非线性回归模型的本质是通过线性模型实现非线性模型,如何实现呢?sklearn就是先将非线性模型转换为线性模型,再利用线性模型的算法进行训练模型。 一、线性模型解决非线性模型的思想 1、样本数据如下 x y 1 45000 2 50000 3 60000 4 80000 5 110000 6 15000...
继续访问

多项式拟合,模型的复杂度以及权重的变化_今晚打佬虎的博客...
sklearn,提供了多项式特征的方法: fromsklearn.preprocessingimportPolynomialFeatures X=np.arange(6).reshape(3,2)poly=PolynomialFeatures(2)poly.fit_transform(X)array([[1.,0.,1.,0.,0.,1.],[1.,2.,3.,4.,6.,9...
继续访问
python数据处理三:使用sklearn实现曲线拟合_耐心的小黑的博客-CSDN博 ...
from sklearn.linear_model import LinearRegressionfrom sklearn.preprocessing import PolynomialFeaturesimport numpy as npimport matplotlib.pyplot as plt#获取待拟合数据x = np.linspace(1, 50, 50)f = np.poly1d([2,5,10])y ...
继续访问
机器学习(十)线性多项式回归之房价与房屋尺寸关系
一.线性回归 (1)线性回归 线性回归(Linear Regression)是利用数理统计中回归分析,来确定两种或两种以上变量间相互依赖的定量关系的一种统计分 析方法。 线性回归利用称为线性回归方程的最小平方函数对一个或多个自变量和因变量之间关系进行建模。这种函数是一个或多个称为回归系数的模型参数的线性组合。只有一个自变量的情况称为简单回归,大于一个自变量情况的叫做多元回归 线性回归:使用形如y=w T x+b的线性模型拟合数据输入和输出之间的映射关系的。 线性回归有很多实际的用途,分为以下两类: 1.如果目标是预测或者映射,线性回归可以用来对观测数据集的y和X的值拟合出一个预测模型。
python完成非线性拟合
在之前的博客"使用python来完成数据的线性拟合"当中,介绍了基于python,使用三种方法完成线性拟合的理论和代码实现。同样经常会碰到样本分布呈现非线性关系的情况,那么如何拟合出来呢?本文侧重对数据已经有建模,但是准确的关系需要得以确定的情况。 如果想直接求出拟合系数,而不清楚原本模型的话,直接利用theta = np.polyfit(X, Y_noise, deg=4)得到y=a*x^4+b*x^3+c*x^2+d方程的theta=[a,b,c,d]。这里deg=4表...
继续访问

sklearn实现多项式回归_盛夏未来的博客
sklearn实现多项式回归 多项式回归 一个数据集,用散点图画出来如下图,可以看到此时用一条直线(或者超平面)是不能拟合的,所以需要用一个多项式表示的曲线(或者超曲面)才能得到更好的拟合结果。
继续访问
多项式回归+房价与房屋尺寸的非线性拟合
多项式回归 多项式回归(Polynomial Regression)是研究一个因变量与一个或多个自变量间多项式的回归分析方法。如果自变量只有一个时,称为一元多项式回归;如果自变量有多个时,称为多元多项式回归。 在一元回归分析中,如果依变量y与自变量X的关系为非线性的,但是又找不到适当的函数曲线来拟合,则可以采用一元多项式回归。后续的实例就是这个例子。 多项式回归的最大优点就是可以通过增加X的高次...
继续访问
Python机器学习应用 | 多项式回归
1 多项式回归多项式回归(Polynomial Regression)是研究一个因变量与一个或多个自变量间多项式的回归分析方法。如果自变量只有一个时,称为一元多项式回归;如果自变量有多个时,称为多元多项式回归。 在一元回归分析中,如果依变量y与自变量x的关系为非线性的,但是又找不到适当的函数曲线来拟合,则可以采用一元多项式回归。 多项式回归的最大优点就是可以通过增加x的高次项对实测点进行逼近,直
继续访问
多项式拟合lm_sklearn之多项式回归
'''多项式回归:若希望回归模型更好的拟合训练样本数据,可以使用多项式回归器。一元多项式回归:数学模型:y = w0 + w1 * x^1 + w2 * x^2 + .... + wn * x^n将高次项看做对一次项特征的扩展得到:y = w0 + w1 * x1 + w2 * x2 + .... + wn * xn那么一元多项式回归即可以看做为多元线性回归,可以使用LinearRegressio...
继续访问
sklearn多项式拟合
继续访问
【Scikit-Learn】多项式拟合
%matplotlib inline import matplotlib.pyplot as plt import numpy as np n_dots = 20 x = np.linspace(0, 1, n_dots) # [0, 1] 之间创建 20 个点 y = np.sqrt(x) + 0.2*np.random.rand(n_dots) - 0....
继续访问
python 非线性多项式拟合_浅析多项式回归与sklearn中的Pipeline
0x00 前言 之前我们介绍了简单线性回归,其输入特征只有一维,即:;推广到多维特征,即多元线性回归:。但是在线性回归的背后是有一个很强的假设条件:数据存在线性关系。但是更多的数据之间具有非线性关系。因此对线性回归法进行改进,使用多项式回归法,可以对非线性数据进行处理。0x01 什么是多项式回归 研究一个因变量与一个或多个自变量间多项式的回归分析方法,称为多项式回归(Polynomial...
继续访问

机器学习-sklearn-多项式回归-对函数拟合-看学习曲线(均方误差MSE)-pipeline
python sklearn pipeline做函数拟合,-看学习曲线(均方误差MSE)
继续访问

sklearn实现多项式回归
1)生成数据集 import numpy as np import matplotlib.pyplot as plt n_train, n_test, true_w, true_b = 100, 100, [1.2, -3.4, 5.6], 5 # X = np.linspace(-3,3,n_train+n_test) X = np.random.normal(size=(n_train...
继续访问
多项式回归
线性回归只能拟合简单的 线性问题,当现在数据的复杂程度不能使用线性拟合,这时要考虑非线性拟合。现在考虑一种最简单的非线性拟合--多项式回归。 多项式回归的含义是直接从线性回归过度到非线性,简单的做法可以将原来的特征的幂次方作为一个新的特征,这样随着特征的逐渐复杂,它也能够解决非线性数据的拟合问题,这种从线性特征集上扩展过来的模型,称为多项式回归。 首先创建非线性带噪声的数据集 import...
继续访问

sklearn多项式回归
# -*- coding: utf-8 -*- """ Created on Mon Jan 29 22:57:10 2018 @author: Administrator """ import matplotlib.pyplot as plt import numpy as np from sklearn.linear_model import LinearRegression#导入线性回归
继续访问
【机器学习】多项式回归python实现
使用python实现多项式回归,没有使用sklearn等机器学习框架,目的是帮助理解算法的原理。 使用一个简单的数据集来模拟,只有几条数据。 代码 从数据集中读取X和y。 为X添加二次方项,用Z替换。 给Z添加 1 列,初始化为 1 ,用来求偏置项。 划分训练集和测试集。 将Z和y的训练集转换为矩阵形式。 和线性回归类似,使用正规方程法,先验证矩阵的可逆性。 去掉Z中全为1的列。 使用测试集...
继续访问

sklearn线性回归完成多次项函数和正弦函数拟合
这样两个式子,使用sklearn 线性回归进行拟合 直接上代码 得到结果:score : 0.9902512046606555 mse : 7940.310765934783画图结果:对于正玄曲线原始数据画图 degree定成三阶拟合图 degree定成二阶拟合图degree定成六阶拟合图,效果非常好,但不知道是不是有点过拟合了、? 话不多说,直接上代码:...
继续访问

热门推荐 python运用sklearn进行数据拟合和回归
在上一篇讲了最小二乘法实现线性回归的原理,实现方面用的是python的static.optimize中的leastsq求出拟合函数。本篇通过sklearn库中的模块来进行拟合和线性回归,并计算拟合误差。 对于线性回归来说,无论是用什么工具实现,步骤都是大同小异的: 初始化多项式方程 对多项式方程进行多次迭代,通过最小二乘法求出使平方损失函数最小情况下的拟合方程。 对模型预测结果进行评估 调整参数...
继续访问

sklearn-多项式回归
import numpy as np import matplotlib.pyplot as plt from sklearn.preprocessing import PolynomialFeatures from sklearn.linear_model import LinearRegression #载入数据 data = np.genfromtxt("job.csv",delim...
继续访问
[机器学习与scikit-learn-31]:算法-回归-线性模拟拟合拟合非线性数据-概述
作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客 本文网址: 目录 第1章 什么是线性与非线性关系 1.1 描述对象 1.2 什么是线性与非线性关系 第2章 数据(分布)的线性与非线性 2.1 什么是线性与非线性数据(拟合、模拟回归) 2.2什么是线性与非线性可分数据(分类、逻辑回归) 2.3 分类问题的拟合表达 第3章 模型的线性与非线性 3.1 线性模型 3.2 特定的非线性模型 3.3 通用的非线性模型:多项式非线性模型(Polyn.
继续访问
可以
最近项目中涉及基于Gradient Boosting Regression 算法拟合时间序列曲线的内容,利用python机器学习包 scikit-learn 中的GradientBoostingRegressor完成
因此就学习了下Gradient Boosting算法,在这里分享下我的理解
Boosting 算法简介
Boosting算法,我理解的就是两个思想:
1)“三个臭皮匠顶个诸葛亮”,一堆弱分类器的组合就可以成为一个强分类器;
2)“知错能改,善莫大焉”,不断地在错误中学习,迭代来降低犯错概率
当然,要理解好Boosting的思想,首先还是从弱学习算法和强学习算法来引入:
1)强学习算法:存在一个多项式时间的学习算法以识别一组概念,且识别的正确率很高;
2)弱学习算法:识别一组概念的正确率仅比随机猜测略好;
Kearns Valiant证明了弱学习算法与强学习算法的等价问题,如果两者等价,只需找到一个比随机猜测略好的学习算法,就可以将其提升为强学习算法。
那么是怎么实现“知错就改”的呢?
Boosting算法,通过一系列的迭代来优化分类结果,每迭代一次引入一个弱分类器,来克服现在已经存在的弱分类器组合的shortcomings
在Adaboost算法中,这个shortcomings的表征就是权值高的样本点
而在Gradient Boosting算法中,这个shortcomings的表征就是梯度
无论是Adaboost还是Gradient Boosting,都是通过这个shortcomings来告诉学习器怎么去提升模型,也就是“Boosting”这个名字的由来吧
Adaboost算法
Adaboost是由Freund 和 Schapire在1997年提出的,在整个训练集上维护一个分布权值向量W,用赋予权重的训练集通过弱分类算法产生分类假设(基学习器)y(x),然后计算错误率,用得到的错误率去更新分布权值向量w,对错误分类的样本分配更大的权值,正确分类的样本赋予更小的权值。每次更新后用相同的弱分类算法产生新的分类假设,这些分类假设的序列构成多分类器。对这些多分类器用加权的方法进行联合,最后得到决策结果。
其结构如下图所示:
前一个学习器改变权重w,然后再经过下一个学习器,最终所有的学习器共同组成最后的学习器。
如果一个样本在前一个学习器中被误分,那么它所对应的权重会被加重,相应地,被正确分类的样本的权重会降低。
这里主要涉及到两个权重的计算问题:
1)样本的权值
1 没有先验知识的情况下,初始的分布应为等概分布,样本数目为n,权值为1/n
2 每一次的迭代更新权值,提高分错样本的权重
2)弱学习器的权值
1 最后的强学习器是通过多个基学习器通过权值组合得到的。
2 通过权值体现不同基学习器的影响,正确率高的基学习器权重高。实际上是分类误差的一个函数
Gradient Boosting
和Adaboost不同,Gradient Boosting 在迭代的时候选择梯度下降的方向来保证最后的结果最好。
损失函数用来描述模型的“靠谱”程度,假设模型没有过拟合,损失函数越大,模型的错误率越高
如果我们的模型能够让损失函数持续的下降,则说明我们的模型在不停的改进,而最好的方式就是让损失函数在其梯度方向上下降。
下面这个流程图是Gradient Boosting的经典图了,数学推导并不复杂,只要理解了Boosting的思想,不难看懂
这里是直接对模型的函数进行更新,利用了参数可加性推广到函数空间。
训练F0-Fm一共m个基学习器,沿着梯度下降的方向不断更新ρm和am
GradientBoostingRegressor实现
python中的scikit-learn包提供了很方便的GradientBoostingRegressor和GBDT的函数接口,可以很方便的调用函数就可以完成模型的训练和预测
GradientBoostingRegressor函数的参数如下:
class sklearn.ensemble.GradientBoostingRegressor(loss='ls', learning_rate=0.1, n_estimators=100, subsample=1.0, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_depth=3, init=None, random_state=None, max_features=None, alpha=0.9, verbose=0, max_leaf_nodes=None, warm_start=False, presort='auto')[source]¶
loss: 选择损失函数,默认值为ls(least squres)
learning_rate: 学习率,模型是0.1
n_estimators: 弱学习器的数目,默认值100
max_depth: 每一个学习器的最大深度,限制回归树的节点数目,默认为3
min_samples_split: 可以划分为内部节点的最小样本数,默认为2
min_samples_leaf: 叶节点所需的最小样本数,默认为1
……
可以参考
官方文档里带了一个很好的例子,以500个弱学习器,最小平方误差的梯度提升模型,做波士顿房价预测,代码和结果如下:
1 import numpy as np 2 import matplotlib.pyplot as plt 3 4 from sklearn import ensemble 5 from sklearn import datasets 6 from sklearn.utils import shuffle 7 from sklearn.metrics import mean_squared_error 8 9 ###############################################################################10 # Load data11 boston = datasets.load_boston()12 X, y = shuffle(boston.data, boston.target, random_state=13)13 X = X.astype(np.float32)14 offset = int(X.shape[0] * 0.9)15 X_train, y_train = X[:offset], y[:offset]16 X_test, y_test = X[offset:], y[offset:]17 18 ###############################################################################19 # Fit regression model20 params = {'n_estimators': 500, 'max_depth': 4, 'min_samples_split': 1,21 'learning_rate': 0.01, 'loss': 'ls'}22 clf = ensemble.GradientBoostingRegressor(**params)23 24 clf.fit(X_train, y_train)25 mse = mean_squared_error(y_test, clf.predict(X_test))26 print("MSE: %.4f" % mse)27 28 ###############################################################################29 # Plot training deviance30 31 # compute test set deviance32 test_score = np.zeros((params['n_estimators'],), dtype=np.float64)33 34 for i, y_pred in enumerate(clf.staged_predict(X_test)):35 test_score[i] = clf.loss_(y_test, y_pred)36 37 plt.figure(figsize=(12, 6))38 plt.subplot(1, 2, 1)39 plt.title('Deviance')40 plt.plot(np.arange(params['n_estimators']) + 1, clf.train_score_, 'b-',41 label='Training Set Deviance')42 plt.plot(np.arange(params['n_estimators']) + 1, test_score, 'r-',43 label='Test Set Deviance')44 plt.legend(loc='upper right')45 plt.xlabel('Boosting Iterations')46 plt.ylabel('Deviance')47 48 ###############################################################################49 # Plot feature importance50 feature_importance = clf.feature_importances_51 # make importances relative to max importance52 feature_importance = 100.0 * (feature_importance / feature_importance.max())53 sorted_idx = np.argsort(feature_importance)54 pos = np.arange(sorted_idx.shape[0]) + .555 plt.subplot(1, 2, 2)56 plt.barh(pos, feature_importance[sorted_idx], align='center')57 plt.yticks(pos, boston.feature_names[sorted_idx])58 plt.xlabel('Relative Importance')59 plt.title('Variable Importance')60 plt.show()
可以发现,如果要用Gradient Boosting 算法的话,在sklearn包里调用还是非常方便的,几行代码即可完成,大部分的工作应该是在特征提取上。
感觉目前做数据挖掘的工作,特征设计是最重要的,据说现在kaggle竞赛基本是GBDT的天下,优劣其实还是特征上,感觉做项目也是,不断的在研究数据中培养对数据的敏感度。
第三行是判断mse是不是小于1e-10(表示1*10^-10),如果是的话,函数直接返回100
随机森林(Random forest)指的是利用多棵树对样本进行训练并预测的一种分类器。 并且其输出的类别是由个别树输出的类别的众数而定。在机器学习中有一个地位很重要的包scikit-learn可实现随机森林算法。
原理:(随机森林的分类预测和回归预测sklearn.ensemble.RandomForestRegressor方法)
(1)给定训练集S,测试集T,特征维数F。确定参数:使用到的CART的数量t,每棵树的深度d,每个节点使用到的特征数量f,终止条件:节点上最少样本数s,节点上最少的信息增益m,对于第1-t棵树,i=1-t:
(2)从S中有放回的抽取大小和S一样的训练集S(i),作为根节点的样本,从根节点开始训练
(3)如果当前节点上达到终止条件,则设置当前节点为叶子节点,如果是分类问题,该叶子节点的预测输出为当前节点样本集合中数量最多的那一类c(j),概率p为c(j)占当前样本集的比例;如果是回归问题,预测输出为当前节点样本集各个样本值的平均值。然后继续训练其他节点。如果当前节点没有达到终止条件,则从F维特征中无放回的随机选取f维特征。利用这f维特征,寻找分类效果最好的一维特征k及其阈值th,当前节点上样本第k维特征小于th的样本被划分到左节点,其余的被划分到右节点。继续训练其他节点。
(4)重复(2)(3)直到所有节点都训练过了或者被标记为叶子节点。
(5)重复(2),(3),(4)直到所有CART都被训练过。
随机森林的简单实现过程如下:
一、 开发环境、编译环境:
PyCharm Community Edition 2016.2.3
Python2.7.10
二、 所用库及安装方法:
pandas[python自带]
sklearn:命令行pip install sklearn;如果没有安装pip,先使用easy_install pip安装pip;如果在MAC上没有权限,使用sudo pip install sklearn;
三、 代码介绍
1. 使用pandas读取本地excel的训练集和测试集,将属性集赋给X_train和Y_train;将要预测的集合赋给X_test和Y_test;
2. 使用DictVectorizer对数据进行规范化、标准化
3. 生成RandomForestRegressor对象,并将训练集传入fit方法中进行训练
4. 调用predict函数进行预测,并将结果存入y_predict变量中;
5. 使用mean_squared_error、score方法输出MSE、NMSE值对拟合度、稳定度进行分析;输出feature_importance,对影响最终结果的属性进行分析;
6. 详细代码见附录
四、 附录
# coding:utf-8
import pandas as pd
data_train = pd.read_excel('/Users/xiaoliu/Desktop/data_train.xlsx')
X_train = data_train[['CPI', 'GDP', 'PPI', 'AJR', 'BJFJ', 'FBDR', 'PCFD', 'PCFDED', 'BDR']]
y_train = data_train['FJ']
data_test = pd.read_excel('/Users/xiaoliu/Desktop/data_test.xlsx')
X_test = data_test[['CPI', 'GDP', 'PPI', 'AJR', 'BJFJ', 'FBDR', 'PCFD', 'PCFDED', 'BDR']]
y_test = data_test['FJ']
from sklearn.feature_extraction import DictVectorizer
vec = DictVectorizer(sparse=False)
X_train = vec.fit_transform(X_train.to_dict(orient='records'))
X_test = vec.transform(X_test.to_dict(orient='records'))
from sklearn.ensemble import RandomForestRegressor
rf = RandomForestRegressor()
rf.fit(X_train,y_train)
y_predict = rf.predict(X_test)
print 'predict value:',y_predict
from sklearn.metrics import mean_squared_error
print 'MSE:', mean_squared_error(y_test, y_predict)
print 'NMES:',rf.score(X_test, y_test)
print rf.feature_importances_
你好:
这是全局变量的用法;
要想在一个函数里面用全局函数:
需要现在外面声明一下;
然后在函数里面使用:global声明
如果把神经网络模型比作一个黑箱,把模型参数比作黑箱上面一个个小旋钮,那么根据通用近似理论(universal approximation theorem),只要黑箱上的旋钮数量足够多,而且每个旋钮都被调节到合适的位置,那这个模型就可以实现近乎任意功能(可以逼近任意的数学模型)。
显然,这些旋钮(参数)不是由人工调节的,所谓的机器学习,就是通过程序来自动调节这些参数。神经网络不仅参数众多(少则十几万,多则上亿),而且网络是由线性层和非线性层交替叠加而成,上层参数的变化会对下层的输出产生非线性的影响,因此,早期的神经网络流派一度无法往多层方向发展,因为他们找不到能用于任意多层网络的、简洁的自动调节参数的方法。
直到上世纪80年代,祖师爷辛顿发明了反向传播算法,用输出误差的均方差(就是loss值)一层一层递进地反馈到各层神经网络,用梯度下降法来调节每层网络的参数。至此,神经网络才得以开始它的深度之旅。
本文用python自己动手实现梯度下降和反向传播算法。 请点击这里 到Github上查看源码。
梯度下降法是一种将输出误差反馈到神经网络并自动调节参数的方法,它通过计算输出误差的loss值( J )对参数 W 的导数,并沿着导数的反方向来调节 W ,经过多次这样的操作,就能将输出误差减小到最小值,即曲线的最低点。
虽然Tensorflow、Pytorch这些框架都实现了自动求导的功能,但为了彻底理解参数调节的过程,还是有必要自己动手实现梯度下降和反向传播算法。我相信你和我一样,已经忘了之前学的微积分知识,因此,到可汗学院复习下 Calculus
和 Multivariable Calculus 是个不错的方法,或是拜读 这篇关于神经网络矩阵微积分的文章 。
Figure2是求导的基本公式,其中最重要的是 Chain Rule ,它通过引入中间变量,将“ y 对 x 求导”的过程转换为“ y 对中间变量 u 求导,再乘以 u 对 x 求导”,这样就将一个复杂的函数链求导简化为多个简单函数求导。
如果你不想涉及这些求导的细节,可以跳过具体的计算,领会其思想就好。
对于神经网络模型: Linear - ReLu - Linear - MSE(Loss function) 来说,反向传播就是根据链式法则对 求导,用输出误差的均方差(MSE)对模型的输出求导,并将导数传回上一层神经网络,用于它们来对 w 、 b 和 x (上上层的输出)求导,再将 x 的导数传回到它的上一层神经网络,由此将输出误差的均方差通过递进的方式反馈到各神经网络层。
对于 求导的第一步是为这个函数链引入中间变量:
接着第二步是对各中间变量求导,最后才是将这些导数乘起来。
首先,反向传播的起点是对loss function求导,即 。 :
mse_grad()之所以用unsqueeze(-1)给导数增加一个维度,是为了让导数的shape和tensor shape保持一致。
linear层的反向传播是对 求导,它也是一个函数链,也要先对中间变量求导再将所有导数相乘:
这些中间变量的导数分别是:
对向量 求导,指的是对向量所有的标量求偏导( ),即: ,这个横向量也称为y的梯度。
这里 ,是一个向量,因此, 求导,指的是y的所有标量(y_1, y_2, ..., y_n)对向量x求偏导,即:
。
这个矩阵称为雅克比矩阵,它是个对角矩阵,因为 ,因此 。
同理, 。
因此,所有中间导数相乘的结果:
lin_grad() 中的inp.g、w.g和b.g分别是求 的导数,以inp.g为例,它等于 ,且需要乘以前面各层的导数,即 outp.g @ w.t() ,之所以要用点积运算符(@)而不是标量相乘,是为了让它的导数shape和tensor shape保持一致。同理,w.g和b.g也是根据相同逻辑来计算的。
ReLu层的求导相对来说就简单多了,当输入 = 0时,导数为0,当输入 0时,导数为1。
求导运算终于结束了,接下来就是验证我们的反向传播是否正确。验证方法是将forward_backward()计算的导数和Pytorch自动微分得到的导数相比较,如果它们相近,就认为我们的反向传播算法是正确的。
首先,将计算好的参数导数保存到w1g、b1g、w2g和b2g中,再用Pytorch的自动微分来求w11、b11、w22和b22的导数。
最后,用np.allclose()来比较导数间的差异,如果有任何一个导数不相近,assert就会报错。结果证明,我们自己动手实现的算法是正确的。
反向传播是遵循链式法则的,它将前向传播的输出作为输入,输入作为输出,通过递进的方式将求导这个动作从后向前传递回各层。神经网络参数的求导需要进行矩阵微积分计算,根据这些导数的反方向来调节参数,就可以让模型的输出误差的优化到最小值。
欢迎关注和点赞,你的鼓励将是我创作的动力
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流