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