質問編集履歴

2

resnet101のファインチューニングを行ったコード追加、参考にさせていただいたサイトのURLを追加。

2020/11/29 00:20

投稿

tomomina
tomomina

スコア0

test CHANGED
File without changes
test CHANGED
@@ -1,6 +1,18 @@
1
1
  Pythonを使って深層学習を勉強している初心者です。
2
2
 
3
- resnet101を用いて、ファインチューニングを行いたいと考えています。前処理として、手元にある画像サイズ640×480を、画像サイズ、224×224に変更する必要があります。画像は、音をスペクトログラムにしたものです。そのため、横軸に時間、縦軸に周波数、色は信号の強さを表しており、リサイズを行った場合、画像にある情報が潰れてしまいます。これを避けるために、前処理で画像サイズを変更しない方法や画像にある情報を潰さずに済む方法がありましたら、教えていただけると助かります。
3
+
4
+
5
+ resnet101を用いて、ファインチューニングを行いたいと考えています。(resnet101の方は、torchvision で提供されている学習済みのモデルを使用しております。)前処理として、手元にある画像サイズ640×480を、画像サイズ、224×224に変更する必要があります。画像は、音をスペクトログラムにしたものです。そのため、横軸に時間、縦軸に周波数、色は信号の強さを表しており、リサイズを行った場合、画像にある情報が潰れてしまいます。これを避けるために、前処理で画像サイズを変更しない方法や画像にある情報を潰さずに済む方法がありましたら、教えていただけると助かります。
6
+
7
+
8
+
9
+
10
+
11
+ 参考させていただいたサイト: https://blog.brainpad.co.jp/entry/2018/04/17/143000
12
+
13
+
14
+
15
+
4
16
 
5
17
  スペクトログラム
6
18
 
@@ -158,4 +170,174 @@
158
170
 
159
171
 
160
172
 
