@@ -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)) |
@@ -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() |
@@ -6,9 +6,9 @@ from torch.utils.data import DataLoader | |||
from torchvision import transforms | |||
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 手写数字训练集 | |||
dataset_path = "../data/mnist" | |||
@@ -50,15 +50,21 @@ for epoch in range(num_epoches): | |||
print('*' * 10) | |||
running_loss = 0.0 | |||
running_acc = 0.0 | |||
for i, data in enumerate(train_loader, 1): | |||
# FIXME: label need to change one-hot coding | |||
img, label = data | |||
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(): | |||
img = Variable(img).cuda() | |||
label = Variable(label).cuda() | |||
else: | |||
img = Variable(img) | |||
label = Variable(label) | |||
# 向前传播 | |||
out = model(img) | |||
loss = criterion(out, label) | |||
@@ -66,6 +72,7 @@ for epoch in range(num_epoches): | |||
_, pred = torch.max(out, 1) | |||
num_correct = (pred == label).sum() | |||
running_acc += num_correct.data[0] | |||
# 向后传播 | |||
optimizer.zero_grad() | |||
loss.backward() | |||
@@ -75,12 +82,15 @@ for epoch in range(num_epoches): | |||
print('[{}/{}] Loss: {:.6f}, Acc: {:.6f}'.format( | |||
epoch + 1, num_epoches, running_loss / (batch_size * i), | |||
running_acc / (batch_size * i))) | |||
print('Finish {} epoch, Loss: {:.6f}, Acc: {:.6f}'.format( | |||
epoch + 1, running_loss / (len(train_dataset)), running_acc / (len( | |||
train_dataset)))) | |||
model.eval() | |||
eval_loss = 0. | |||
eval_acc = 0. | |||
for data in test_loader: | |||
img, label = data | |||
img = img.view(img.size(0), -1) | |||
@@ -96,9 +106,10 @@ for epoch in range(num_epoches): | |||
_, pred = torch.max(out, 1) | |||
num_correct = (pred == label).sum() | |||
eval_acc += num_correct.data[0] | |||
print('Test Loss: {:.6f}, Acc: {:.6f}'.format(eval_loss / (len( | |||
test_dataset)), eval_acc / (len(test_dataset)))) | |||
print() | |||
# 保存模型 | |||
torch.save(model.state_dict(), './neural_network.pth') | |||
torch.save(model.state_dict(), './model_Neural_Network.pth') |