Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

train_model_1.2.py 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. import torch
  2. import torchvision.models
  3. import sys
  4. import pandas as pd
  5. import os
  6. from datasetmaker import TrainDataClass, TestDataClass
  7. from torch.utils.data import Dataset, DataLoader
  8. from torchvision import transforms, datasets
  9. from torch import optim
  10. import torch.nn as nn
  11. import torch.nn.functional as F
  12. weight_dir_root = 'weights_backup'
  13. acc_dir_root = 'accs'
  14. '''
  15. filename:train_model_1.0.py
  16. create date: 11/17/2020 Tue
  17. Author: Jeong Geol Kim
  18. Contact: atarib4816@gmail.com
  19. Description: This .py file will train, save weight and save Results with parameters. parameters will input by .txt file.
  20. filename format: partofarchitecture_backbone_yymmdd.lcfg
  21. eg) shapesort_mobilenetv2_201118.txt
  22. '''
  23. def Read_Config(lcfg_name):
  24. '''
  25. Description: read options from .lcfg and initialize learning options.
  26. .lcfg file has 10 pramas: {role} {bbname} {dsversion} {dsname} {epoch} {batchsize} {optmizer} {learningloss} {lossfunction} {saveperiod}
  27. '''
  28. N_OF_PARAMS = 10
  29. dict_key = ['role', 'bbname', 'dsversion', 'dsname', 'epoch', 'batchsize', 'optimizer', 'learningloss', 'lossfunction', 'saveperiod']
  30. f = open(lcfg_name, 'r')
  31. p_string = f.readline()
  32. f.close()
  33. params = p_string.split()
  34. if len(params) != N_OF_PARAMS:
  35. print("Error: {} is broken. please check learning configures. Or you have to change constant N_OF_PARMAS.".format(lcfg_name))
  36. return
  37. else:
  38. print("----Learning Options----")
  39. print("Role of Classifier: {}".format(params[0]))
  40. print("Backbone Name: {}".format(params[1]))
  41. print("Dataset version: {}".format(params[2]))
  42. print("Dataset target: {}".format(params[3]))
  43. print("Number of iterations: {}".format(params[4]))
  44. print("Images per Batch: {}".format(params[5]))
  45. print("Optimizer Name: {}".format(params[6]))
  46. print("learning loss: {}".format(params[7]))
  47. print("Loss function Name: {}".format(params[8]))
  48. print("Period of saving weight: {}".format(params[9]))
  49. parmas_dictionary = dict(zip(dict_key, params))
  50. return parmas_dictionary
  51. def Preprocess(params, lcfg_name):
  52. dataset_root = os.path.join(os.getcwd(),'datasets',params['dsversion'],params['dsname'])
  53. classes = tuple(os.listdir(os.path.join(dataset_root,'train')))
  54. #NOTE: we don't have to transform because we already shrink raw images as same as MoblieNetV2's input size
  55. tsfm=transforms.Compose([
  56. transforms.ToTensor()
  57. ])
  58. train = TrainDataClass(dataset_root, tsfm)
  59. trainloader = DataLoader(train, batch_size=int(params['batchsize']), shuffle=True)
  60. test = TestDataClass(dataset_root, tsfm)
  61. testloader = DataLoader(test, batch_size=int(params['batchsize']), shuffle=True)
  62. return classes, trainloader, testloader
  63. def Model_Construct(params, lcfg_name):
  64. if params['bbname'] == 'moblienetv2':
  65. model = torch.hub.load('pytorch/vision', 'mobilenet_v2', pretrained=True)
  66. return model
  67. if params['bbname'] == 'resnet50':
  68. model = torch.hub.load('pytorch/vision', 'resnet50', pretrained=True)
  69. return model
  70. def Train(params, lcfg_name, model, trainLoader, testLoader, criterion, optimizer):
  71. params = params
  72. lcfg_name = lcfg_name
  73. model = model
  74. trainLoader = trainLoader
  75. criterion = criterion
  76. optimizer = optimizer
  77. weight_dir_root = 'weights_backup'
  78. acc_dir_root = 'accs'
  79. device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
  80. #print(torch.cuda.device_count())
  81. print(device)
  82. model = model.to(device)
  83. for epoch in range(int(params['epoch'])):
  84. running_loss = 0.0
  85. for i, data in enumerate(trainLoader, 0):
  86. # [inputs, labels]의 목록인 data로부터 입력을 받은 후;
  87. inputs, labels = data[0].to(device), data[1].to(device)
  88. # 변화도(Gradient) 매개변수를 0으로 만들고
  89. optimizer.zero_grad()
  90. # 순전파 + 역전파 + 최적화를 한 후
  91. outputs = model(inputs).to(device)
  92. loss = criterion(outputs, labels)
  93. loss.backward()
  94. optimizer.step()
  95. # 통계를 출력합니다.
  96. running_loss += loss.item()
  97. #print(i)
  98. if i % 50 == 49: # print every 50 mini-batches
  99. print('[%d, %5d] loss: %.3f' %
  100. (epoch + 1, i + 1, running_loss / 2000))
  101. running_loss = 0.0
  102. correct = 0
  103. total = 0
  104. with torch.no_grad():
  105. for data in testLoader:
  106. inputs, labels = data[0].to(device), data[1].to(device)
  107. outputs = model(inputs).to(device)
  108. _, predicted = torch.max(outputs.data, 1)
  109. total += labels.size(0)
  110. correct += (predicted == labels).sum().item()
  111. accuracy = (100 * correct / total)
  112. print('Accuracy: {0}'.format(accuracy))
  113. acc_name = os.path.join(os.getcwd(),acc_dir_root,lcfg_name + '.csv')
  114. weight_name = os.path.join(os.getcwd(), weight_dir_root,lcfg_name,params['role']+'_'+str(epoch+1)+'.pth')
  115. if epoch % int(params['saveperiod']) == (int(params['saveperiod']) - 1):
  116. params['savedat'] = epoch + 1
  117. params['accuracy'] = accuracy
  118. cols = params.keys()
  119. #NOTE: dictionary needs extend
  120. if not os.path.isfile(acc_name):
  121. df = pd.DataFrame(index = range(0), columns = cols)
  122. row = list(params.values())
  123. df = df.append(pd.Series(row, index=cols), ignore_index= True)
  124. df.to_csv(acc_name)
  125. else:
  126. df = pd.read_csv(acc_name, index_col = 0)
  127. row = list(params.values())
  128. df = df.append(pd.Series(row, index=cols), ignore_index= True)
  129. df.to_csv(acc_name)
  130. if not os.path.isfile(weight_name):
  131. torch.save(model.state_dict(),weight_name)
  132. #if epoch % int(params['saveperiod']) == (int(params['saveperiod']) - 1):
  133. # torch.save(model.state_dict(), os.path.join(os.getcwd(), weight_dir_root,lcfg_name))
  134. print('Finished Training')
  135. return model
  136. '''
  137. def Test(model, testLoader):
  138. correct = 0
  139. total = 0
  140. device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
  141. with torch.no_grad():
  142. for data in testLoader:
  143. inputs, labels = data[0].to(device), data[1].to(device)
  144. outputs = model(inputs).to(device)
  145. _, predicted = torch.max(outputs.data, 1)
  146. total += labels.size(0)
  147. correct += (predicted == labels).sum().item()
  148. accuracy = (100 * correct / total)
  149. print('Accuracy: {}'.format(accuracy))
  150. return accuracy
  151. '''
  152. def Save_Weight(params, lcfg_name):
  153. DEFAULT_DIR = 'weights_backup'
  154. pass
  155. def Save_Result(params, lcfg_name):
  156. DEFAULT_DIR = 'acc_save'
  157. result_file = os.path.join(os.getcwd(),DEFAULT_DIR,lcfg_name) + '.csv'
  158. if os.path.isfile(result_file):
  159. df = pd.read_csv(result_file)
  160. else:
  161. cols = ['backbone', 'dataset', 'epoch', 'batchsize', 'optimizer', 'learningloss', 'lossfunction', 'saveat', 'accuracy', 'precision', 'recall']
  162. #row = []
  163. df = pd.DataFrame(params, columns = cols)
  164. print(df)
  165. df.to_csv(result_file)
  166. pass
  167. def Set_Optimizer(params, model):
  168. if params['optimizer'] == 'RMSprop':
  169. optimizer = optim.RMSprop(model.parameters(), lr = float(params['learningloss']), momentum=0.9)
  170. return optimizer
  171. elif params['optimizer'] == 'SGD':
  172. optimizer = optim.SGD(model.parameters(), lr = float(params['learningloss']), momentum=0.9)
  173. return optimizer
  174. elif params['optimizer'] == 'Adam':
  175. optimizer = optim.Adam(model.parameters(), lr = float(params['learningloss']))
  176. return optimizer
  177. if __name__ == "__main__":
  178. for root, dirs, files in os.walk('.', topdown = True):
  179. for filename in files:
  180. if filename.endswith(('lcfg')):
  181. lcfg_path = os.path.join(root, filename)
  182. lcfg_name = os.path.splitext(filename)[0]
  183. params = Read_Config(lcfg_path)
  184. #print(params)
  185. if not os.path.exists(os.path.join(os.getcwd(),weight_dir_root,lcfg_name)):
  186. os.makedirs(os.path.join(os.getcwd(),weight_dir_root,lcfg_name), exist_ok=True)
  187. else:
  188. pass
  189. classes, trainLoader, testLoader = Preprocess(params, lcfg_name)
  190. #print(classes)
  191. model = Model_Construct(params, lcfg_name)
  192. #print(model.eval())
  193. if params['lossfunction'] == 'CrossEntropyLoss':
  194. criterion = nn.CrossEntropyLoss()
  195. else:
  196. criterion = nn.MultiLabelMarginLoss()
  197. optimizer = Set_Optimizer(params, model)
  198. model = Train(params, lcfg_name, model, trainLoader, testLoader, criterion, optimizer)
  199. else:
  200. pass