teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

13

追記

2021/01/18 13:20

投稿

daikooooooon
daikooooooon

スコア9

title CHANGED
File without changes
body CHANGED
@@ -193,4 +193,60 @@
193
193
  とすることで、ちゃんとtest用のtransformをするようになり、最初に書いていた1枚ずつ推論するコードとまったく同じ結果になりました
194
194
  seedを固定しないと結果が同じにならなかったのは、train用のtransformのRandom~等の影響だと思います
195
195
  また、test時には不要なtransformの処理もなくなり、少し早くなって1秒当たり3.9フレームほど処理できるようになり、2時間20分で推論できるようになりましたが、まだ1時間を切れていないので、さらに高速化できればまた追記します
196
- A_kirisakiさん、様々な助言を下さり、本当にありがとうございました。
196
+ A_kirisakiさん、様々な助言を下さり、本当にありがとうございました。
197
+ ・1/18
198
+ 画像の読み込み等をデータローダーで並列化し、1秒で6.5フレームほど処理でき、1時間20分で終わるようになりました
199
+ ```Python
200
+ キャッシュを使用してフレーム画像を取得するクラスを追加
201
+ class Frame:
202
+ def __init__(self, cap):
203
+ self.cap = cap
204
+
205
+ @lru_cache(maxsize=1) # キャッシュ
206
+ def __call__(self, frame_num):
207
+ # self.cap.set(cv2.CAP_PROP_POS_FRAMES, frame_num)
208
+ ret, frame = self.cap.read()
209
+ pil_frame = cv2pil(frame)
210
+ return pil_frame
211
+
212
+ Frameクラスに合わせて__getitem__を変更
213
+ class Dataset(data.Dataset):
214
+ def __init__(self, x, y, cap, num_frame, transform=None, phase="test"):
215
+ self.x = x
216
+ self.y = y
217
+ self.num_frame = num_frame
218
+ self.transform = transform
219
+ self.phase = phase
220
+ self.get_frame = Frame(cap)
221
+
222
+ def __len__(self):
223
+ return len(self.x) * len(self.y) * self.num_frame
224
+
225
+ def __getitem__(self, index):
226
+ frame_num = index // (len(self.x) * len(self.y)) # index // 8 * 8
227
+ i = (index - (frame_num * len(self.x) * len(self.y))) // len(self.x)
228
+ j = (index - (frame_num * len(self.x) * len(self.y))) % len(self.y)
229
+ self.frame = self.get_frame(frame_num)
230
+ cropped_img = self.frame.crop((int(self.x[i]), int(self.y[j]), int(self.x[i])+256, int(self.y[j])+256))
231
+ cropped_img = self.frame.crop((int(self.x[j]), int(self.y[i]), int(self.x[j])+256, int(self.y[i])+256))
232
+ cropped_img = self.transform(cropped_img, self.phase)
233
+ return cropped_img
234
+
235
+ Frameクラスのおかげで、1フレームずつ読み込んでそのたびにデータローダーを宣言する必要が無くなったので、推論部分を変更
236
+ train_dataset = Dataset(x, y, cap, num_frame, transform=Transform(resize, mean, std), phase="test")
237
+ train_dataloader = torch.utils.data.DataLoader(train_dataset, batch_size=64, num_workers=1, pin_memory=True) # num_workersは2にすると変なメッセージが出る上に、1と速度が大差ないので1
238
+
239
+ model.eval()
240
+ print("-------------")
241
+ print("推論開始")
242
+
243
+ #推論
244
+ with torch.no_grad():
245
+ for i, inputs in enumerate(tqdm(train_dataloader)):
246
+ if use_cuda:
247
+ inputs = inputs.cuda()
248
+ outputs = model(inputs)
249
+ prob_array[i] = softmax(outputs)[:, 1].to('cpu').detach().numpy().copy().reshape(len(x), len(y))
250
+ ```
251
+ 目標の50分まではまだ届いていませんが思いつくことは大体やったので、解決にしようと思います。
252
+ ありがとうございました。

12

追記

2021/01/18 13:20

投稿

daikooooooon
daikooooooon

スコア9

