1.采用自己的数据集来构造Dataloader
现将其封装成TensorDataset,再将其变成DataLoader
# 获取数据
train_data, test_data = load_data()#自己定义的函数
x = train_data[:, :-1]
# x=x.float32()
x=torch.tensor(x)
x.to(torch.float32)
y = train_data[:, -1:]
# y=y.float32()
y=torch.tensor(y)
from torch.utils.data import TensorDataset
from torch.utils.data import DataLoader
all_train_data = TensorDataset(x,y)
data = DataLoader(all_train_data, batch_size=2, shuffle=True)
for i, j in enumerate(data):
x, y = j
print(x.shape)
print(y.shape)
print(' batch:{0} x:{1} y: {2}'.format(i, x, y))
2.误差函数CrossEntropyLoss
如果 误差函数 用了 CrossEntropyLoss (内置了Softmax) 不要再用softmax
但若是使用了MSELoss(),则需要Softmax
3.Loss爆炸达到nan或者几百
降低初始的学习率,并设置学习率衰减
比如这段代码的lr,将其降低即可
optimizer = torch.optim.Adam(rnn.parameters(), lr=0.01)
4.loss训练
loss_func=torch.nn.CrossEntropyLoss()
loss = loss_func(output, b_y)
在训练过程中总是会弹出来
0D or 1D target tensor expected, multi-target not supported
这是因为tensor的格式没有匹配上
需要使用squeeze:从数组的形状中删除单维度条目,即把shape中为1的维度去掉
loss = loss_func(output, b_y.squeeze(dim=1).long())
处理完之后
格式变化:
其中64是batch_size,28是设置的分类类别总数
5.CNN模型格式处理
现数据格式:
想用CNN的模型进行处理
但是格式总是出现问题,这就需要我们真正了解CNN所输入的格式是什么?
(N,C,H,W)一般情况是处理图片
- N:Batch,批处理大小,表示一个batch中的图像数量
- C:Channel,通道数,表示一张图像中的通道数
- H:Height,高度,表示图像垂直维度的像素数
- W:Width,宽度,表示图像水平维度的像素数
但是我们这边采取的是纯数据而非图像,通过观察我们可以发现,最终需要的是(64,1,1,9)
如果直接获取数据,输出的类型是:(batch=64,特征=9)
x torch.Size([64, 9])
这时候就需要view
b_x = x.view(-1, 1, 9)
view中一个参数定为-1,代表动态调整这个维度上的元素个数,以保证元素的总数不变
b_x torch.Size([64, 1, 9])
采用Conv1d(CNN用来处理文本的函数):
self.conv1 = nn.Conv1d(in_channels=1,out_channels=1,kernel_size=2,stride=1)
即可实现
6.Mask的机制
因为掩码是想要将其一部分的数据排除在外,如果考虑到最后一层有softmax进行分类的情况下,我们可以通过给这一部分赋上很大的负数,这样的话经过softmax,其概率就可以近似为0了。
我们可以针对Transformer(NLP)里面的两种mask,分别是padding mask和sequence mask进行分析。
padding mask:就是为让每个句子的长度相同,将不足最长长度句子的后面添上padding mask,从而进行处理。
Sequence mask:sequence mask是为了使得decoder不能看见未来的信息。也就是对于一个序列,在time_step为t的时刻,我们的解码输出应该只能依赖于t时刻之前的输入,因此需要将t后面的信息隐藏掉。这里比较巧妙,是通过一个上三角矩阵,上三角的值全为1,下三角的值全为0,对角线也是0。把这个矩阵作用在每一个序列上即可实现掩码操作。
7.RNN输入
一般情况下,RNN输入的对象是文本,在批处理情况下,输入的格式为:
【batch_size, timesteps, input_dim】
batch_size:是批处理的长度,也就是一次是对几个句子进行处理
timesteps:可以理解成seq_length,也就是句子的长度,一般是整个文本最长的句子长度
input_dim:表示的是某一时刻输入数据的维度,可以理解为每个句子中词的维度,如只有‘I’、‘like’、‘you’,那么这个文本输入的input_dim=3。
个人尝试(不知道是否正确)
针对上面的数据,我是将input_dim=1,理解为这个数值维度为1,且就表示这个数。
8.随机提取数据
随机提取1000个数据
batch_size = 1000
slice = np.random.choice(training_data.shape[0], batch_size)
# print(array[slice])
test_data = training_data[slice]
9.DataFrame转化类型
python报错TypeError:Cannot convert the series to class float的原因分析:
不能直接使用float(...),而是astype(float)函数
10.range
for i in range(200,450):
是指 i 的范围是200-449 。
11.权重参数梯度清零
optimizer.zero_grad()
功能:梯度初始化为零,把loss关于weight的导数变成0
根据pytorch中的backward()函数的计算,当网络参量进行反馈时,梯度是被积累的而不是被替换掉。
但是在每一个batch时毫无疑问并不需要将两个batch的梯度混合起来累积,因此这里就需要重置。
optimizer.zero_grad() # 梯度初始化为零,把loss关于weight的导数变成0
output = model(data) # forward:将数据传入模型,前向传播求出预测的值
loss = F.cross_entropy(output, target) # 求loss
loss.backward() # backward:反向传播求梯度
optimizer.step() # optimizer:更新所有参数
总结来说:梯度累加就是,每次获取1个batch的数据,计算1次梯度,梯度不清空,不断累加,累加一定次数后,根据累加的梯度更新网络参数,然后清空梯度,进行下一次循环。
一定条件下,batchsize越大训练效果越好,梯度累加则实现了batchsize的变相扩大,如果accumulation_steps,也就是梯度更新的步长为8,则batchsize '变相' 扩大了8倍,是解决显存受限的一个不错的trick,使用时需要注意,学习率也要适当放大。
12.数据归一化
原始样本各个分量数值的数量级如果有很大的差异,在更新过程中会将导致更新的w远远大于其他分量,从而使得其他分享几乎丧失调控作用,所以需要对其进行规范化处理。
一般情况下的通过获取这个特征值的max、min、average value,通过
x_new=(x-avgs)/(max-min)得到.