源代码
代码如下
import torch
import numpy as np
from torch.autograd import Variable
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt
# """ builds features i.e. a matrix with columns [x, x^2, x^3]."""
def make_features(x):
x = x.unsqueeze(1)
return torch.cat([ x ** i for i in range(1, 4)], 1) # 按列合并
# 设定target参数
w_target = torch.FloatTensor([0.5, 3, 2.4]).unsqueeze(1) # unsqueeze 变“数组”为“矩阵”(增加维度)
b_target = torch.FloatTensor([0.9])
# 计算y的真实值
def f(x):
"""近似 function."""
return x.mm(w_target) + b_target[0]
# 返回x y
def get_batch(batch_size=256):
"""build a batch i.e (x, f(x)) pair."""
random = torch.randn(batch_size) # 生成batch_size个随机数
random = random.numpy()
random.sort() # 升序排列random,涉及类型转换,tensor 2 array
random = torch.from_numpy(random) # random 类型转换 array 2 tensor
# print(random)
x = make_features(random) # 生成x, x^2, x^3 的列矩阵
y = f(x) # 生成真实y
# 检查cuda加速 转Variable
if torch.cuda.is_available():
return Variable(x).cuda(), Variable(y).cuda()
else:
return Variable(x), Variable(y)
# -------------------------定义模型---------------------------
class poly_model(nn.Module):
def __init__(self):
super(poly_model, self).__init__()
self.poly = nn.Linear(3, 1) # 输入三维,输出一维
def forward(self, x):
out = self.poly(x)
return out
if torch.cuda.is_available():
model = poly_model().cuda()
else:
model = poly_model()
# ------------定义损失函数和优化函数--------------
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=1e-3)
# 循环直到误差小于1e-3
epoch = 0
while True:
# get data
batch_x, batch_y = get_batch() # 得到真实值
# forward pass
output = model(batch_x) # 用模型计算output (预测值)
loss = criterion(output, batch_y) #计算损失函数,前者为预测值,后者为真实值
print_loss = loss.data
# 重置参数
optimizer.zero_grad() # 优化器梯度归零
# backward pass
loss.backward()
# 更新参数
optimizer.step()
epoch+=1
if (epoch-1)%500 == 0:
# print('batch_x:', type(batch_x))
# print('batch_y:', type(batch_y))
# print('output:',type(output))
batch_x = batch_x.cpu()
batch_y = batch_y.cpu()
output = output.cpu()
# print('batch_x:', type(batch_x))
# print('batch_y:', type(batch_y))
# print('output:', type(output))
output = output.detach().numpy()
plt.plot(batch_x.numpy()[:, 0], batch_y.data.numpy(), color='b', label='real curve')
# plt.plot(batch_x.numpy()[:, 0], output, 'r', label='fitting curve')
plt.legend()
plt.show()
output = torch.from_numpy(output)
batch_x = batch_x.cuda()
batch_y = batch_y.cuda()
output = output.cuda()
# --------------------------------------------------------------------------
if print_loss < 1e-3:
print('epoch:{}'.format(epoch))
break
model.eval() # 将模型转变为测试模式(有一些层操作在训练和测试的时候不一样,所以要转换
# 去cuda化
batch_x = batch_x.cpu()
batch_y = batch_y.cpu()
output = output.cpu()
output = output.detach().numpy()
plt.plot(batch_x.numpy()[:,0], batch_y.data.numpy(), color='b', label='real curve')
# plt.plot(batch_x.numpy()[:,0], output, 'r', label='fitting curve')
# plt.legend()
plt.show()
for param in model.named_parameters():
print(param[0])
print(param[1])
疑惑
可视化