title CHANGED
File without changes
body CHANGED
@@ -192,4 +192,5 @@
192
192
  ```
193
193
  とすることで、ちゃんとtest用のtransformをするようになり、最初に書いていた1枚ずつ推論するコードとまったく同じ結果になりました
194
194
  seedを固定しないと結果が同じにならなかったのは、train用のtransformのRandom~等の影響だと思います
195
- また、test時には不要なtransformの処理もなくなり、少し早くなって1秒当たり3.9フレームほど処理できるようになり、2時間20分で推論できるようになりましたが、まだ1時間を切れていないので、さらに高速化できればまた追記します
195
+ また、test時には不要なtransformの処理もなくなり、少し早くなって1秒当たり3.9フレームほど処理できるようになり、2時間20分で推論できるようになりましたが、まだ1時間を切れていないので、さらに高速化できればまた追記します
196
+ A_kirisakiさん、様々な助言を下さり、本当にありがとうございました。

11

追記

2021/01/16 18:45

投稿

daikooooooon
daikooooooon

スコア9

title CHANGED
File without changes
body CHANGED
@@ -153,4 +153,43 @@
153
153
  ```
154
154
  ・1/8
155
155
  torch.manual_seed(1)とrandom.seed(1)を行うと推論結果が実行毎に同じになるようになりましたが、以前のように1枚ずつ推論していたときとは少し異なる結果となっています
156
- 1枚ずつ推論する方では、実行結果が毎回同じになっています
156
+ 1枚ずつ推論する方では、実行結果が毎回同じになっています
157
+ ・1/17
158
+ 解決しました!!
159
+ 私の初歩的なミスでした。申し訳ありません。
160
+ データ拡張のTransformを
161
+ ```Python
162
+ class Transform():
163
+ def __init__(self, resize, mean, std):
164
+ self.data_transform = {
165
+ "train": transforms.Compose([
166
+ #Histogram_Equalization(),
167
+ Luminance_Histogram_Equalization(),
168
+ transforms.RandomRotation((-20,20)),
169
+ transforms.RandomVerticalFlip(),
170
+ transforms.RandomHorizontalFlip(),
171
+ transforms.Resize(resize),
172
+ transforms.ToTensor(),
173
+ transforms.Normalize(mean, std)
174
+ ]),
175
+ "test": transforms.Compose([
176
+ #Histogram_Equalization(),
177
+ # Luminance_Histogram_Equalization(),
178
+ transforms.Resize(resize),
179
+ transforms.ToTensor(),
180
+ transforms.Normalize(mean, std)
181
+ ])
182
+ }
183
+
184
+ def __call__(self, img, phase="train"):
185
+ return self.data_transform[phase](img)
186
+ ```
187
+ というふうに、Transformのtrainとtestを辞書型にしていて、デフォルトでtrainの方を呼び出すようにしていたのが原因でした。
188
+ datasetのgetitemを変更し
189
+ ```Python
190
+ ✖ cropped_img = self.transform(cropped_img)
191
+ 〇 cropped_img = self.transform(cropped_img, self.phase)
192
+ ```
193
+ とすることで、ちゃんとtest用のtransformをするようになり、最初に書いていた1枚ずつ推論するコードとまったく同じ結果になりました
194
+ seedを固定しないと結果が同じにならなかったのは、train用のtransformのRandom~等の影響だと思います
195
+ また、test時には不要なtransformの処理もなくなり、少し早くなって1秒当たり3.9フレームほど処理できるようになり、2時間20分で推論できるようになりましたが、まだ1時間を切れていないので、さらに高速化できればまた追記します

10

追記

2021/01/16 18:43

投稿

daikooooooon
daikooooooon

スコア9

title CHANGED
File without changes
body CHANGED
@@ -150,4 +150,7 @@
150
150
  inputs = inputs.cuda()
151
151
  outputs = model(inputs)
152
152
  prob_array[i] = softmax(outputs)[:, 1].to('cpu').detach().numpy().copy().reshape(len(x), len(y)) #8×8にreshape
