wee4 7月28日

梯度爆炸和梯度消失 

调整参数时,w=w*lr*梯度

梯度消失和梯度爆炸的根源主要是因为深度神经网络结构以及反向传播算法,目前优化神经网络的方法都是基于反向传播的思想,即根据损失函数计算的误差通过反向传播的方式,指导深度网络权值的更新。

现在gpu大多数采用16位浮点数,因为运算快。

lr太大,直接炸掉;lr太小,每次调参幅度太小,几乎不变。 

梯度0:不管学习多大,学习进度不会有任何进展。因为参数更新时,w-lr*梯度

 解决方法:

resnet:残差网络 

LSTM:长短期记忆递归

LSTM,全称 Long Short Term Memory (长短期记忆) 是一种特殊的递归神经网络 。这种网络与一般的前馈神经网络不同,LSTM可以利用时间序列对输入进行分析;简而言之,当使用前馈神经网络时,神经网络会认为我们 t 时刻输入的内容与 t+1 时刻输入的内容完全无关,对于许多情况,例如图片分类识别,这是毫无问题的,可是对于一些情景,例如自然语言处理 (NLP, Natural Language Processing) 或者我们需要分析类似于连拍照片这样的数据时,合理运用 T 或之前的输入来处理 T+1 时刻显然可以更加合理的运用输入的信息。

为了当α大于1的时候,梯度累加,会导致方差梯度爆炸;小于1,会导致梯度消失。所以应为1. 

线性激活函数就只能等于本身

 tanh和relu在原点的时候,能满足等于它本身(f(x)=x),而sigmoid不能。

# coding:utf-8
# coding:gbk
 
import os
import torch
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from torch import nn
from d2l import torch as d2l
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
 
train_data = pd.read_csv(r'D:\Projects\2022\202203\data\train.csv')
test_data = pd.read_csv(r'D:\Projects\2022\202203\data\test.csv')
 
print(train_data.shape)
print(test_data.shape)
 
# 显示前四个和最后两个特征,以及相应标签(房价)
print(train_data.iloc[0:4, [0, 1, 2, 3, -3, -2, -1]])
 
# 在每个样本中,第一个特征是ID,我们将其从数据集中删除
all_features = pd.concat((train_data.iloc[:, 1:-1], test_data.iloc[:, 1:]))
 
# 将所有缺失的值替换为相应特征的平均值,通过将特征重新缩放到零均值和单位方差来标准化数据
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()))
all_features[numeric_features] = all_features[numeric_features].fillna(0)
 
# 处理离散值。我们用一次独热编码替换它们
all_features = pd.get_dummies(all_features,dummy_na=True)
print(all_features.shape)
 
# 从pandas格式中提取Numpy格式,并将其转换为张量表示
n_train = train_data.shape[0]
train_features = torch.tensor(all_features[:n_train].values, dtype=torch.float32)
test_features = torch.tensor(all_features[n_train:].values, dtype=torch.float32)
train_labels = torch.tensor(train_data.SalePrice.values.reshape(-1, 1), dtype=torch.float32)
 
# 训练
loss = nn.MSELoss()
in_features = train_features.shape[1]
 
def get_net():
    net = nn.Sequential(nn.Linear(in_features, 1))
    return net
 
# 我们更关心相对误差,解决这个问题的一种方法是用价格预测的对数来衡量差异
def log_rmse(net, features, labels):
    clipped_preds = torch.clamp(net(features), 1, float('inf'))
    rmse = torch.sqrt(loss(torch.log(clipped_preds), torch.log(labels)))
    return rmse.item()
 
# 我们的训练函数将借助Adam优化器
def train(net, train_features, train_labels, test_features, test_labels, num_epochs, learning_rate, weight_decay, batch_size):
    train_ls, test_ls = [], []
    train_iter = d2l.load_array((train_features, train_labels), batch_size)
    optimizer = torch.optim.Adam(net.parameters(), lr=learning_rate, weight_decay=weight_decay)
    for epoch in range(num_epochs):
        for X, y in train_iter:
            optimizer.zero_grad()
            l = loss(net(X), y)
            l.backward()
            optimizer.step()
        train_ls.append(log_rmse(net, train_features, train_labels))
        if test_labels is not None:
            test_ls.append(log_rmse(net, test_features, test_labels))
    return train_ls, test_ls
 
