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