当前位置:   article > 正文

基于Pytorch的面向对象的深度学习项目编码规范_深度学习编码规范

深度学习编码规范

参考:

编程进阶之路:用简单的面向对象编程提升深度学习原型

深度学习过程编程实现的面向对象思考

 

(1/4)首先明确一个思考方式:

一切皆是对象一切我的理解是包括两类

  • 对象
  • 非对象

(2/4)为什么要有对象?

对象不用说了,就是一些名词,比如:模型,算法,数据(训练集,测试集),设备,等。
非对象肯定是包括过程的,过程怎么变为对象呢?或者说,“过程怎么被赋予对象的一些属性呢?”
如何赋予过程一些东西,这些东西使过程看起来像是对象,那么就要分析以下正常的对象有哪些属性,或者说是特点。
在创建一个对象时,首先要有他所属的类,类相当于一个命名空间,对象在此基础上扩展,类可以有自己的属性,这些属性是每个对象(由此类生出)共有的。类里面定义一些方法,类和对象都可以访问。这两种东西(类属性,类方法)都是属于类的,如果面向对象的设计就到这里,那么这个“类”和普通方法没什么区别,因为这个“类‘的对象(即使能够被创建)不具有扩展性。我认为的扩展性就是对象的方法和属性可以在对象诞生后增删改。既然可以通过对象增删改,那么就必须通过对象,但是在创建类的时候,对象还没有出生啊!!,怎么办呢?就要定义一个代指未来对象的东西,python中是self关键字,java中是this关键字。所以在定义类时,只要是希望仅仅属于对象的东西(属性)那么就要加上这种代指对象的关键字。

(3/4)那么过程该怎么对象化呢?

一个过程应该有明确步骤,而每一步需要操作的东西就是该过程对应类的某些属性。

(4/4)深度学习过程编程实现的面向对象

对象

  • 模型
  1. class Net(nn.Module):
  2. def __init__(self):
  3. super(Net, self).__init__()
  4. self.fc = nn.Linear(784, 10)
  5. def forward(self, x):
  6. return self.fc(x.view(x.size(0), -1))
  • 优化算法
 optimizer = torch.optim.Adam(model.parameters(), lr=args.learning_rate)
  • 数据加载
  1. class MNISTDataLoader(data.DataLoader):
  2. def __init__(self, root, batch_size, train=True):
  3. transform = transforms.Compose([
  4. transforms.ToTensor(),
  5. transforms.Normalize((0.1307,), (0.3081,)),
  6. ])
  7. dataset = datasets.MNIST(root, train=train, transform=transform, download=True)
  8. sampler = None
  9. if train and distributed_is_initialized():
  10. sampler = data.DistributedSampler(dataset)
  11. super(MNISTDataLoader, self).__init__(
  12. dataset,
  13. batch_size=batch_size,
  14. shuffle=(sampler is None),
  15. sampler=sampler,
  16. )
  • 设备
device = torch.device('cuda' if torch.cuda.is_available() and not args.no_cuda else 'cpu')
  • 错误率
  1. class Average(object):
  2. def __init__(self):
  3. self.sum = 0
  4. self.count = 0
  5. def __str__(self):
  6. return '{:.6f}'.format(self.average)
  7. @property
  8. def average(self):
  9. return self.sum / self.count
  10. def update(self, value, number):
  11. self.sum += value * number
  12. self.count += number
  • 准确率
  1. class Accuracy(object):
  2. def __init__(self):
  3. self.correct = 0
  4. self.count = 0
  5. def __str__(self):
  6. return '{:.2f}%'.format(self.accuracy * 100)
  7. @property
  8. def accuracy(self):
  9. return self.correct / self.count
  10. def update(self, output, target):
  11. with torch.no_grad():
  12. pred = output.argmax(dim=1)
  13. self.correct += correct
  14. self.count += output.size(0)

过程

  • 训练和测试
  1. class Trainer(object):
  2. def __init__(self, model, optimizer, train_loader, test_loader, device):
  3. self.model = model
  4. self.optimizer = optimizer
  5. self.train_loader = train_loader
  6. self.test_loader = test_loader
  7. self.device = device
  8. def fit(self, epochs):
  9. for epoch in range(1, epochs + 1):
  10. train_loss, train_acc = self.train()
  11. test_loss, test_acc = self.evaluate()
  12. print(
  13. 'Epoch: {}/{},'.format(epoch, epochs),
  14. 'train loss: {}, train acc: {},'.format(train_loss, train_acc),
  15. 'test loss: {}, test acc: {}.'.format(test_loss, test_acc),
  16. )
  17. def train(self):
  18. self.model.train()
  19. train_loss = Average()
  20. train_acc = Accuracy()
  21. for data, target in self.train_loader:
  22. data = data.to(self.device)
  23. target = target.to(self.device)
  24. output = self.model(data)
  25. loss = F.cross_entropy(output, target)
  26. self.optimizer.zero_grad()
  27. loss.backward()
  28. self.optimizer.step()
  29. train_loss.update(loss.item(), data.size(0))
  30. train_acc.update(output, target)
  31. return train_loss, train_acc
  32. def evaluate(self):
  33. self.model.eval()
  34. test_loss = Average()
  35. test_acc = Accuracy()
  36. with torch.no_grad():
  37. for data, target in self.test_loader:
  38. data = data.to(self.device)
  39. target = target.to(self.device)
  40. output = self.model(data)
  41. loss = F.cross_entropy(output, target)
  42. test_loss.update(loss.item(), data.size(0))
  43. test_acc.update(output, target)
  44. return test_loss, test_acc
  • 运行
  1. def run(args):
  2. device = torch.device('cuda' if torch.cuda.is_available() and not args.no_cuda else 'cpu')
  3. model = Net()
  4. if distributed_is_initialized():
  5. model.to(device)
  6. model = nn.parallel.DistributedDataParallel(model)
  7. else:
  8. model = nn.DataParallel(model)
  9. model.to(device)
  10. optimizer = torch.optim.Adam(model.parameters(), lr=args.learning_rate)
  11. train_loader = MNISTDataLoader(args.root, args.batch_size, train=True)
  12. test_loader = MNISTDataLoader(args.root, args.batch_size, train=False)
  13. trainer = Trainer(model, optimizer, train_loader, test_loader, device)
  14. trainer.fit(args.epochs)

主函数

  1. def main():
  2. parser = argparse.ArgumentParser()
  3. parser.add_argument('--backend', type=str, default='gloo', help='Name of the backend to use.')
  4. parser.add_argument(
  5. '-i',
  6. '--init-method',
  7. type=str,
  8. default='tcp://127.0.0.1:23456',
  9. help='URL specifying how to initialize the package.')
  10. parser.add_argument('-s', '--world-size', type=int, default=1, help='Number of processes participating in the job.')
  11. parser.add_argument('-r', '--rank', type=int, default=0, help='Rank of the current process.')
  12. parser.add_argument('--epochs', type=int, default=20)
  13. parser.add_argument('--no-cuda', action='store_true')
  14. parser.add_argument('-lr', '--learning-rate', type=float, default=1e-3)
  15. parser.add_argument('--root', type=str, default='data')
  16. parser.add_argument('--batch-size', type=int, default=128)
  17. args = parser.parse_args()
  18. print(args)
  19. if args.world_size > 1:
  20. distributed.init_process_group(
  21. backend=args.backend,
  22. init_method=args.init_method,
  23. world_size=args.world_size,
  24. rank=args.rank,
  25. )
  26. run(args)
  27. if __name__ == '__main__':
  28. main()

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/345402
推荐阅读
相关标签
  

闽ICP备14008679号