Browse Source

Add pytorch example for nn

pull/1/MERGE
Shuhui Bu 6 years ago
parent
commit
5b7042b1a5
4 changed files with 246 additions and 27 deletions
  1. +6
    -23
      2_pytorch/PyTorch快速入门.ipynb
  2. +129
    -0
      demo_code/CNN_CIFAR.py
  3. +96
    -0
      demo_code/Nerual_Network.py
  4. +15
    -4
      demo_code/Neural_Network.0.py

+ 6
- 23
2_pytorch/PyTorch快速入门.ipynb
File diff suppressed because it is too large
View File


+ 129
- 0
demo_code/CNN_CIFAR.py View File

@@ -0,0 +1,129 @@
import torch as t
import torch.nn as nn
import torch.nn.functional as F
from torch import optim
from torch.autograd import Variable

import torchvision as tv
import torchvision.transforms as transforms
from torchvision.transforms import ToPILImage

show = ToPILImage() # 可以把Tensor转成Image,方便可视化

# 第一次运行程序torchvision会自动下载CIFAR-10数据集,
# 大约100M,需花费一定的时间,
# 如果已经下载有CIFAR-10,可通过root参数指定

# 定义对数据的预处理
transform = transforms.Compose([
transforms.ToTensor(), # 转为Tensor
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)), # 归一化
])

# 训练集
dataset_path = "../data"
trainset = tv.datasets.CIFAR10(
root=dataset_path, train=True, download=True, transform=transform)

trainloader = t.utils.data.DataLoader(
trainset,
batch_size=4,
shuffle=True,
num_workers=2)

# 测试集
testset = tv.datasets.CIFAR10(
dataset_path, train=False, download=True, transform=transform)

testloader = t.utils.data.DataLoader(
testset,
batch_size=4,
shuffle=False,
num_workers=2)

classes = ('plane', 'car', 'bird', 'cat', 'deer',
'dog', 'frog', 'horse', 'ship', 'truck')


# Define the network
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(3, 6, 5)
self.conv2 = nn.Conv2d(6, 16, 5)
self.fc1 = nn.Linear(16*5*5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)

def forward(self, x):
x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
x = F.max_pool2d(F.relu(self.conv2(x)), 2)
x = x.view(x.size()[0], -1)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x


net = Net()
print(net)

criterion = nn.CrossEntropyLoss() # 交叉熵损失函数
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

t.set_num_threads(8)
for epoch in range(2):

running_loss = 0.0
for i, data in enumerate(trainloader, 0):

# 输入数据
inputs, labels = data
inputs, labels = Variable(inputs), Variable(labels)

# 梯度清零
optimizer.zero_grad()

# forward + backward
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()

# 更新参数
optimizer.step()

# 打印log信息
running_loss += loss.data[0]
if i % 2000 == 1999: # 每2000个batch打印一下训练状态
print('[%d, %5d] loss: %.3f' \
% (epoch + 1, i + 1, running_loss / 2000))
running_loss = 0.0
print('Finished Training')

dataiter = iter(testloader)
images, labels = dataiter.next() # 一个batch返回4张图片
print('实际的label: ', ' '.join(\
'%08s'%classes[labels[j]] for j in range(4)))
show(tv.utils.make_grid(images / 2 - 0.5)).resize((400,100))


# 计算图片在每个类别上的分数
outputs = net(Variable(images))
# 得分最高的那个类
_, predicted = t.max(outputs.data, 1)

print('预测结果: ', ' '.join('%5s'\
% classes[predicted[j]] for j in range(4)))


correct = 0 # 预测正确的图片数
total = 0 # 总共的图片数
for data in testloader:
images, labels = data
outputs = net(Variable(images))
_, predicted = t.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum()

print('10000张测试集中的准确率为: %d %%' % (100 * correct / total))

+ 96
- 0
demo_code/Nerual_Network.py View File

@@ -0,0 +1,96 @@
from __future__ import print_function

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.autograd import Variable

from torchvision import datasets, transforms

# Training settings
batch_size = 64

# MNIST Dataset
dataset_path = "../data/mnist"
train_dataset = datasets.MNIST(root=dataset_path,
train=True,
transform=transforms.ToTensor(),
download=True)

test_dataset = datasets.MNIST(root=dataset_path,
train=False,
transform=transforms.ToTensor())

# Data Loader (Input Pipeline)
train_loader = torch.utils.data.DataLoader(dataset=train_dataset,
batch_size=batch_size,
shuffle=True)

test_loader = torch.utils.data.DataLoader(dataset=test_dataset,
batch_size=batch_size,
shuffle=False)


# define Network
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.l1 = nn.Linear(784, 520)
self.l2 = nn.Linear(520, 320)
self.l3 = nn.Linear(320, 240)
self.l4 = nn.Linear(240, 120)
self.l5 = nn.Linear(120, 10)

def forward(self, x):
x = x.view(-1, 784) # Flatten the data (n, 1, 28, 28)-> (n, 784)
x = F.relu(self.l1(x))
x = F.relu(self.l2(x))
x = F.relu(self.l3(x))
x = F.relu(self.l4(x))
return self.l5(x)


