Pytorch搭建神经网络--回归与分类问题

torch.nn搭建神经网络–回归问题

import torch
import torch.nn as nn
import torch.nn.functional as F
import matplotlib.pyplot as plt

x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1)
y = x.pow(2) + 0.2 * torch.rand(x.size())

# plt.scatter(x, y)
# plt.show()

class Net(nn.Module):
    def __init__(self, n_feature, n_hidden, n_output):
        super(Net, self).__init__()
        self.hidden = nn.Linear(n_feature, n_hidden)
        self.predict = nn.Linear(n_hidden, n_output)

    def forward(self, x):
         x = F.relu(self.hidden(x))
         x = self.predict(x)
         return x

net = Net(1, 10, 1)
print(net)

optimizer = torch.optim.SGD(net.parameters(), lr=0.5)
loss_func = nn.MSELoss()

plt.ion()
for t in range(100):
    prediction = net(x)
    loss = loss_func(prediction, y)

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if t % 5 == 0:
        plt.cla()
        plt.scatter(x, y)
        plt.plot(x.detach().numpy(), prediction.detach().numpy(), color='r')
        plt.text(0.5, 0, 'Loss=%.4f' % loss, color='r')
        plt.pause(0.1)

plt.ioff()
plt.show()

和利用Tensorflow构建神经网络的过程非常类似,主要包括以下几点相同和不同点:
相同点:
1.都是利用class结构定义一个框架,搭建层,规定optimizer和loss。
不同点:
1.在之前tensorflow中,需要定义weights,并且定义linear运算wx+b和activation运算activation function=;在torch中利用nn.Linear()就可以直接进行线性运算,而且在forward过程中,直接利用F.relu()激活。
2.直接的体验是Pytorch是一个动态结构,不需要像Tensorflow一样,需要先搭建一个静态框架,利用下面的结构作为一个窗口进入。

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

而在torch更强调的是梯度下降的过程,所以务必要加的语句是:

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

3.loss函数的定义方式不同,Tensorflow中是tf.reduce_mean(),这里直接就是nn.MSEloss().

总体而言,torch的语句更加便捷,而且操作更加灵活。
需要注意的是,torch中主要就是用tensor运算,需要在tensor和numpy之间相互转换,尤其是利用plot画图时,只能对numpy进行操作,所以需要利用语句.detach().numpy()转换为数组形式。

torch.nn搭建神经网络–分类问题

import torch
import numpy as np
import torch.nn as nn
import torch.nn.functional as F
import matplotlib.pyplot as plt

x0 = torch.normal(-2, 1, [1000, 2])
y0 = torch.zeros(1000)
x1 = torch.normal(2, 1, [1000, 2])
y1 = torch.ones(1000)
x = torch.cat((x0, x1), 0).type(torch.FloatTensor)
y = torch.cat((y0, y1), 0).type(torch.LongTensor)
print(y.shape)
plt.scatter(x.detach().numpy()[:, 0], x.detach().numpy()[:, 1])
plt.show()

class Net(nn.Module):
    def __init__(self, n_input, n_hidden, n_output):
        super(Net, self).__init__()
        self.hidden = nn.Linear(n_input, n_hidden)
        self.output = nn.Linear(n_hidden, n_output)

    def forward(self, x):
        x = F.relu(self.hidden(x))
        x = F.softmax(self.output(x), dim=1)
        return x

net = Net(2, 10, 2)
# print(net)

optimizer = torch.optim.SGD(net.parameters(), lr=0.5)
loss_fun = nn.CrossEntropyLoss()


plt.ion()
for i in range(50):
    out = net(x)
    loss = loss_fun(out, y)

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if i % 2 == 0:
        plt.cla()
        prediction = torch.max(out, dim=1)[1]
        pre_y = prediction.detach().numpy()
        plt.scatter(x.detach().numpy()[:, 0], x.detach().numpy()[:, 1], c=pre_y, s=10)
        accuracy = torch.sum(torch.eq(prediction, y)).item() / 2000
        plt.text(1.5, -4, 'Accuracy=%.4f' % accuracy)
        plt.pause(0.1)
plt.ioff()
plt.show()

输出结果为:
在这里插入图片描述
在这里插入图片描述
在这里需要注意的问题主要是plt当中数组、标量、张量之间的转换。
1.标签集y必须是LongTensor。
2.softmax函数版本更新,要明确dim。
3.在plt.scatter中画散点图必须是numpy格式,所以要用语句.detach().numpy()。
4.比较两个张量a,b中的元素是否相等,用语句torch.eq(a,b),比较结果为True或者False。比较时务必要注意两者的shape必须是相等的,否则就会出错。这里prediction和y的shape都是torch.Size([2000])。下面的错误代码就是一个教训。
5.当利用torch.sum将正确个数求出来之后。获得的值并不是一个标量,而是一个tensor。而计算精度时用到的除法运算是针对标量的。所以对于tensor a要用语句**a.item()**将其转换为标量。

错误代码

第一次编写时,定义

y0 = torch.zeros(1000, 1)
y1 = torch.ones(1000, 1)
y = torch.cat((y0, y1), 0).type(torch.LongTensor)

后面是:

for i in range(100):
    out = net(x)       
    loss = loss_fun(out, y.squeeze())  #

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if i % 5 == 0:
        plt.cla()
        prediction = torch.max(out, dim=1)[1]
        pre_y = prediction.detach().numpy()
        plt.scatter(x.detach().numpy()[:, 0], x.detach().numpy()[:, 1], c=pre_y, s=10)
        accuracy = (torch.sum(torch.eq(prediction, y)) / 2000).detach().numpy()
        accuarcy = accuracy.item()
        plt.text(1.5, -4, 'Accuracy=%.2f' % accuracy)
        plt.pause(0.1)
plt.ioff()
plt.show()

输出结果为:精度都上1000了(头发又掉了),显然是错的。
在这里插入图片描述
所以在使用torch.eq时务必要保证两个的shape是一样的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值