153
- ```
153
+ ```
154
+ ・1/8
155
+ torch.manual_seed(1)とrandom.seed(1)を行うと推論結果が実行毎に同じになるようになりましたが、以前のように1枚ずつ推論していたときとは少し異なる結果となっています
156
+ 1枚ずつ推論する方では、実行結果が毎回同じになっています

9

追記

2021/01/08 09:17

投稿

daikooooooon
daikooooooon

スコア9

title CHANGED
File without changes
body CHANGED
@@ -109,14 +109,45 @@
109
109
  #追記
110
110
  ・1/4
111
111
  cap.read()すると勝手に次のフレームに行くみたいなので、余計なcap.setをコメントアウトしたところ、実行時間が約1.3倍になり、7時間ほどで処理できるようになりました。
112
+ 30000フレームちょっとの動画の
113
+ read()に7分
114
+ cv2pilに8分
115
+ cropとtransformに30分
116
+ output = model(cropped_img_tensor)に約6時間
117
+ かかるようです。
112
118
  ```Python
113
119
  for i in tqdm(range(num_frame), position=0):
114
120
  #cap.set(cv2.CAP_PROP_POS_FRAMES, i+1)
115
121
  ret, frame = cap.read()
116
122
  ```
117
- 30000フレームちょっとの動画の
123
+ ・1/5
124
+ dataloaderを使用し、64枚一気に推論するように変更したところ、1秒で2.6フレームほど処理可能で、3時間ちょっとで処理できるようになりました。
125
+ しかし、以前の実装では大丈夫だったのですが、なぜか実行毎に推論結果が同じにならず、原因を調査中です。
126
+ ```Python
118
- read()に7分
127
+ getitemを変更
128
+ def __getitem__(self, index):
129
+ i = index // len(self.x)
130
+ j = index % len(self.y)
131
+ cropped_img = self.frame.crop((int(self.x[j]), int(self.y[i]), int(self.x[j])+256, int(self.y[i])+256))
132
+ cropped_img = self.transform(cropped_img)
133
+ return cropped_img
134
+
135
+ 推論部分を変更
136
+ for i in tqdm(range(num_frame), position=0):
137
+ ret, frame = cap.read()
138
+
119
- cv2pilに8分
139
+ if not ret:
140
+ break
141
+ else:
142
+ pil_frame = cv2pil(frame)
143
+
144
+ train_dataset = Dataset(x, y, pil_frame, transform=Transform(resize, mean, std), phase="test")
145
+ train_dataloader = torch.utils.data.DataLoader(train_dataset, batch_size=64, num_workers=2, pin_memory=True)
146
+
120
- cropとtransformに30分
147
+ with torch.no_grad():
148
+ for inputs in train_dataloader:
149
+ if use_cuda:
150
+ inputs = inputs.cuda()
121
- output = model(cropped_img_tensor)に約6時間
151
+ outputs = model(inputs)
152
+ prob_array[i] = softmax(outputs)[:, 1].to('cpu').detach().numpy().copy().reshape(len(x), len(y)) #8×8にreshape
122
- かかるようです。
153
+ ```

8

追記

2021/01/05 06:20

投稿

daikooooooon
daikooooooon

スコア9

title CHANGED
File without changes
body CHANGED
@@ -106,7 +106,7 @@
106
106
 
107
107
 
108
108
 
109
- 追記
109
+ #追記
110
110
  ・1/4
111
111
  cap.read()すると勝手に次のフレームに行くみたいなので、余計なcap.setをコメントアウトしたところ、実行時間が約1.3倍になり、7時間ほどで処理できるようになりました。
112
112
  ```Python
@@ -114,4 +114,9 @@
114
114
  #cap.set(cv2.CAP_PROP_POS_FRAMES, i+1)
115
115
  ret, frame = cap.read()
116
116
  ```
117
+ 30000フレームちょっとの動画の
118
+ read()に7分
119
+ cv2pilに8分
120
+ cropとtransformに30分
117
- 約3万フレームの動画のread()に7分、cv2pilに8分かかるようです。
121
+ output = model(cropped_img_tensor)に約6時間
122
+ かかるようです。

7

修正

2021/01/04 14:59