model = Net()

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)


def train(epoch):
#model.train()
for batch_idx, (data, target) in enumerate(train_loader):
data, target = Variable(data), Variable(target)
optimizer.zero_grad()
output = model(data)
loss = criterion(output, target)
loss.backward()
optimizer.step()
if batch_idx % 10 == 0:
print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
epoch, batch_idx * len(data), len(train_loader.dataset),
100. * batch_idx / len(train_loader), loss.data[0]))


def test():
model.eval()
test_loss = 0
correct = 0
for data, target in test_loader:
data, target = Variable(data, volatile=True), Variable(target)
output = model(data)
# sum up batch loss
test_loss += criterion(output, target).data[0]
# get the index of the max
pred = output.data.max(1, keepdim=True)[1]
correct += pred.eq(target.data.view_as(pred)).cpu().sum()

test_loss /= len(test_loader.dataset)
print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
test_loss, correct, len(test_loader.dataset),
100. * correct / len(test_loader.dataset)))


for epoch in range(1, 10):
train(epoch)
test()

demo_code/Neural_Network.py → demo_code/Neural_Network.0.py View File

@@ -6,9 +6,9 @@ from torch.utils.data import DataLoader
from torchvision import transforms from torchvision import transforms
from torchvision import datasets from torchvision import datasets


batch_size = 32
learning_rate = 1e-2
num_epoches = 50
batch_size = 32
learning_rate = 1e-2
num_epoches = 50


# 下载训练集 MNIST 手写数字训练集 # 下载训练集 MNIST 手写数字训练集
dataset_path = "../data/mnist" dataset_path = "../data/mnist"
@@ -50,15 +50,21 @@ for epoch in range(num_epoches):
print('*' * 10) print('*' * 10)
running_loss = 0.0 running_loss = 0.0
running_acc = 0.0 running_acc = 0.0

for i, data in enumerate(train_loader, 1): for i, data in enumerate(train_loader, 1):
# FIXME: label need to change one-hot coding
img, label = data img, label = data
img = img.view(img.size(0), -1) img = img.view(img.size(0), -1)
target = torch.zeros(label.size(0), 10)
target = target.scatter_(1, label.data, 1)

if torch.cuda.is_available(): if torch.cuda.is_available():
img = Variable(img).cuda() img = Variable(img).cuda()
label = Variable(label).cuda() label = Variable(label).cuda()
else: else:
img = Variable(img) img = Variable(img)
label = Variable(label) label = Variable(label)

# 向前传播 # 向前传播
out = model(img) out = model(img)
loss = criterion(out, label) loss = criterion(out, label)
@@ -66,6 +72,7 @@ for epoch in range(num_epoches):
_, pred = torch.max(out, 1) _, pred = torch.max(out, 1)
num_correct = (pred == label).sum() num_correct = (pred == label).sum()
running_acc += num_correct.data[0] running_acc += num_correct.data[0]

# 向后传播 # 向后传播
optimizer.zero_grad() optimizer.zero_grad()
loss.backward() loss.backward()
@@ -75,12 +82,15 @@ for epoch in range(num_epoches):
print('[{}/{}] Loss: {:.6f}, Acc: {:.6f}'.format( print('[{}/{}] Loss: {:.6f}, Acc: {:.6f}'.format(
epoch + 1, num_epoches, running_loss / (batch_size * i), epoch + 1, num_epoches, running_loss / (batch_size * i),
running_acc / (batch_size * i))) running_acc / (batch_size * i)))

print('Finish {} epoch, Loss: {:.6f}, Acc: {:.6f}'.format( print('Finish {} epoch, Loss: {:.6f}, Acc: {:.6f}'.format(
epoch + 1, running_loss / (len(train_dataset)), running_acc / (len( epoch + 1, running_loss / (len(train_dataset)), running_acc / (len(
train_dataset)))) train_dataset))))

model.eval() model.eval()
eval_loss = 0. eval_loss = 0.
eval_acc = 0. eval_acc = 0.

for data in test_loader: for data in test_loader:
img, label = data img, label = data
img = img.view(img.size(0), -1) img = img.view(img.size(0), -1)
@@ -96,9 +106,10 @@ for epoch in range(num_epoches):
_, pred = torch.max(out, 1) _, pred = torch.max(out, 1)
num_correct = (pred == label).sum() num_correct = (pred == label).sum()
eval_acc += num_correct.data[0] eval_acc += num_correct.data[0]

print('Test Loss: {:.6f}, Acc: {:.6f}'.format(eval_loss / (len( print('Test Loss: {:.6f}, Acc: {:.6f}'.format(eval_loss / (len(
test_dataset)), eval_acc / (len(test_dataset)))) test_dataset)), eval_acc / (len(test_dataset))))
print() print()


# 保存模型 # 保存模型
torch.save(model.state_dict(), './neural_network.pth')
torch.save(model.state_dict(), './model_Neural_Network.pth')

Loading…
Cancel
Save