質問編集履歴

3

詳細なソースコードの追加

2021/08/27 07:31

投稿

mek_41
mek_41

スコア3

test CHANGED
File without changes
test CHANGED
@@ -1,40 +1,350 @@
1
+ 1.前提・実現したいこと
2
+
1
3
  python3でmain.pyでlossの計算をしており、その結果をresultに保存してvisual.pyでtSNEを用いて可視化するプログラムを作っています。
2
4
 
3
-
4
-
5
- 可視化した結果は
6
-
7
- plt.savefig("ファイル名.png")
8
-
9
- で保存しています。
10
-
11
-
12
-
13
- 今回はmain.pyで10000epoch学習させるですが、1000epoch毎にそれまでのlossの学習結果をvisual.pyで可視化してくれるプログラムが欲しいです。
14
-
15
-
16
-
17
- ①10000epoch学習し終わった後に1000epoch毎に可視化させていく
18
-
19
- ②10000epoch学習しているときに、1000epoch過ぎるごとに、visual.pyが実行されていく
20
-
21
-
22
-
23
- ①または②のような機能を実装したいのですがうまく書くことができません。
24
-
25
-
26
-
27
- 今は10000epochの学習が終わった後にvisual.pyを実行させて可視化しており、途中経過が見れなくて困っています。
28
-
29
-
30
-
31
-
32
-
33
- 出力結果ぼ表示と書き込みは以下のようにしています。
34
-
35
-
36
-
37
- ##### training & validation #####
5
+ main.pyで10000epoch学習させるのですが、1000epoch毎にlossの学習結果をvisual.pyで可視化してくれるプログラムを実装したいと考えています。
6
+
7
+
8
+
9
+ 2.発生している問題
10
+
11
+ 今は10000epochの学習が終わった後にvisual.pyを実行させて可視化し、plt.savefig("ファイル名.png")で保存しています5000epochなどの途中経過が見れなくて困っています。また、visual.pyを実行させ、可視化結果をvisual.pyが実行されるごとに名前を変えて保存がしたいです。
12
+
13
+
14
+
15
+ 3.該当ソースコード
16
+
17
+ ```main,py
18
+
19
+ ##### ライブラリ読み込み #####
20
+
21
+ ## 省略
22
+
23
+
24
+
25
+ ### dataloader##
26
+
27
+ ## 省略
28
+
29
+
30
+
31
+ ## train ##
32
+
33
+ def train(epoch):
34
+
35
+ model.train()
36
+
37
+
38
+
39
+ # 初期設定
40
+
41
+ sum_loss = 0
42
+
43
+ correct = 0
44
+
45
+ total = 0
46
+
47
+
48
+
49
+ # 学習ループ inputs:入力画像 targets:教師ラベル
50
+
51
+ for batch_idx, (inputs, targets) in enumerate(tqdm(train_loader, leave=False)):
52
+
53
+
54
+
55
+ inputs = inputs.cuda(device)
56
+
57
+ targets = targets.cuda(device)
58
+
59
+
60
+
61
+ targets = targets.long()
62
+
63
+
64
+
65
+ y,output = model(inputs)
66
+
67
+
68
+
69
+ loss = criterion(output, targets)
70
+
71
+
72
+
73
+ optimizer.zero_grad()
74
+
75
+
76
+
77
+ loss.backward()
78
+
79
+
80
+
81
+ optimizer.step()
82
+
83
+
84
+
85
+ sum_loss += loss.item()
86
+
87
+
88
+
89
+
90
+
91
+ ##精度の計算##
92
+
93
+ # 出力をsoftmax関数に(0~1)
94
+
95
+ output = F.softmax(y, dim=1)
96
+
97
+
98
+
99
+ # 最大ベクトル
100
+
101
+ _, predicted = output.max(1)
102
+
103
+
104
+
105
+ # total = 正解, correct = 予測
106
+
107
+ total += (targets.size(0)*targets.size(1)*targets.size(2))
108
+
109
+ correct += predicted.eq(targets).sum().item() #predicted.eq(targets)
110
+
111
+
112
+
113
+ return sum_loss/(batch_idx+1), correct/total
114
+
115
+
116
+
117
+
118
+
119
+
120
+
121
+ ## validation ##
122
+
123
+ def val(epoch):
124
+
125
+ model.eval()
126
+
127
+
128
+
129
+ sum_loss = 0
130
+
131
+ correct = 0
132
+
133
+ total = 0
134
+
135
+
136
+
137
+ # 設定:パラメータの更新なし
138
+
139
+ with torch.no_grad():
140
+
141
+ # 学習ループ inputs:入力画像 targets:教師ラベル画像
142
+
143
+ for batch_idx, (inputs, targets) in enumerate(tqdm(val_loader, leave=False)):
144
+
145
+ inputs = inputs.cuda(device)
146
+
147
+ targets = targets.cuda(device)
148
+
149
+
150
+
151
+ targets = targets.long()
152
+
153
+
154
+
155
+ y, output = model(inputs)
156
+
157
+
158
+
159
+ loss = criterion(output, targets)
160
+
161
+
162
+
163
+ sum_loss += loss.item()
164
+
165
+
166
+
167
+ ##精度の計算##
168
+
169
+
170
+
171
+ # 出力をsoftmax関数に(0~1)
172
+
173
+ output = F.softmax(y, dim=1)
174
+
175
+ # 最大ベクトル
176
+
177
+ _, predicted = output.max(1)
178
+
179
+ # total = 正解, correct = 予測
180
+
181
+ total += (targets.size(0)*targets.size(1)*targets.size(2))
182
+
183
+ correct += predicted.eq(targets).sum().item() #predicted.eq(targets) :
184
+
185
+ return sum_loss/(batch_idx+1), correct/total
186
+
187
+
188
+
189
+
190
+
191
+ ## main ##
192
+
193
+ if __name__ == '__main__':
194
+
195
+ parser = argparse.ArgumentParser(description='SemanticSegmentation')
196
+
197
+ parser.add_argument('--gpu', '-g', type=int, default=0,
198
+
199
+ help='GPU id')
200
+
201
+ parser.add_argument('--batchsize', '-b', type=int, default=4,
202
+
203
+ help='Number of images in each mini-batch')
204
+
205
+ parser.add_argument('--Tbatchsize', '-t', type=int, default=4,
206
+
207
+ help='Number of images in each mini-batch')
208
+
209
+ parser.add_argument('--num_epochs', '-e', type=int, default=65536,
210
+
211
+ help='Number of epoch')# 学習回数(epoch)指定
212
+
213
+ parser.add_argument('--out', '-o', type=str, default='result',
214
+
215
+ help='Directory to output the result')
216
+
217
+ parser.add_argument('--seed', '-s', type=int, default=0,
218
+
219
+ help='Random seed')
220
+
221
+ parser.add_argument('--lr', '-l', type=float, default=1e-3,
222
+
223
+ help='Learning rate')
224
+
225
+ args = parser.parse_args()
226
+
227
+
228
+
229
+ ## Covid-19 dataset ##
230
+
231
+ classes = 4
232
+
233
+ inputs_ch = 3
234
+
235
+
236
+
237
+
238
+
239
+ ## 初期設定表示 ##
240
+
241
+ print("[Experimental conditions]")
242
+
243
+ print(" GPU ID : {}".format(args.gpu))
244
+
245
+ print(" Epochs : {}".format(args.num_epochs))
246
+
247
+ print(" Minibatch size : {}".format(args.batchsize))
248
+
249
+ print(" Class number : {}".format(classes))
250
+
251
+ print(" Learning rate : {}".format(args.lr))
252
+
253
+ print("")
254
+
255
+
256
+
257
+
258
+
259
+ ## GPU設定 ##
260
+
261
+ device = torch.device('cuda:{}'.format(args.gpu) if torch.cuda.is_available() else 'cpu')
262
+
263
+
264
+
265
+
266
+
267
+ ## 保存ディレクトリ・ファイル ##
268
+
269
+
270
+
271
+ if not os.path.exists("{}".format(args.out)):
272
+
273
+ os.mkdir("{}".format(args.out))
274
+
275
+
276
+
277
+ PATH_1 = "{}/trainloss.txt".format(args.out)
278
+
279
+ PATH_2 = "{}/valloss.txt".format(args.out)
280
+
281
+ PATH_3 = "{}/trainaccuracy.txt".format(args.out)
282
+
283
+ PATH_4 = "{}/valaccuracy.txt".format(args.out)
284
+
285
+
286
+
287
+ with open(PATH_1, mode = 'w') as f:
288
+
289
+ pass
290
+
291
+ with open(PATH_2, mode = 'w') as f:
292
+
293
+ pass
294
+
295
+ with open(PATH_3, mode = 'w') as f:
296
+
297
+ pass
298
+
299
+ with open(PATH_4, mode = 'w') as f:
300
+
301
+ pass
302
+
303
+
304
+
305
+
306
+
307
+ # モデル設定
308
+
309
+ model = UNet(in_ch=inputs_ch, n_class=classes).cuda(device) #in_ch = input channel, n_class = output channel
310
+
311
+
312
+
313
+
314
+
315
+ # 損失関数設定
316
+
317
+ criterion = SquareLoss(device=device)
318
+
319
+
320
+
321
+ # オプティマイザー設定
322
+
323
+ optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)
324
+
325
+
326
+
327
+ # 初期値の乱数設定
328
+
329
+ random.seed(args.seed) #python
330
+
331
+ np.random.seed(args.seed) #numpy
332
+
333
+ torch.manual_seed(args.seed) #pytorch
334
+
335
+
336
+
337
+
338
+
339
+ # データ読み込み+初期設定
340
+
341
+ train_loader, val_loader = dataload()
342
+
343
+
344
+
345
+
346
+
347
+ ## training & validation ##
38
348
 
39
349
  best_loss = 1000
40
350
 
@@ -48,7 +358,7 @@
48
358
 
49
359
 
50
360
 
51
- ##### 結果表示 #####
361
+ ## 結果表示 ##
52
362
 
53
363
  print("Epoch{:3d}/{:3d} TrainLoss={:.4f} ValAccuracy={:.2f}%".format(epoch+1,args.num_epochs,train_loss,val_accuracy*100))
54
364
 
@@ -56,7 +366,7 @@
56
366
 
57
367
 
58
368
 
59
- ##### 出力結果書き込み #####
369
+ ## 出力結果書き込み ##
60
370
 
61
371
  with open(PATH_1, mode = 'a') as f:
62
372
 
@@ -84,14 +394,256 @@
84
394
 
85
395
  torch.save(model.state_dict(), PATH)
86
396
 
87
-
88
-
89
-     ##### 1000epochごとにplot #####
90
-
91
- if epoch % 1000==0:
92
-
93
- test(epoch=epoch+1)
94
-
95
-
96
-
97
- 1000epochごとにプロットするには以下のようにプログラムを足せばいいのはわかるのですが、1000epochごとに、visual.pyを実行するにはどうしたらいいでしょうか。
397
+ ```
398
+
399
+ ```visual_tSNE.py
400
+
401
+ from sklearn.manifold import TSNE
402
+
403
+ # 結果の可視化
404
+
405
+ import matplotlib.pyplot as plt
406
+
407
+
408
+
409
+ ##### ライブラリ読み込み #####
410
+
411
+ ## 省略
412
+
413
+
414
+
415
+
416
+
417
+ ## test関数 ##
418
+
419
+ def test():
420
+
421
+
422
+
423
+ model.eval()
424
+
425
+
426
+
427
+ correct = 0
428
+
429
+ total = 0
430
+
431
+ test_transform = transforms.Compose([transforms.ToTensor(), #0~1正規化+Tensor型に変換
432
+
433
+ transforms.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225]),
434
+
435
+ ])
436
+
437
+ # 画像はcovid-19のtest画像を利用
438
+
439
+ img = Image.open('Dataset/covid19/Image/test/img_100.png').convert('RGB')
440
+
441
+
442
+
443
+ # ラベル読み込み
444
+
445
+ L = Image.open('Dataset/covid19/Label/test/img_100.png').convert("L")
446
+
447
+ # 画像の正規化
448
+
449
+ inputs = test_transform(img)
450
+
451
+ to_tensor = transforms.ToTensor()
452
+
453
+ L = to_tensor(L) * 255
454
+
455
+
456
+
457
+
458
+
459
+ inputs = inputs.cuda(device).unsqueeze(0)
460
+
461
+ print(inputs.shape)
462
+
463
+
464
+
465
+ y,h = model(inputs)
466
+
467
+
468
+
469
+ y = F.softmax(y, dim=1)
470
+
471
+
472
+
473
+ _, predicted = y.max(1)
474
+
475
+
476
+
477
+ return predicted, h, L
478
+
479
+
480
+
481
+
482
+
483
+ class UNet(nn.Module):
484
+
485
+ # 初期設定
486
+
487
+ def __init__(self, in_ch=1, n_class=4):
488
+
489
+ super(UNet, self).__init__()
490
+
491
+ # Convolution Layer
492
+
493
+ ## 省略
494
+
495
+
496
+
497
+ def __call__(self, x):
498
+
499
+ # Block1 Encoder
500
+
501
+ # Block2 Encoder
502
+
503
+ # Block3 Encoder
504
+
505
+ # Block4 Middle
506
+
507
+ # Block5 Decoder
508
+
509
+ # Block6 Decoder
510
+
511
+ # Block7 Decoder
512
+
513
+ # discriminate
514
+
515
+ y = self.conv_f(h)
516
+
517
+
518
+
519
+ return y, h
520
+
521
+
522
+
523
+ ## GPU設定 ##
524
+
525
+ device = torch.device('cuda:0')
526
+
527
+
528
+
529
+ # モデル設定
530
+
531
+ model = UNet(in_ch=3, n_class=4).cuda(device)
532
+
533
+
534
+
535
+
536
+
537
+ # 学習済みモデルのロード
538
+
539
+ model_path = PATH ="result/model.pth"
540
+
541
+ model.load_state_dict(torch.load(model_path))
542
+
543
+
544
+
545
+ y, h , L = test()
546
+
547
+ print(L.shape)
548
+
549
+
550
+
551
+ y = y.view(y.size(1) * y.size(2)) # (W*Hのデータ数にする)
552
+
553
+ L = L.view(L.size(1) * L.size(2))
554
+
555
+ L = L.to(torch.int32) # float32 -> int32
556
+
557
+ #print(y.size())
558
+
559
+ y = y.tolist()
560
+
561
+ L = L.tolist()
562
+
563
+
564
+
565
+
566
+
567
+ h = h.view(1, h.size(1), h.size(2) * h.size(3))
568
+
569
+ h = h[0] # (h.size(1), W*H)
570
+
571
+ h = h.permute([1, 0]) # 次元を入れ替え(データ数, 次元)
572
+
573
+
574
+
575
+ X_test = h.to('cpu').detach().numpy().astype(np.float32) # tensor -> numpy
576
+
577
+
578
+
579
+ # 入力画像の確認
580
+
581
+ print(X_test.shape)
582
+
583
+ print(type(X_test))
584
+
585
+
586
+
587
+ # t-SNEの適応
588
+
589
+ # X_testにt-SNEを適応し、得られた低次元データをX_tsneに格納する
590
+
591
+ tsne = TSNE(n_components = 2) # 低次元データの次元数
592
+
593
+ X_tsne = tsne.fit_transform(X_test) # X_test : 入力画像とラベル
594
+
595
+
596
+
597
+ # t-SNEの可視化
598
+
599
+ colors = ['black', 'blue', 'green', 'red']
600
+
601
+ plt.xlim(X_tsne[:, 0].min(), X_tsne[:, 0].max() + 1)
602
+
603
+ plt.ylim(X_tsne[:, 1].min(), X_tsne[:, 1].max() + 1)
604
+
605
+
606
+
607
+ for color_index in range(len(colors)): # 黒青緑赤の順に描画
608
+
609
+ for i in range(len(X_test)):
610
+
611
+ if L[i] == color_index:
612
+
613
+ plt.text(
614
+
615
+ X_tsne[i, 0],
616
+
617
+ X_tsne[i, 1],
618
+
619
+ str(L[i]),
620
+
621
+ color = colors[L[i]]
622
+
623
+ )
624
+
625
+ plt.xlabel('t-SNE Feature1')
626
+
627
+ plt.ylabel('t-SNE Feature2')
628
+
629
+
630
+
631
+ plt.savefig(ファイル名.png")
632
+
633
+ ```
634
+
635
+ 4.自分で調べたこと
636
+
637
+ if epoch % 1000==0:
638
+
639
+ test(epoch=epoch+1)
640
+
641
+
642
+
643
+ 1000epochごとにプロットするには以下のようにを足せばいいのはわかるのですが、1000epochごとに、visual.pyを実行し、それぞれ名前を変えて保存するにはどうしたらいでしょうか。(例:1000epochの可視化結果 img1.png, 2000epochの可視化結果 img2.pngなど)
644
+
645
+
646
+
647
+ 5.使っているツール
648
+
649
+ python3