投稿

daikooooooon
daikooooooon

スコア9

title CHANGED
File without changes
body CHANGED
@@ -6,6 +6,7 @@
6
6
  ⑤出力した確率を、配列の対応する場所に格納
7
7
  ⑥③へ
8
8
  という単純な実装で、処理時間が1フレームあたり約1秒かかり、とても遅いです。
9
+ 処理したい動画は30000フレームちょっとあり、10時間ほどかかります。
9
10
  0.1秒ほどで処理するのが理想で、高速化のためいくつか思いついたことを試したのですが上手くいきません。
10
11
  高速化する良い方法がありましたら教えていただきたいです
11
12
  ```Python
@@ -107,9 +108,10 @@
107
108
 
108
109
  追記
109
110
  ・1/4
110
- cap.read()すると勝手に次のフレームに行くみたいなので、余計なcap.setをコメントアウトしたところ、実行時間が約1.3倍になりました
111
+ cap.read()すると勝手に次のフレームに行くみたいなので、余計なcap.setをコメントアウトしたところ、実行時間が約1.3倍になり、7時間ほどで処理できるようになりました
111
112
  ```Python
112
113
  for i in tqdm(range(num_frame), position=0):
113
114
  #cap.set(cv2.CAP_PROP_POS_FRAMES, i+1)
114
115
  ret, frame = cap.read()
115
- ```
116
+ ```
117
+ 約3万フレームの動画のread()に7分、cv2pilに8分かかるようです。

6

追記

2021/01/04 14:52

投稿

daikooooooon
daikooooooon

スコア9

title CHANGED
File without changes
body CHANGED
@@ -101,4 +101,15 @@
101
101
 
102
102
  これはVGG16で実行したときの時間です
103
103
  32762はフレーム数です
104
- 一番時間がかかるのは推論だと思うのですが、なぜかモデルをMobileNet_v2にしてもほとんど実行時間は変わりませんでした
104
+ 一番時間がかかるのは推論だと思うのですが、なぜかモデルをMobileNet_v2にしてもほとんど実行時間は変わりませんでした
105
+
106
+
107
+
108
+ 追記
109
+ ・1/4
110
+ cap.read()すると勝手に次のフレームに行くみたいなので、余計なcap.setをコメントアウトしたところ、実行時間が約1.3倍になりました
111
+ ```Python
112
+ for i in tqdm(range(num_frame), position=0):
113
+ #cap.set(cv2.CAP_PROP_POS_FRAMES, i+1)
114
+ ret, frame = cap.read()
115
+ ```

5

誤字

2021/01/04 14:33

投稿

daikooooooon
daikooooooon

スコア9

title CHANGED
File without changes
body CHANGED
@@ -60,31 +60,40 @@
60
60
  print(c-b)
61
61
  print(d-c)
