pytorchトレーニングデータおよびテストすべてのコード(4)
7775 ワード
前文に接する
この部分は補足すべきで、これまで補足すべきはモデルフレームワーク、tensorboardx、writerデータでの保存などの知識です
モデルパラメータのロード
10回ごとにepochは1回モデルパラメータを保存して、この方式は最適化することができます!!! torch.save(net.state_dict(), os.path.join(save_dir, 'models', modelName + '_epoch-' + str(epoch) + '.pth'))保存ファイル名はpthで終わる.net.state_dict()ここでちょっと質問がありますが、前から知っているnetとそのパラメータはすべてGPUの上にあります.このとき保存されている場所は明らかにローカルパスですが、なぜCPUに移行してから保存しないのですか.理由は関数state_かもしれませんdict()は既に処理するので不要である.
上は検証集の部分で、訓練のepochにも含まれています.
テストの時はnet.eval()と訓練の時はnet.を使います.train()は同じです
ここでは勾配を求める必要がないのでtorchを使用しています.no_grad()は、もちろんここで以下のコードに変更することもできますが、VariableのデフォルトはFalseです
torch.max関数の機能参照:https://blog.csdn.net/Z_lbj/article/details/79766690
predictionsの構造と数値はまだ明らかにされていないので,ネットワークの出力を理解してから知ることができる.
次は計算miouです.
utils.get_iou(predictions,labels)はbatchのmiouの関数を計算し、intersecは各種類の物体の予測とラベルが一致する数を保存し、unionは各種類の物体の数、すなわち総数を保存し、背景を物体に予測する画素や物体の数も含む可能性がある. unique_label = np.unique(gt_tmp.data.cpu().numpy()は、得られたラベル図に含まれる種類の数である.
上の文は、背景を物体と予測する画素や物体の数が計算に現れないことを保証しています.つまり、偽のラベルを削除します.したがってiouの大きさは21要素ではなく、大部分は21未満である可能性があります.また、ここで算出される各クラスiou=予測される真実ラベル数/真実ラベル数.
これがすべてのbatchで発生したmiouを合わせてtotal_を得ることですmiou:
完全部検証図画像を走るとき:
ここでii*testBatch+inputs.data.shape[0]=241*6+6=242*6=1452ですが、実際の総枚数は1449で、つまり最後のbatchは3枚の画像しかありません.
ここで得られたmiouは平均1枚あたりのiou値、running_loss_tsも1枚あたりの画像の損失を平均している.
最終的にすべてのepochが走り終わったら閉鎖します
# Show 10 * 3 images results each epoch
if ii % (num_img_tr // 10) == 0:
grid_image = make_grid(inputs[:3].clone().cpu().data, 3, normalize=True)
writer.add_image('Image', grid_image, global_step)
grid_image = make_grid(utils.decode_seg_map_sequence(torch.max(outputs[:3], 1)[1].detach().cpu().numpy()), 3, normalize=False,
range=(0, 255))
writer.add_image('Predicted label', grid_image, global_step)
grid_image = make_grid(utils.decode_seg_map_sequence(torch.squeeze(labels[:3], 1).detach().cpu().numpy()), 3, normalize=False, range=(0, 255))
writer.add_image('Groundtruth label', grid_image, global_step)
この部分は補足すべきで、これまで補足すべきはモデルフレームワーク、tensorboardx、writerデータでの保存などの知識です
# Save the model
if (epoch % snapshot) == snapshot - 1: # snapshot = 10
torch.save(net.state_dict(), os.path.join(save_dir, 'models', modelName + '_epoch-' + str(epoch) + '.pth'))
print("Save model at {}
".format(os.path.join(save_dir, 'models', modelName + '_epoch-' + str(epoch) + '.pth')))
net.load_state_dict(
torch.load(os.path.join(save_dir, 'models', modelName + '_epoch-' + str(resume_epoch - 1) + '.pth'),
map_location=lambda storage, loc: storage)) # Load all tensors onto the CPU
モデルパラメータのロード
10回ごとにepochは1回モデルパラメータを保存して、この方式は最適化することができます!!! torch.save(net.state_dict(), os.path.join(save_dir, 'models', modelName + '_epoch-' + str(epoch) + '.pth'))保存ファイル名はpthで終わる.net.state_dict()ここでちょっと質問がありますが、前から知っているnetとそのパラメータはすべてGPUの上にあります.このとき保存されている場所は明らかにローカルパスですが、なぜCPUに移行してから保存しないのですか.理由は関数state_かもしれませんdict()は既に処理するので不要である.
# One testing epoch
if useTest and epoch % nTestInterval == (nTestInterval - 1): # nTestInterval = 5
total_miou = 0.0
net.eval()
for ii, sample_batched in enumerate(testloader):
inputs, labels = sample_batched['image'], sample_batched['label']
# Forward pass of the mini-batch
inputs, labels = Variable(inputs, requires_grad=True), Variable(labels)
if gpu_id >= 0:
inputs, labels = inputs.cuda(), labels.cuda()
with torch.no_grad():
outputs = net.forward(inputs)
predictions = torch.max(outputs, 1)[1]
loss = criterion(outputs, labels, size_average=False, batch_average=True)
running_loss_ts += loss.item()
total_miou += utils.get_iou(predictions, labels)
# Print stuff
if ii % num_img_ts == num_img_ts - 1:
miou = total_miou / (ii * testBatch + inputs.data.shape[0])
running_loss_ts = running_loss_ts / num_img_ts
print('Validation:')
print('[Epoch: %d, numImages: %5d]' % (epoch, ii * testBatch + inputs.data.shape[0]))
writer.add_scalar('data/test_loss_epoch', running_loss_ts, epoch)
writer.add_scalar('data/test_miour', miou, epoch)
print('Loss: %f' % running_loss_ts)
print('MIoU: %f
' % miou)
running_loss_ts = 0
上は検証集の部分で、訓練のepochにも含まれています.
net.eval() #
# net
net.load_state_dict(
torch.load(os.path.join(save_dir, 'models', modelName + '_epoch-' + str(resume_epoch - 1) + '.pth'),
map_location=lambda storage, loc: storage))
net.cuda()
optimizer = optim.SGD(net.parameters(), lr=p['lr'], momentum=p['momentum'], weight_decay=p['wd'])
net.train()
net.forward(inputs)
torch.save(net.state_dict(), os.path.join(save_dir, 'models', modelName + '_epoch-' + str(epoch) + '.pth'))
テストの時はnet.eval()と訓練の時はnet.を使います.train()は同じです
# Forward pass of the mini-batch
inputs, labels = Variable(inputs, requires_grad=True), Variable(labels)
if gpu_id >= 0:
inputs, labels = inputs.cuda(), labels.cuda()
with torch.no_grad():
outputs = net.forward(inputs)
ここでは勾配を求める必要がないのでtorchを使用しています.no_grad()は、もちろんここで以下のコードに変更することもできますが、VariableのデフォルトはFalseです
# Forward pass of the mini-batch
inputs, labels = Variable(inputs, requires_grad=False), Variable(labels)
# or inputs, labels = Variable(inputs), Variable(labels)
if gpu_id >= 0:
inputs, labels = inputs.cuda(), labels.cuda()
outputs = net.forward(inputs)
predictions = torch.max(outputs, 1)[1]
torch.max関数の機能参照:https://blog.csdn.net/Z_lbj/article/details/79766690
predictionsの構造と数値はまだ明らかにされていないので,ネットワークの出力を理解してから知ることができる.
次は計算miouです.
total_miou += utils.get_iou(predictions, labels)
def get_iou(pred, gt, n_classes=21):
total_miou = 0.0
for i in range(len(pred)):
pred_tmp = pred[i]
gt_tmp = gt[i]
intersect = [0] * n_classes # *
# union=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
union = [0] * n_classes
for j in range(n_classes):
match = (pred_tmp == j) + (gt_tmp == j)
it = torch.sum(match == 2).item()
un = torch.sum(match > 0).item()
intersect[j] += it
union[j] += un
iou = []
unique_label = np.unique(gt_tmp.data.cpu().numpy())
for k in range(len(intersect)):
if k not in unique_label:
continue
iou.append(intersect[k] / union[k])
miou = (sum(iou) / len(iou))
total_miou += miou
return total_miou
utils.get_iou(predictions,labels)はbatchのmiouの関数を計算し、intersecは各種類の物体の予測とラベルが一致する数を保存し、unionは各種類の物体の数、すなわち総数を保存し、背景を物体に予測する画素や物体の数も含む可能性がある. unique_label = np.unique(gt_tmp.data.cpu().numpy()は、得られたラベル図に含まれる種類の数である.
if k not in unique_label:
continue
上の文は、背景を物体と予測する画素や物体の数が計算に現れないことを保証しています.つまり、偽のラベルを削除します.したがってiouの大きさは21要素ではなく、大部分は21未満である可能性があります.また、ここで算出される各クラスiou=予測される真実ラベル数/真実ラベル数.
これがすべてのbatchで発生したmiouを合わせてtotal_を得ることですmiou:
total_miou += utils.get_iou(predictions, labels)
# miou
完全部検証図画像を走るとき:
# Print stuff
if ii % num_img_ts == num_img_ts - 1:
miou = total_miou / (ii * testBatch + inputs.data.shape[0])
running_loss_ts = running_loss_ts / num_img_ts
print('Validation:')
print('[Epoch: %d, numImages: %5d]' % (epoch, ii * testBatch + inputs.data.shape[0]))
writer.add_scalar('data/test_loss_epoch', running_loss_ts, epoch)
writer.add_scalar('data/test_miour', miou, epoch)
print('Loss: %f' % running_loss_ts)
print('MIoU: %f
' % miou)
running_loss_ts = 0
ここでii*testBatch+inputs.data.shape[0]=241*6+6=242*6=1452ですが、実際の総枚数は1449で、つまり最後のbatchは3枚の画像しかありません.
ここで得られたmiouは平均1枚あたりのiou値、running_loss_tsも1枚あたりの画像の損失を平均している.
最終的にすべてのepochが走り終わったら閉鎖します
writer.close()