2

ソースコードの追加

2021/08/27 07:31

投稿

mek_41
mek_41

スコア3

test CHANGED
File without changes
test CHANGED
@@ -86,9 +86,9 @@
86
86
 
87
87
 
88
88
 
89
-     ##### 10epochごとにplot #####
89
+     ##### 1000epochごとにplot #####
90
90
 
91
- if epoch % 10==0:
91
+ if epoch % 1000==0:
92
92
 
93
93
  test(epoch=epoch+1)
94
94
 

1

ソースコードの追加

2021/08/24 05:25

投稿

mek_41
mek_41

スコア3

test CHANGED
File without changes
test CHANGED
@@ -20,8 +20,78 @@
20
20
 
21
21
 
22
22
 
23
- でもどちらパターンでも構わないです。
23
+ ①または②よう機能を実装したですがうまく書くことができません
24
24
 
25
25
 
26
26
 
27
27
  今は10000epochの学習が終わった後にvisual.pyを実行させて可視化しており、途中経過が見れなくて困っています。
28
+
29
+
30
+
31
+
32
+
33
+ 出力結果ぼ表示と書き込みは以下のようにしています。
34
+
35
+
36
+
37
+ ##### training & validation #####
38
+
39
+ best_loss = 1000
40
+
41
+ #args.num_epochs = max epoch
42
+
43
+ for epoch in range(args.num_epochs):
44
+
45
+ train_loss, train_accuracy = train(epoch) # train
46
+
47
+ val_loss, val_accuracy = val(epoch) # validation
48
+
49
+
50
+
51
+ ##### 結果表示 #####
52
+
53
+ print("Epoch{:3d}/{:3d} TrainLoss={:.4f} ValAccuracy={:.2f}%".format(epoch+1,args.num_epochs,train_loss,val_accuracy*100))
54
+
55
+
56
+
57
+
58
+
59
+ ##### 出力結果を書き込み #####
60
+
61
+ with open(PATH_1, mode = 'a') as f:
62
+
63
+ f.write("{}\t{:.2f}\n".format(epoch+1, train_loss))
64
+
65
+ with open(PATH_2, mode = 'a') as f:
66
+
67
+ f.write("{}\t{:.2f}\n".format(epoch+1, val_loss))
68
+
69
+ with open(PATH_3, mode = 'a') as f:
70
+
71
+ f.write("{}\t{:.2f}\n".format(epoch+1, (train_accuracy*100)))
72
+
73
+ with open(PATH_4, mode = 'a') as f:
74
+
75
+ f.write("{}\t{:.2f}\n".format(epoch+1, (val_accuracy)*100))
76
+
77
+
78
+
79
+ if train_loss <= best_loss:
80
+
81
+ best_loss = train_loss
82
+
83
+ PATH ="{}/model.pth".format(args.out)
84
+
85
+ torch.save(model.state_dict(), PATH)
86
+
87
+
88
+
89
+     ##### 10epochごとにplot #####
90
+
91
+ if epoch % 10==0:
92
+
93
+ test(epoch=epoch+1)
94
+
95
+
96
+
97
+ 1000epochごとにプロットするには以下のようにプログラムを足せばいいのはわかるのですが、1000epochごとに、visual.pyを実行するにはどうしたらいいでしょうか。