Don't call me turkryをcnnでとく
Jan 21, 2020
ネットサーフィン中に面白そうなものを見つけたので、後出しになるが解いてみる。🦃
https://www.kaggle.com/c/dont-call-me-turkey/
学習データ
学習データは1データごとに下のような構造
1 | - audio_embedding |
audio_embeddingとは、VGGishによって、YouTubeの動画データをを1秒ごとに128次元に圧縮したものらしい。これが最大10秒分ある。
vidはYouTubeで動画を開いたときにurlの末尾につく、youtube.com/watch?v=2lAe1cqCOXoの2lAe1cqCOXoの値のよう。試しにis_turkey=1の動画を見ると、七面鳥の鳴き声を確認できる。
モデル設計
データ前処理
10秒に満たないデータがあるため、0で埋める。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23train = pd.read_json('train.json')
test = pd.read_json('test.json')
#train data
train_x_raw=np.array(train.audio_embedding)# [1195,10,128]たまに足りなくておかしい
train_x =np.zeros((1195,10,128))
##整形
for i in range(len(train_x_raw)):
if(np.array(train_x_raw[i]).shape[0] is not 10):#足りない場合埋める
lack=10 - np.array(train_x_raw[i]).shape[0]
train_x[i]=np.append(train_x_raw[i],np.zeros((lack,128) ),axis=0)
else:#足りてたらnumpyに変換
train_x[i]=np.array(train_x_raw[i])
train_y=train.is_turkey
#test data
test_x_raw=test.audio_embedding#[1196,10,128]
test_x =np.zeros((1196,10,128))
for i in range(len(test_x_raw)):
if(np.array(test_x_raw[i]).shape[0] is not 10):#足りない場合埋める
lack=10 - np.array(test_x_raw[i]).shape[0]
test_x[i]=np.append(test_x_raw[i],np.zeros((lack,128)),ax is=0)
else:#足りてたらnumpyに変換
test_x[i]=np.array(test_x_raw[i])モデル定義
10x128を1枚の画像のようにcnnの入力とする。損失関数nn.BCEWithLogitsLoss()
はsigmoidを含むため、モデルの出力は(0~1)でない。
1 | class ML(nn.Module): |
学習部分
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31device = torch.device('cuda')
model = cnn(device=device).to(device)
criterion = nn.BCEWithLogitsLoss()
optimizer = optimizers.Adam(model.parameters())
def train_step(x,t):
model.train()
y=model(x)
loss = criterion(y,t)
optimizer.zero_grad()
loss.backward()
optimizer.step()
return loss
#パラメータ更新開始
epochs =100
lists=np.array(range(len(train_x)))
histories=np.array([])
for epoch in tqdm(range(epochs)):
train_loss = 0.
np.random.shuffle(lists)
for i in lists:
x_tmp = np.array(train_x[i]).reshape(1,1,10,128)
x = torch.from_numpy(x_tmp).type('torch.FloatTensor').to('cuda')#入力形式に変換(入力)
t = torch.from_numpy(np.array([train_y[i]])).type('torch.Floa tTensor').to('cuda')#入力形式に変換(出力)
loss = train_step(x,t)#順伝播,逆伝播,更新
train_loss += loss.item()
train_loss /= len(train_x)
histories=np.append(histories,train_loss)
print('Epoch: {}, Cost: {:.3f}'.format(epoch+1,train_loss))損失関数の推移
- 結果
実際のcompetitionの様子を見てるとまだまだ上がいるので、改良の余地がありそう。
出典・参考:
Don’t call me turkey! kaggle
https://www.kaggle.com/c/dont-call-me-turkey/(PyTorch) Temporal Convolutional Networks
https://www.kaggle.com/ceshine/pytorch-temporal-convolutional-networksVGGish https://github.com/tensorflow/models/tree/master/research/audioset/vggish