Pytorch学习——搭建第一个神经网络

与使用GPU有关的函数

检查GPU是否可用

torch.cuda.is_available()

若输出为True,则表明GPU可用。

输出可用GPU的个数

torch.cuda.device_count()

输出GPU的信息

torch.cuda.get_device_name(0) #序号从0开始

输出当前GPU序号

torch.cuda.current_device()

指定使用GPU

#device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
device = torch.device('cuda:0')
#还需要将模型(神经网络)与数据转移到相应的设备上
model = model.to(device)
data = data.to(device)
#如后面要用到data,可能要使用data.cpu()
#TypeError: can't convert cuda:0 device type tensor to numpy.
#Use Tensor.cpu() to copy the tensor to host memory first.

Pytorch中与矩阵等有关的数学运算函数

Pytorch中包含了Numpy中的大多数函数,具体可以参考其官网.

torch.unsqueeze()

这里介绍一个函数torch.unsqueeze(input, dim),该函数的功能是在指定的dim上加上一个冗余维度。
如当我们使用torch.linspace(start, end, num)或是torch.ones(n)等产生数据时产生的Tensor是一维的,而后续的运算都需要基于一个二维(或更高维)的Tensor,所以需要进行维度的扩展。举例如下:

x = data.ones(5)
x = torch.unsqueeze(x, dim=0) #作为2维张量的首行
x = torch.unsqueeze(x, dim=-1) #作为2维张量的首列

特别的,当在我们想自己搭建一个简单的神经网络时,假若生成data只有一个feature时,需要将其变为一个二维张量的一列。举例如下:

x = torch.linspace(-1, 1, 10)
print(x)
print(x.size())
x = torch.unsqueeze(x, dim=1)
print(x)
print(x.size())

输出为

tensor([-1.0000, -0.7778, -0.5556, -0.3333, -0.1111,  0.1111,  0.3333,  0.5556,
         0.7778,  1.0000])
torch.Size([10])
tensor([[-1.0000],
        [-0.7778],
        [-0.5556],
        [-0.3333],
        [-0.1111],
        [ 0.1111],
        [ 0.3333],
        [ 0.5556],
        [ 0.7778],
        [ 1.0000]])
torch.Size([10, 1])

还有一种极端情况是只有一个样本数据,此时则需要将其转化为二维张量的一行,即上面的dim应设为0

关于这个函数的更多信息,可以参考下面几个链接:
《torch.squeeze()和torch.unsqueeze()》
《PyTorch中为什么需要使用squeeze()和unsqueeze()操作?》
《torch.unsqueeze() 和 torch.squeeze()》

神经网络类的定义

class NeuralNet(torch.nn.Module):

    def __init__(self, input_size, hidden_size, output_size):
        
        super(NeuralNet, self).__init__()

        self.net = torch.nn.Sequential(
            torch.nn.Linear(input_size, hidden_size),
            torch.nn.ReLU(),
            torch.nn.Linear(hidden_size, hidden_size),
            torch.nn.ReLU(),
            torch.nn.Linear(hidden_size, output_size)
        )

    def forward(self, x):
      
        out = self.net(x)
        
        return out

上面的代码定义了一个3层的前馈神经网络。其中两个隐藏层的神经元个数相同,且采用了相同的激活函数。若不同隐藏层采用不同数量的神经元,只需要在__init__()函数的参数列表中给出,然后在其内进行相关定义即可。上述代码等价于下面的代码:

class NeuralNet(torch.nn.Module):

    def __init__(self, input_size, hidden_size, output_size):
        
        super(NeuralNet, self).__init__()

        self.hidden1 = torch.nn.Linear(input_size, hidden_size)
        self.hidden2 = torch.nn.Linear(hidden_size, hidden_size)
	    self.output= torch.nn.Linear(hidden_size, output_size)
	    self.act_fun = torch.nn.ReLU()

    def forward(self, x):
      
        out = self.hidden1(x)
        out = self.act_fun(out)
        out = self.hidden2(out)
        out = self.act_fun(out)
        out = self.output(out)
        
        return out
  • torch.nn.Linear(input_size, output_size)定义一个线性全连接层
  • torch.nn.ReLU()函数表示使用ReLU激活函数。

实例化一个神经网络类

# to(device)选择在'cpu'或'cuda'上运行
model = NeuralNet(input_size, hidden_size, output_size).to(device)

定义损失函数

loss_fun = torch.nn.MSELoss()

损失函数的选择取决于相应的任务,如回归常用MSE,而分类常用Cross Entropy。下面的链接给出了比较全面的torch中的损失函数及其用法:
PyTorch 学习笔记(六):PyTorch的十八个损失函数

一个需要注意的是多分类采用CrossEntropyLoss时,不需要再输出层添加Softmax激活函数,在调用CrossEntropyLoss时会自动计算,即此时输出层设为线性全连接层。

BCELoss是二分类下的交叉熵损失,此时需要显式的在输出层(一个神经元)添加一个Sigmoid激活函数。

选择并设置优化器

optimizer = torch.optim.Adam(model.parameters(), lr=0.01)

一轮迭代的实现

y_hat = model(x) #前向运算
loss = loss_fun(y_hat, y) #计算误差
optimizer.zero_grad() #所有参数的梯度清零,防止累加
loss.backward() #误差反向传播,所有参数的梯度都会被计算
optimizer.step() #进行一次参数更新

完整代码

colab在线

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值