62
62
  ```
63
- 0%| | 0/32762 [00:00<?, ?it/s]0.05161237716674805
63
+ 0%| | 0/32762 [00:00<?, ?it/s]
64
+ 0.05161237716674805
64
65
  0.017586469650268555
65
66
  2.1721038818359375
66
- 0%| | 1/32762 [00:02<20:23:48, 2.24s/it]0.044759511947631836
67
+ 0%| | 1/32762 [00:02<20:23:48, 2.24s/it]
68
+ 0.044759511947631836
67
69
  0.016994237899780273
68
70
  0.6606061458587646
69
- 0%| | 2/32762 [00:02<16:14:59, 1.79s/it]0.056168556213378906
71
+ 0%| | 2/32762 [00:02<16:14:59, 1.79s/it]
72
+ 0.056168556213378906
70
73
  0.016913175582885742
71
74
  0.6579580307006836
72
- 0%| | 3/32762 [00:03<13:22:14, 1.47s/it]0.06777358055114746
75
+ 0%| | 3/32762 [00:03<13:22:14, 1.47s/it]
76
+ 0.06777358055114746
73
77
  0.01434183120727539
74
78
  0.6527915000915527
75
- 0%| | 4/32762 [00:04<11:21:56, 1.25s/it]0.07939982414245605
79
+ 0%| | 4/32762 [00:04<11:21:56, 1.25s/it]
80
+ 0.07939982414245605
76
81
  0.014380693435668945
77
82
  0.6701173782348633
78
- 0%| | 5/32762 [00:05<10:02:29, 1.10s/it]0.09820103645324707
83
+ 0%| | 5/32762 [00:05<10:02:29, 1.10s/it]
84
+ 0.09820103645324707
79
85
  0.014620542526245117
80
86
  0.6635544300079346
81
- 0%| | 6/32762 [00:05<9:08:54, 1.01s/it]0.10292172431945801
87
+ 0%| | 6/32762 [00:05<9:08:54, 1.01s/it]
88
+ 0.10292172431945801
82
89
  0.015182971954345703
83
90
  0.6512439250946045
84
- 0%| | 7/32762 [00:06<8:30:15, 1.07it/s]0.11549758911132812
91
+ 0%| | 7/32762 [00:06<8:30:15, 1.07it/s]
92
+ 0.11549758911132812
85
93
  0.01836109161376953
86
94
  0.649014949798584
87
- 0%| | 8/32762 [00:07<8:05:24, 1.12it/s]0.13360857963562012
95
+ 0%| | 8/32762 [00:07<8:05:24, 1.12it/s]
96
+ 0.13360857963562012
88
97
  0.016347885131835938
89
98
  0.6655523777008057
90
99
 

4

計測結果の修正

2020/12/30 15:15

投稿

daikooooooon
daikooooooon

スコア9

title CHANGED
File without changes
body CHANGED
@@ -60,25 +60,33 @@
60
60
  print(c-b)
61
61
  print(d-c)
62
62
  ```
63
- 0%| | 0/32762 [00:00<?, ?it/s]
63
+ 0%| | 0/32762 [00:00<?, ?it/s]0.05161237716674805
64
- 0.0496668815612793
65
- 0.017401933670043945
64
+ 0.017586469650268555
66
- 2.247164726257324
65
+ 2.1721038818359375
67
- 0%| | 1/32762 [00:02<21:03:37, 2.31s/it]
66
+ 0%| | 1/32762 [00:02<20:23:48, 2.24s/it]0.044759511947631836
68
- 0.05923867225646973
67
+ 0.016994237899780273
69
- 0.016553640365600586
68
+ 0.6606061458587646
70
- 0.6884787082672119
71
- 0%| | 2/32762 [00:03<16:49:43, 1.85s/it]
69
+ 0%| | 2/32762 [00:02<16:14:59, 1.79s/it]0.056168556213378906
70
+ 0.016913175582885742
72
- 0.05535531044006348
71
+ 0.6579580307006836
73
- 0.014247894287109375
74
- 0.708582878112793
75
- 0%| | 3/32762 [00:03<13:54:16, 1.53s/it]
72
+ 0%| | 3/32762 [00:03<13:22:14, 1.47s/it]0.06777358055114746
76
- 0.06719350814819336
73
+ 0.01434183120727539
77
- 0.01429295539855957
74
+ 0.6527915000915527
78
- 0.6995298862457275
79
- 0%| | 4/32762 [00:04<11:51:55, 1.30s/it]
75
+ 0%| | 4/32762 [00:04<11:21:56, 1.25s/it]0.07939982414245605
76
+ 0.014380693435668945
77
+ 0.6701173782348633
78
+ 0%| | 5/32762 [00:05<10:02:29, 1.10s/it]0.09820103645324707
79
+ 0.014620542526245117
80
+ 0.6635544300079346
81
+ 0%| | 6/32762 [00:05<9:08:54, 1.01s/it]0.10292172431945801
82
+ 0.015182971954345703
80
- 0.07828927040100098
83
+ 0.6512439250946045
84
+ 0%| | 7/32762 [00:06<8:30:15, 1.07it/s]0.11549758911132812
85
+ 0.01836109161376953
86
+ 0.649014949798584
87
+ 0%| | 8/32762 [00:07<8:05:24, 1.12it/s]0.13360857963562012
81
- 0.015504837036132812
88
+ 0.016347885131835938
89
+ 0.6655523777008057
82
90
 
