虽然使用过pytorch来搭建GANs,但是对于Pytorch其实还是不是很熟,这里想系统的学习下。顺便再来做一下笔记。
https://morvanzhou.github.io/tutorials/machine-learning/torch/3-01-regression/
大家直接看原文好了。这里我自己随便写写便于我自己记忆。
torch.unsqueeze()
,会扩展这个维度。然后dim选择的方向是列的方向。这里,就是将[1,2,3]
变成了[[1], [2], [3]]
类似于这样的操作。torch.rand()
随机数,范围为(0,1)然后,输入的内容为tuple表示规模.data
先获取数据之后,再用numpy()
来转成numpy中的数据类型。import torch
import matplotlib.pyplot as plt
import torch.nn.functional as F # 激励函数都在这
x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1) # x data (tensor), shape=(100, 1)
y = x.pow(2) + 0.2*torch.rand(x.size()) # noisy y data (tensor), shape=(100, 1)
# 画图
plt.scatter(x.data.numpy(), y.data.numpy())
plt.show()
这里会写一个类。就是神经网络类。
torch.nn.Module
在pytorch的官方文档中写道
Base class for all neural network modules.
所有神经网络的基类
Your models should also subclass this class.
你的模型也需要是这个类的子类
Modules can also contain other Modules, allowing to nest them in a tree structure. You can assign the submodules as regular attributes:
Modules可以包括其他的模块,允许按照树形结构建造它。你也可以创立一个子模块,通过下面的方式。(其实文档下写的标准方法,跟下面的是一样的)
super
函数实现父类的初始化class Net(torch.nn.Module): # 继承 torch 的 Module
def __init__(self, n_feature, n_hidden, n_output):
super(Net, self).__init__() # 继承 __init__ 功能
# 定义每层用什么样的形式
self.hidden = torch.nn.Linear(n_feature, n_hidden) # 隐藏层线性输出
self.predict = torch.nn.Linear(n_hidden, n_output) # 输出层线性输出
def forward(self, x): # 这同时也是 Module 中的 forward 功能
# 正向传播输入值, 神经网络分析出输出值
x = F.relu(self.hidden(x)) # 激励函数(隐藏层的线性值)
x = self.predict(x) # 输出值
return x
之后,我们就需要自己申明这样的一个对象了。
net = Net(n_feature=1, n_hidden=10, n_output=1)
意思就是输入层的节点数为1,隐藏层的节点为10,输出层的节点为1
因为输入层为x,而我们这里考虑的只是一个简单的函数拟合问题,当然,这里就只有一个节点啦。这里,我们想起来,为什么之前需要有unsqueeze()操作了。
操作其实非常粗糙
MSELoss
其实就是 ∑ ( x i , y i ) ( x i − y i ) 2 \sum_{(xi, yi)}(x_i- y_i) ^2 ∑(xi,yi)(xi−yi)2。当然啦,有一个系数什么的。那个在确定了输入的集合的规模情况下,这个就是无关紧要的啦。optimizer = torch.optim.SGD(net.parameters(), lr=0.2) # 传入 net 的所有参数, 学习率
loss_func = torch.nn.MSELoss() # 预测值和真实值的误差计算公式 (均方差)
for t in range(100):
prediction = net(x) # 喂给 net 训练数据 x, 输出预测值
loss = loss_func(prediction, y) # 计算两者的误差
optimizer.zero_grad() # 清空上一步的残余更新参数值
loss.backward() # 误差反向传播, 计算参数更新值
optimizer.step() # 将参数更新值施加到 net 的 parameters 上
到这里,其实整个模型就拟合完了。
pip install
的import torch
import matplotlib.pyplot as plt
import torch.nn.functional as F # 激励函数都在这
import os
import shutil
import imageio
PNGFILE = './png/'
if not os.path.exists(PNGFILE):
os.mkdir(PNGFILE)
else:
shutil.rmtree(PNGFILE)
os.mkdir(PNGFILE)
x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1) # x data (tensor), shape=(100, 1)
y = x.pow(2) + 0.2 * torch.rand(x.size()) # noisy y data (tensor), shape=(100, 1)
# 画图
plt.scatter(x.data.numpy(), y.data.numpy())
class Net(torch.nn.Module): # 继承 torch 的 Module
def __init__(self, n_feature, n_hidden, n_output):
super(Net, self).__init__() # 继承 __init__ 功能
# 定义每层用什么样的形式
self.hidden = torch.nn.Linear(n_feature, n_hidden) # 隐藏层线性输出
self.predict = torch.nn.Linear(n_hidden, n_output) # 输出层线性输出
def forward(self, x): # 这同时也是 Module 中的 forward 功能
# 正向传播输入值, 神经网络分析出输出值
x = F.relu(self.hidden(x)) # 激励函数(隐藏层的线性值)
x = self.predict(x) # 输出值
return x
net = Net(1, 10, 1)
optimizer = torch.optim.SGD(net.parameters(), lr=.21)
loss_func = torch.nn.MSELoss()
name_list = []
for t in range(100):
prediction = net(x)
loss = loss_func(prediction, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (t + 1) % 5:
plt.cla()
plt.scatter(x.data.numpy(), y.data.numpy())
plt.plot(x.data.numpy(), prediction.data.numpy(), color='r')
plt.text(0.5, 0, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 20, 'color': 'red'})
plt.savefig(PNGFILE + '%d.png' % t)
name_list.append(PNGFILE + '%d.png' % t)
generated_images = []
for png_path in name_list:
generated_images.append(imageio.imread(png_path))
shutil.rmtree(PNGFILE)
imageio.mimsave('net.gif', generated_images, 'GIF', duration=0.2)