引用情况
import numpy as np
import pandas as pd
import os
import gzip
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets
from torchvision import transforms
from torch.utils.data import Dataset
from torch.utils.data import DataLoader
上面的引用中,torch.nn是用来构建神经网络每个层的,例如卷积层,全连接层等。torch.nn.functional用以引用各种数学函数,例如激活函数等。torch.optim是各种优化方法,例如SGD,ADAM等。
torchvision和torch.utils.data等就不重要了
数据集
首先需要数据集,这里使用MNIST手写数字数据集,该数据集既可以用来训练全连接,也可以训练卷积神经网络。强烈不建议从官网下载该数据集,因为网速奇慢无比,而且还总是error断开连接。首先手动下载链接MNIST,密码3no7。将该压缩包文件解压后有四个文件,放在同一个文件夹中,记住路径。然后直接copy下面这段代码即可。下面这段代码是我在CSDN中一个大佬中抄过来的,代替读取数据集的,对以后的学习工作并没有什么价值,copy即可。
class DealDataset(Dataset):
"""
读取数据、初始化数据
"""
def __init__(self, folder, data_name, label_name,transform=None):
(train_set, train_labels) = load_data(folder, data_name, label_name) # 其实也可以直接使用torch.load(),读取之后的结果为torch.Tensor形式
self.train_set = train_set
self.train_labels = train_labels
self.transform = transform
def __getitem__(self, index):
img, target = self.train_set[index], int(self.train_labels[index])
if self.transform is not None:
img = self.transform(img)
return img, target
def __len__(self):
return len(self.train_set)
def load_data(data_folder, data_name, label_name):
with gzip.open(os.path.join(data_folder,label_name), 'rb') as lbpath: # rb表示的是读取二进制数据
y_train = np.frombuffer(lbpath.read(), np.uint8, offset=8)
with gzip.open(os.path.join(data_folder,data_name), 'rb') as imgpath:
x_train = np.frombuffer(
imgpath.read(), np.uint8, offset=16).reshape(len(y_train), 28, 28)
return (x_train, y_train)
trainDataset = DealDataset('./data/MNIST/', "train-images-idx3-ubyte.gz","train-labels-idx1-ubyte.gz",transform=transforms.ToTensor())
testDataset = DealDataset('./data/MNIST/', "t10k-images-idx3-ubyte.gz","t10k-labels-idx1-ubyte.gz",transform=transforms.ToTensor())
# 训练数据和测试数据的装载
train_loader = DataLoader(
dataset=trainDataset,
batch_size=100, # 一个批次可以认为是一个包,每个包中含有100张图片
shuffle=False,
)
test_loader = DataLoader(
dataset=testDataset,
batch_size=100,
shuffle=False,
)
注意上面代码中的路径’./data/MNIST/’,我的notebook的路径是home/notebook,数据集文件夹是home/notebook/data/MNIST,所以路径是这样,注意修改路径。
全连接神经网络
这里构建一个十分简单基础的包含一个隐含层的全连接神经网络。
#需要继承nn.Module,不要忘了
class NN(nn.Module):
def __init__(self):
#super(NN,self).__init__()如果不理解就背下来,不懂python的super可以百度一下
super(NN,self).__init__()
#self.fc1构建第一个全连接层(full connect),nn.Linear是torch的全连接层方法,两个参数是左右的神经元个数
self.fc1 = nn.Linear(28*28,500)
self.fc2 = nn.Linear(500,10)
def forward(self,x):
x = self.fc1(x)
#F.relu是torch的relu激活函数,还有其他激活函数,可以参考官网
x = F.relu(x)
x = self.fc2(x)
return x
使用pytorch构建神经网络的步骤就这么简单,首先定义一个类,类里面包含两种方法,init和forward,网络的层定义在init中,前向方法定义在forward中就可以了。
实例化类,这里默认都是有GPU的,没有GPU。。。。。。买一个吧。
net_NN = NN().cuda()
卷积神经网络
class CNN(nn.Module):
def __init__(self):
super(CNN,self).__init__()
#定义卷积和全连接层
self.c1 = nn.Conv2d(1,6,(5,5))
self.c2 = nn.Conv2d(6,16,(5,5))
self.fc1 = nn.Linear(256,120)
self.fc2 = nn.Linear(120,84)
self.fc3 = nn.Linear(84,10)
def forward(self,x):
#全向方法
#x = F.max_pool2d(F.relu(self.c1(x)),2)
x = self.c1(x)
x = F.relu(x)
x = F.max_pool2d(x,2)
x = self.c2(x)
x = F.relu(x)
x = F.max_pool2d(x,2)
x = x.view(-1,self.num_flat_feature(x))
x = self.fc1(x)
x = F.relu(x)
x = self.fc2(x)
x = F.relu(x)
x = self.fc3(x)
return x
def num_flat_feature(self,x):
size = x.size()[1:]
num_features = 1
for s in size:
num_features *= s
return num_features
损失函数&优化方法&学习率
#损失函数,也可以选择其他损失函数
criterion = nn.CrossEntropyLoss()
#学习率
lr = 0.01
#优化方法,也可以选择其他优化方法
#net_NN.parameters(),将实例的参数传递给优化函数,优化函数自动计算导数
optimizer = optim.SGD(net_NN.parameters(),lr = lr,momentum = 0.9)
训练函数
def train(model, criterion, optimizer, epochs):
loss = 0.0
for epoch in range(epochs):
for i, data in enumerate(train_loader):
(inputs, labels) = data
#step1,获取inputs,计算outputs
#因为是全连接网络,所以需要reshape到一维,卷积不需要
inputs = inputs.reshape(-1, 28*28).to(device)
labels = labels.to(device)
outputs = model(inputs)
#step2,清零梯度,计算loss,反向传播
optimizer.zero_grad()
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
if i%100 == 0:
print('Epoch [{}/{}], Loss: {:.4f}'
.format(epoch + 1, epochs, loss.item()))
所以使用pytorch构建一个神经网络总共就四步。
第一步,把训练数据拿来。
第二步,把神经网络搭上。
第三步,确定loss_function,lr和优化方法。
第四步,构建训练函数。1.获取inputs,计算outputs。2.清零梯度,计算loss,反向传播。
你学废了吗?
保存与加载模型
torch.save(net_NN,'parh/name.pkl')
net = torch.load('parh/name.pkl')
测试函数
def test(test_loader,model):
correct = 0
total = 0
for data in test_loader:
inputs, labels = data
inputs = inputs.cuda()
labels = labels.cuda()
outputs = model(inputs)
#torch.max并不是np.max一个意思,是用以计算sofamax的分类类别的,建议CSDN查一下
_, predict = torch.max(outputs, 1)
total += labels.size(0)
correct += (predict == labels).sum()
print(total,correct)