83
91
 
84
92
 

3

誤字

2020/12/30 15:08

投稿

daikooooooon
daikooooooon

スコア9

title CHANGED
File without changes
body CHANGED
@@ -52,8 +52,8 @@
52
52
  cropped_img_tensor = transform(cropped_img, phase="test").unsqueeze(0) #transformしたあと、推論するためバッチの次元を追加
53
53
 
54
54
  output = model(cropped_img_tensor)
55
- bag_prob = softmax(output)[0][1].item() #softmaxを計算
55
+ prob = softmax(output)[0][1].item() #softmaxを計算
56
- prob_array[i][k][j] = bag_prob
56
+ prob_array[i][k][j] = prob
57
57
 
58
58
  d = time.time() ##############################
59
59
  print(b-a)

2

32762がフレーム数であることを追記

2020/12/30 15:06

投稿

daikooooooon
daikooooooon

スコア9

title CHANGED
File without changes
body CHANGED
@@ -83,4 +83,5 @@
83
83
 
84
84
 
85
85
  これはVGG16で実行したときの時間です
86
+ 32762はフレーム数です
86
87
  一番時間がかかるのは推論だと思うのですが、なぜかモデルをMobileNet_v2にしてもほとんど実行時間は変わりませんでした

1

実行時間計測結果の追加

2020/12/30 15:01

投稿

daikooooooon
daikooooooon

スコア9

title CHANGED
File without changes
body CHANGED
@@ -28,4 +28,59 @@
28
28
  output = model(cropped_img_tensor)
29
29
  prob = softmax(output)[0][1].item() #softmaxを計算
30
30
  prob_array[i][k][j] = prob
31
- ```
31
+ ```
32
+
33
+ ↓実行時間計測
34
+ ```Python
35
+ for i in tqdm(range(num_frame), position=0):
36
+ a = time.time() ###############################
37
+ cap.set(cv2.CAP_PROP_POS_FRAMES, i+1)
38
+ ret, frame = cap.read()
39
+ b = time.time()############################
40
+
41
+ if not ret:
42
+ break
43
+ else:
44
+ pil_frame = cv2pil(frame)
45
+
46
+ c = time.time() #######################
47
+
48
+ with torch.no_grad():
49
+ for j in range(len(x)):
50
+ for k in range(len(y)):
51
+ cropped_img = pil_frame.crop((int(x[j]), int(y[k]), int(x[j])+256, int(y[k])+256))
52
+ cropped_img_tensor = transform(cropped_img, phase="test").unsqueeze(0) #transformしたあと、推論するためバッチの次元を追加
53
+
54
+ output = model(cropped_img_tensor)
55
+ bag_prob = softmax(output)[0][1].item() #softmaxを計算
56
+ prob_array[i][k][j] = bag_prob
57
+
58
+ d = time.time() ##############################
59
+ print(b-a)
60
+ print(c-b)
61
+ print(d-c)
62
+ ```
63
+ 0%| | 0/32762 [00:00<?, ?it/s]
64
+ 0.0496668815612793
65
+ 0.017401933670043945
66
+ 2.247164726257324
67
+ 0%| | 1/32762 [00:02<21:03:37, 2.31s/it]
68
+ 0.05923867225646973
69
+ 0.016553640365600586
70
+ 0.6884787082672119
71
+ 0%| | 2/32762 [00:03<16:49:43, 1.85s/it]
72
+ 0.05535531044006348
73
+ 0.014247894287109375
74
+ 0.708582878112793
75
+ 0%| | 3/32762 [00:03<13:54:16, 1.53s/it]
76
+ 0.06719350814819336
77
+ 0.01429295539855957
78
+ 0.6995298862457275
79
+ 0%| | 4/32762 [00:04<11:51:55, 1.30s/it]
80
+ 0.07828927040100098
81
+ 0.015504837036132812
82
+
83
+
84
+
85
+ これはVGG16で実行したときの時間です
86
+ 一番時間がかかるのは推論だと思うのですが、なぜかモデルをMobileNet_v2にしてもほとんど実行時間は変わりませんでした