用sin曲线拟合cos上的数据:
# 用sin曲线拟合cos曲线上的数据
import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
torch.manual_seed(1)
# Hyper parameters
TIME_STEP=10
INPUT_SIZE=1 #曲线上的每个数据点作为一个输入
LR=0.02
# RNN model
class RNN(nn.Module):
def __init__(self):
super(RNN, self).__init__()
self.rnn=nn.RNN(
input_size=INPUT_SIZE,
hidden_size=32, # 32个神经元
num_layers=1, # the num of RNN layers
batch_first=True, # input and output: (batch,time_step,input_size/output_size)
)
self.out=nn.Linear(32,1)
def forward(self,x,h_state): # hidden state 是连续的,所以要一直传递这个state
# x (batch,time_step,input_size)
# h_state (num_layers,batch,hidden_size)
# r_out (batch_size,time_step, output_size)
r_out,h_state=self.rnn(x,h_state) # 将h_state也作为RNN的输入
outs=[] # 把每个时间点的预测值取出来保存到这个list中
for time_step in range(r_out.size(1)): # 取计算的每个时间点的output
outs.append(self.out(r_out[:,time_step,:]))
return torch.stack(outs,dim=1),h_state # 每个batch为一组重新组合outs并返回,返回的是最后一个时刻的h_state
# def forward() 可以替换为下面的形式:
'''
def forward(self,x,h_state):
r_out,h_state=self.rnn(x,h_state)
r_out=r_out.view(-1,32) # 把r_out reshape成32列,行数不确定
outs=self.out(r_out)
return outs.view(-1,32,TIME_STEP),h_state
'''
rnn=RNN()
# print(rnn)
'''
RNN(
(rnn): RNN(1, 32, batch_first=True)
(out): Linear(in_features=32, out_features=1, bias=True)
)
'''
# 训练 sin为输入的x,cos为想要拟合的y,就是用sin曲线上的点去对应cos上的点
optimizer=torch.optim.Adam(rnn.parameters(),lr=LR)
loss_func=nn.MSELoss()
h_state=None # 定义初始的 hidden state
plt.figure(figsize=(10,5))
for step in range(100):
start,end=step*np.pi,(step+1)*np.pi
#用sin曲线预测cos上的值
steps=np.linspace(start,end,TIME_STEP,dtype=np.float32,endpoint=False)
x_np=np.sin(steps)
y_np=np.cos(steps)
x=torch.from_numpy(x_np[np.newaxis,:,np.newaxis]) # np.newaxis:在这个位置上增加一个一维
y=torch.from_numpy(y_np[np.newaxis,:,np.newaxis])
prediction,h_state=rnn(x,h_state)
h_state=h_state.data # !! 把h_state重新包装一下放进下一个iteration中,不然会报错
loss=loss_func(prediction,y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
plt.plot(steps,y.data.numpy().flatten(),'r-') # flatten() 将所有的数据放在一个维度中
plt.plot(steps,prediction.data.numpy().flatten(),'b-')
plt.draw()
plt.pause(0.1)
plt.show()
注:
1. torch.stack()
import torch
a=torch.tensor([[1,1,1],[1,2,3]])
b=torch.tensor([[2,2,2],[2,2,3]])
c=torch.tensor([[3,3,3],[3,2,3]])
list=[a,b,c]
print('dim=0:\n',torch.stack(list,dim=0))
print('dim=1:\n',torch.stack(list,dim=1))
'''
dim=0:
tensor([[[1, 1, 1],
[1, 2, 3]],
[[2, 2, 2],
[2, 2, 3]],
[[3, 3, 3],
[3, 2, 3]]])
dim=1:
tensor([[[1, 1, 1],
[2, 2, 2],
[3, 3, 3]],
[[1, 2, 3],
[2, 2, 3],
[3, 2, 3]]])
'''
2. np.newaxis(),在指定位置增加一个一维的维度
import torch
import numpy as np
np.newaxis
x=torch.tensor([1,2,3])
x_new=x[np.newaxis,:,np.newaxis]
print(x_new)
'''
tensor([[[1],
[2],
[3]]])
'''