![64602fdda29e646e2913bf1f09923fd1.gif](https://i-blog.csdnimg.cn/blog_migrate/acb57e56740131a78d88090ea8af6ed5.gif)
![183ee3cb9b96c331ef1cf6fc5186c0ad.png](https://i-blog.csdnimg.cn/blog_migrate/21dd285fcdb0526097db4a08b7ea427d.png)
![52a1af81d116763bd6a315d24738f3a7.png](https://i-blog.csdnimg.cn/blog_migrate/67232fea545aeedd4359f825110d12dc.png)
今天介绍深度学习中存在的一些问题,以及为什么需要对参数进行初始化,最后实现一个房价预测实例。
0 1梯度消失、梯度爆炸深度模型有关数值稳定性的典型问题是梯度消失(vanishing)和爆炸(explosion)。当神经网络的层数较多时,模型的数值稳定性容易变差。
假设有一个层的多层感知机,所有隐藏层的激活函数为恒等映射,即
,且不考虑偏差参数,那么
。当层数较多时,梯度的计算可能出现消失或爆炸。简单的说,假设所有层的权重参数大于1或小于1,如所有层的
,就会使权重之积出现非常大或非常小的情况,即爆炸或消失,如
。
假设隐藏层使用相同的激活函数,且将每个隐藏单元的参数都初始化为相等的值,那么在正向传播时每个隐藏单元将根据相同的输入计算出相同的值,并传递至输出层。在反向传播中,每个隐藏单元的参数梯度值相等。因此,这些参数在使用基于梯度的优化算法迭代后值依然相等。之后的迭代也是如此。在这种情况下,无论隐藏单元有多少,隐藏层本质上只有1个隐藏单元在发挥作用。因此通常将神经网络的模型参数,特别是权重参数,进行随机初始化。
0 3房价预测实例数据读取及预处理:
使用的是房价数据。两个数据集都包括每栋房子的特征,如街道类型、建造年份、房顶类型、地下室状况等特征值。这些特征值有连续的数字、离散的标签甚至是缺失值“na”。只有训练数据集包括了每栋房子的价格,也就是标签。
去下载数据
# 标准化def standardNormal(all_features): numeric_features = all_features.dtypes[all_features.dtypes != 'object'].index all_features[numeric_features] = all_features[numeric_features].apply( lambda x: (x - x.mean()) / (x.std())) # 标准化后,每个数值特征的均值变为0,所以可以直接用0来替换缺失值 all_features[numeric_features] = all_features[numeric_features].fillna(0) # 将离散数值转成指示特征 # dummy_na=True将缺失值也当作合法的特征值并为其创建指示特征 all_features = pd.get_dummies(all_features, dummy_na=True) return all_featuresdef loadData(): test_data = pd.read_csv("../data/houseprice/test.csv") train_data = pd.read_csv("../data/houseprice/train.csv") all_features = pd.concat((train_data.iloc[:, 1:-1], test_data.iloc[:, 1:])) all_features = standardNormal(all_features) # 划分训练集和测试集 n_train = train_data.shape[0] train_features = torch.tensor(all_features[:n_train].values, dtype=torch.float) test_features = torch.tensor(all_features[n_train:].values, dtype=torch.float) train_labels = torch.tensor(train_data.SalePrice.values, dtype=torch.float).view(-1, 1) return train_features, train_labels, test_features
模型评价:
def log_rmse(net, features, labels): loss = get_loss() with torch.no_grad(): # 将小于1的值设成1,使得取对数时数值更稳定 clipped_preds = torch.max(net(features), torch.tensor(1.0)) rmse = torch.sqrt(2 * loss(clipped_preds.log(), labels.log()).mean()) return rmse.item()
K折交叉验证:
def get_k_fold_data(k, i, X, y): # 返回第i折交叉验证时所需要的训练和验证数据 assert k > 1 fold_size = X.shape[0] // k X_train, y_train = None, None for j in range(k): idx = slice(j * fold_size, (j + 1) * fold_size) X_part, y_part = X[idx, :], y[idx] if j == i: X_valid, y_valid = X_part, y_part elif X_train is None: X_train, y_train = X_part, y_part else: X_train = torch.cat((X_train, X_part), dim=0) y_train = torch.cat((y_train, y_part), dim=0) return X_train, y_train, X_valid, y_valid
0
4训练及结果
import torchimport torch.nn as nnimport numpy as npimport pandas as pdimport sysdef k_fold(k, X_train, y_train, num_epochs, learning_rate, weight_decay, batch_size): train_l_sum, valid_l_sum = 0, 0 for i in range(k): data = get_k_fold_data(k, i, X_train, y_train) net = get_net(X_train.shape[1]) loss = get_loss() train_ls, valid_ls = train(net, *data, loss, num_epochs, learning_rate, weight_decay, batch_size) train_l_sum += train_ls[-1] valid_l_sum += valid_ls[-1] if i == 0: util.show_loss(range(1, num_epochs + 1), train_ls, 'epochs', 'rmse', range(1, num_epochs + 1), valid_ls,['train', 'valid']) print('fold %d, train rmse %f, valid rmse %f' % (i, train_ls[-1], valid_ls[-1])) return train_l_sum / k, valid_l_sum / kdef main(): k, num_epochs, lr, weight_decay, batch_size = 5, 100, 5, 0, 64 train_features, train_labels, test_features = loadData() train_l, valid_l = k_fold(k, train_features, train_labels, num_epochs, lr, weight_decay, batch_size)if __name__ == '__main__': main()
fold 0, train rmse 0.240870, valid rmse 0.222502fold 1, train rmse 0.229827, valid rmse 0.272058fold 2, train rmse 0.232241, valid rmse 0.238182fold 3, train rmse 0.237940, valid rmse 0.218737fold 4, train rmse 0.231035, valid rmse 0.259251
可以使用K折交叉验证来选择超参数。一组参数的训练误差可以达到很低,但是在K折交叉验证上的误差可能反而较高。这种现象很可能是由过拟合造成的。因此,当训练误差降低时,我们要观察K折交叉验证上的误差是否也相应降低。
如需源码,请后台回复 "房价预测"。有什么问题,可添加微信 "wxid-3ccc".
双向Dijkstra算法
EndNote引文编排
利用GN算法进行社区发现
Python爬取高德地图--瓦片图
高斯混合模型判定交通拥堵状态
分享数据---GIMMS NDVI 3gv1(1982-2015)
机器人局部规划算法--DWA算法原理
ArcGIS时间滑块实现车辆轨迹动态展示
多时间序列数据MK突变检验突变点提取
整数规划求解最短路径问题
世界各国GDP排名变化--Python动图实现
![e547f457943a286c860db925f9cd92d2.png](https://i-blog.csdnimg.cn/blog_migrate/4d99af1221353d46d936e090f9214577.png)
![3579bef33306ccda80142852175b6a41.png](https://i-blog.csdnimg.cn/blog_migrate/c1a5a8f575d23135ed10865834d142a7.jpeg)
![28916186e93436b0c2408714ce876cc8.png](https://i-blog.csdnimg.cn/blog_migrate/635b35f9e53bc35fe61a661fc567a9ee.png)