# K折交叉验证
def get_k_fold_data(k, i, X, y):
    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], 0)
            y_train = torch.cat([y_train, y_part], 0)
    return X_train, y_train, X_valid, y_valid
  
# 返回训练和验证误差的平均值
def 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()
        train_ls, valid_ls = train(net, *data, num_epochs, learning_rate, weight_decay, batch_size)
        train_l_sum += train_ls[-1]
        valid_l_sum += valid_ls[-1]
        if i == 0:
            d2l.plot(list(range(1, num_epochs + 1)), [train_ls, valid_ls], xlabel='epoch', ylabel='rmse', xlim=[1, num_epochs], legend=['train', 'valid'], yscale='log')
        print(f'fold {i + 1}, train log rmse {float(train_ls[-1])},'
              f'valid log rmse  {float(valid_ls[-1]):f}')
    plt.show()
    return train_l_sum / k, valid_l_sum / k
 
 
# 模型选择
k, num_epochs, lr, weight_decay, batch_size = 5, 100, 5, 0, 64
train_l, valid_l = k_fold(k, train_features, train_labels, num_epochs, lr, weight_decay, batch_size)
print(f'{k}-折验证:平均训练log rmse: {float(train_l):f},'
      f'平均验证log rmse: {float(valid_l):f}')
 
 
def train_and_pred(train_features, test_features, train_labels, test_data, num_epochs, lr, weight_decay, batch_size):
    net = get_net()
    train_ls, _ = train(net, train_features, train_labels, None, None, num_epochs, lr, weight_decay, batch_size)
    d2l.plot(np.arange(1, num_epochs + 1), [train_ls], xlabel='epochs', ylabel='log rmse', xlim=[1, num_epochs], yscale='log')
    print(f'train log rmse {float(train_ls[-1]):f}')
    preds = net(test_features).detach().numpy()
    test_data['SalePrice'] = pd.Series(preds.reshape(1, -1)[0])
    submission = pd.concat([test_data['Id'], test_data['SalePrice']], axis=1)
    submission.to_csv('submission.csv', index=False)
    plt.show()
 
train_and_pred(train_features, test_features, train_labels, test_data, num_epochs, lr, weight_decay, batch_size)

 

 1、定义module里有那些层。定义一个网络,20->64全连接层,relu激活层,64->32全连接层,relu激活层,串起来。定义一个线性类,32->16的全连接

  2、forward :  把x放网络里,再把结果放进全连接层里

1. 均匀分布
torch.nn.init.uniform_(tensor, a=0, b=1)
服从~U ( a , b ) 

constant_:让m.weight永远是42

apply函数:调用  apply(init_42):调用init_42函数

卷积层

 

h是输出 ,x是输入    k,l是空间坐标。这里的变换,只是为了更改下标,以引出卷积

 

只在(i,j)四周的一定范围内计算。其余记零(忽略范围外) 

卷积层是一个特殊的全连接层。一般的全连接,一层对一层。卷积是一个矩阵对一个矩阵 

卷积就是过去对现在的影响,周围像素点对当前像素的影响。图像是f(不稳定的输入)卷积核是g(不变,稳定的输出)。卷积核类似“既定规则”,f经过g之后,会转化成结果。

 想知道f(x-1,y-1)对f(x,y)产生了什么影响。

就是f(x-1,y-1)*g(未知,未知)。想知道x时刻对t时刻的影响。

已经知道了x时刻吃进去的东西,还得知道(t-x)小时的时间里,东西会消化多少。所以,未知=x-(x-1)=1  未知=y-(y-1)=1。f(x-1,y-1)*g(1,1) 或者,f(x+1,y-1)*g(x-(x+1),1)=f(x+1,y-1)*g(-1,1)

 

核的大小 控制了局部性,核大一点,看的范围多一点;核小一点,看的小一点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值