173
+
174
+
175
+
176
+
177
+
178
+
179
+
180
+
181
+ #resnet101を用いたファインチューニング
182
+
183
+
184
+
185
+ use_pretrained = True # 学習済みのパラメータを使用
186
+
187
+ net = models.resnet101(pretrained=use_pretrained)
188
+
189
+
190
+
191
+
192
+
193
+ net.fc = nn.Linear(in_features=2048, out_features=10)
194
+
195
+ print(net)
196
+
197
+ # 訓練モードに設定
198
+
199
+ net.train()
200
+
201
+
202
+
203
+ print('ネットワーク設定完了:学習済みの重みをロードし、訓練モードに設定しました')
204
+
205
+
206
+
207
+
208
+
209
+ # 損失関数の設定
210
+
211
+ criterion = nn.CrossEntropyLoss()
212
+
213
+
214
+
215
+
216
+
217
+ # ファインチューニングで学習させるパラメータを、変数params_to_updateの1~3に格納する
218
+
219
+
220
+
221
+ params_to_update_1 = []
222
+
223
+ params_to_update_2 = []
224
+
225
+ params_to_update_3 = []
226
+
227
+
228
+
229
+ # 学習させる層のパラメータ名を指定
230
+
231
+ update_param_names_1 = ["layer"]
232
+
233
+ update_param_names_2 = ["downsample"]
234
+
235
+ update_param_names_3 = ["fc.weight", "fc.bias"]
236
+
237
+ update_param_names_4 = ["bn"]
238
+
239
+ update_param_names_5 = ["downsample.1.weight"]
240
+
241
+ update_param_names_6 = ["conv1.weight"]
242
+
243
+ update_param_names_7 = ["bn1.weight","bn1.bias"]
244
+
245
+
246
+
247
+ # パラメータごとに各リストに格納する
248
+
249
+ for name, param in net.named_parameters():
250
+
251
+ print(name)
252
+
253
+ if update_param_names_1[0] in name:# layer:conv
254
+
255
+ if update_param_names_2[0] in name:# downsample:conv
256
+
257
+ param.requires_grad = False
258
+
259
+ print("勾配計算なし。学習しない:", name)
260
+
261
+ else:
262
+
263
+ param.requires_grad = True
264
+
265
+ params_to_update_1.append(param)
266
+
267
+ print("params_to_update_1に格納:", name)
268
+
269
+
270
+
271
+ elif name in update_param_names_6:
272
+
273
+ param.requires_grad = True
274
+
275
+ params_to_update_2.append(param)
276
+
277
+ print("params_to_update_2に格納:", name)
278
+
279
+
280
+
281
+ elif name in update_param_names_7:
282
+
283
+ param.requires_grad = True
284
+
285
+ params_to_update_2.append(param)
286
+
287
+ print("params_to_update_2に格納:", name)
288
+
289
+
290
+
291
+
292
+
293
+ elif name in update_param_names_3:# fc:conv
294
+
295
+ param.requires_grad = True
296
+
297
+ params_to_update_3.append(param)
298
+
299
+ print("params_to_update_3に格納:", name)
300
+
301
+
302
+
303
+ elif name in update_param_names_4:
304
+
305
+ param.requires_grad = False
306
+
307
+ print("bn: 勾配計算なし。学習しない:", name)
308
+
309
+
310
+
311
+
312
+
313
+ else:
314
+
315
+ param.requires_grad = False
316
+
317
+ print("勾配計算なし。学習しない:", name)
318
+
319
+
320
+
321
+
322
+
323
+
324
+
325
+ # 最適化手法の設定
326
+
327
+ # 1e-4 = 1*10^-4 , 5e-4 = 5*10^-4
328
+
329
+
330
+
331
+ optimizer = optim.Adam([
332
+
333
+ {'params': params_to_update_1, 'lr': 1e-4},
334
+
335
+ {'params': params_to_update_2, 'lr': 1e-4},
336
+
337
+ {'params': params_to_update_3, 'lr': 1e-3}
338
+
339
+ ])
340
+
341
+
342
+
161
343
  ```

1

画像を入れ、コードを入れました。

2020/11/29 00:20

投稿

tomomina
tomomina

スコア0

test CHANGED
File without changes
test CHANGED
@@ -1,3 +1,161 @@
1
1
  Pythonを使って深層学習を勉強している初心者です。
2
2
 
3
3
  resnet101を用いて、ファインチューニングを行いたいと考えています。前処理として、手元にある画像サイズ640×480を、画像サイズ、224×224に変更する必要があります。画像は、音をスペクトログラムにしたものです。そのため、横軸に時間、縦軸に周波数、色は信号の強さを表しており、リサイズを行った場合、画像にある情報が潰れてしまいます。これを避けるために、前処理で画像サイズを変更しない方法や画像にある情報を潰さずに済む方法がありましたら、教えていただけると助かります。
4
+
5
+ スペクトログラム
6
+
7
+ ![イメージ説明](c191adbfc061c54ab2b034ac04d4e9f2.jpeg)
8
+
9
+ スペクトログラムを224×224にリサイズし、色情報の規格化を行った画像。
10
+
11
+ ![イメージ説明](544101676c87bb4ca658275f2dbeb5bc.png)
12
+
13
+
14
+
15
+ ```Python
16
+
17
+
18
+
19
+ # 入力画像の前処理をするクラス
20
+
21
+ # 訓練時と推論時で処理が異なる
22
+
23
+
24
+
25
+
26
+
27
+ class ImageTransform():
28
+
29
+ """
30
+
31
+ 画像の前処理クラス。訓練時、検証時で異なる動作をする。
32
+
33
+ 画像のサイズをリサイズし、色を標準化する。
34
+
35
+ 訓練時はRandomResizedCropとRandomHorizontalFlipでデータオーギュメンテーションする。
36
+
37
+
38
+
39
+
40
+
41
+ Attributes
42
+
43
+ ----------
44
+
45
+ resize : int
46
+
47
+ リサイズ先の画像の大きさ。
48
+
49
+ mean : (R, G, B)
50
+
51
+ 各色チャネルの平均値。
52
+
53
+ std : (R, G, B)
54
+
55
+ 各色チャネルの標準偏差。
56
+
57
+ """
58
+
59
+
60
+
61
+ def __init__(self, resize, mean, std):
62
+
63
+ self.data_transform = {
64
+
65
+ 'train': transforms.Compose([
66
+
67
+ transforms.Resize((224,224)),
68
+
69
+ #transforms.RandomHorizontalFlip(), # データオーギュメンテーション
70
+
71
+ transforms.ToTensor(), # テンソルに変換
72
+
73
+ transforms.Normalize(mean, std) # 標準化
74
+
75
+ ]),
76
+
77
+ 'val': transforms.Compose([
78
+
79
+ transforms.Resize((224,224)),
80
+
81
+ transforms.ToTensor(), # テンソルに変換
82
+
83
+ transforms.Normalize(mean, std) # 標準化
84
+
85
+ ]),
86
+
87
+ }
88
+
89
+
90
+
91
+
92
+
93
+ def __call__(self, img, phase='train'):
94
+
95
+ """
96
+
97
+ Parameters
98
+
99
+ ----------
100
+
101
+ phase : 'train' or 'val'
102
+
103
+ 前処理のモードを指定。
104
+
105
+ """
106
+
107
+ return self.data_transform[phase](img)
108
+
109
+
110
+
111
+ # 訓練時の画像前処理の動作を確認
112
+
113
+ # 実行するたびに処理結果の画像が変わる
114
+
115
+
116
+
117
+ # 1. 画像読み込み
118
+
119
+ image_file_path = './data/rockk.00000.jpg'
120
+
121
+ img = Image.open(image_file_path) # [高さ][幅][色RGB]
122
+
123
+
124
+
125
+ # 2. 元の画像の表示
126
+
127
+ plt.imshow(img)
128
+
129
+ plt.show()
130
+
131
+
132
+
133
+ # 3. 画像の前処理と処理済み画像の表示
134
+
135
+ size = 224
136
+
137
+ mean = (0.485, 0.456, 0.406)
138
+
139
+ std = (0.229, 0.224, 0.225)
140
+
141
+
142
+
143
+ transform = ImageTransform(size, mean, std)
144
+
145
+ img_transformed = transform(img, phase="train") # torch.Size([3, 224, 224])
146
+
147
+
148
+
149
+ # (色、高さ、幅)を (高さ、幅、色)に変換し、0-1に値を制限して表示
150
+
151
+ img_transformed = img_transformed.numpy().transpose((1, 2, 0))
152
+
153
+ img_transformed = np.clip(img_transformed, 0, 1)
154
+
155
+ plt.imshow(img_transformed)
156
+
157
+ plt.show()
158
+
159
+
160
+
161
+ ```