python实现dijkstra_深度学习Pytorch实现房价预测

64602fdda29e646e2913bf1f09923fd1.gif 183ee3cb9b96c331ef1cf6fc5186c0ad.png 52a1af81d116763bd6a315d24738f3a7.png

今天介绍深度学习中存在的一些问题,以及为什么需要对参数进行初始化,最后实现一个房价预测实例。

0 1梯度消失、梯度爆炸

深度模型有关数值稳定性的典型问题是梯度消失(vanishing)和爆炸(explosion)。当神经网络的层数较多时,模型的数值稳定性容易变差。

假设有一个f9848de4-8d2b-eb11-8da9-e4434bdf6706.svg层的多层感知机,所有隐藏层的激活函数为恒等映射,即fb848de4-8d2b-eb11-8da9-e4434bdf6706.svg,且不考虑偏差参数,那么fc848de4-8d2b-eb11-8da9-e4434bdf6706.svg。当层数较多时,梯度的计算可能出现消失或爆炸。简单的说,假设所有层的权重参数大于1或小于1,如所有层的fe848de4-8d2b-eb11-8da9-e4434bdf6706.svg,就会使权重之积出现非常大或非常小的情况,即爆炸或消失,如04858de4-8d2b-eb11-8da9-e4434bdf6706.svg

0 2随机初始化参数

假设隐藏层使用相同的激活函数,且将每个隐藏单元的参数都初始化为相等的值,那么在正向传播时每个隐藏单元将根据相同的输入计算出相同的值,并传递至输出层。在反向传播中,每个隐藏单元的参数梯度值相等。因此,这些参数在使用基于梯度的优化算法迭代后值依然相等。之后的迭代也是如此。在这种情况下,无论隐藏单元有多少,隐藏层本质上只有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

模型评价:

06858de4-8d2b-eb11-8da9-e4434bdf6706.svg

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

a17305da5726a9a68cc4ac11b42f4515.png

可以使用K折交叉验证来选择超参数。一组参数的训练误差可以达到很低,但是在K折交叉验证上的误差可能反而较高。这种现象很可能是由过拟合造成的。因此,当训练误差降低时,我们要观察K折交叉验证上的误差是否也相应降低。

如需源码,请后台回复 "房价预测"。有什么问题,可添加微信 "wxid-3ccc".

ecf42ca52e01242c1d442a75943c3072.png

双向Dijkstra算法

EndNote引文编排

利用GN算法进行社区发现

Python爬取高德地图--瓦片图

高斯混合模型判定交通拥堵状态

分享数据---GIMMS NDVI 3gv1(1982-2015)

机器人局部规划算法--DWA算法原理

ArcGIS时间滑块实现车辆轨迹动态展示

多时间序列数据MK突变检验突变点提取

整数规划求解最短路径问题

世界各国GDP排名变化--Python动图实现

d9d2ebfaaabd73e06b5e8d0c4a84bad5.png

0fe45731d6cfef9b475796740b84a0f8.gif

▼ 更多精彩推荐,敬请关注我们 ▼ e547f457943a286c860db925f9cd92d2.png 3579bef33306ccda80142852175b6a41.png 28916186e93436b0c2408714ce876cc8.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值