@@ -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 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') |