李宏毅2022機器學習HW4 Speaker Identification下

發表於2024-03-02

Task

Sample Baseline模型介紹

class Classifier(nn.Module):
	def __init__(self, d_model=80, n_spks=600, dropout=0.1):
		super().__init__()
		# Project the dimension of features from that of input into d_model.
		self.prenet = nn.Linear(40, d_model)

		# transformer
		self.encoder_layer = nn.TransformerEncoderLayer(
			d_model=d_model, dim_feedforward=256, nhead=2
		)
		self.encoder = self.encoder_layer

		self.pred_layer = nn.Sequential(
			nn.Linear(d_model, d_model),
			nn.ReLU(),
			nn.Linear(d_model, n_spks),
		)

	def forward(self, mels):
		"""
		args:
			mels: (batch size, length, 40)
		return:
			out: (batch size, n_spks)
		"""
		# out: (batch size, length, d_model)
		out = self.prenet(mels)
		# out: (length, batch size, d_model)
		out = out.permute(1, 0, 2)
		# The encoder layer expect features in the shape of (length, batch size, d_model).
		out = self.encoder(out)
		# out: (batch size, length, d_model)
		out = out.transpose(0, 1)
		# mean pooling
		stats = out.mean(dim=1)
		# out: (batch, n_spks)
		out = self.pred_layer(stats)
		return out

模型開始對特徵進行了升維以增強表示能力,隨後透過transformer的encoder對資料進一步編碼(未使用decoder),到這一步就包含了原來沒有包含的注意力資訊,以英文Sequence為例,如果原來的Sequence中每個單詞是獨立編碼的是沒有任何關聯的,那麼經過這一步之後,每一個單詞的編碼都是由其他單詞編碼的疊加而成。最後透過pred_layer進行預測(當然在此之前進行了一個mean pooling,這個下面會講)。

在模型的前向傳播時,模型基本是安裝前面定義的各層進行計算的,我們注意到在給encoder的輸入時,維度的順序為(length,batch_size, d_model),而不是(batch_size, length, d_model),實際上這是為了平行計算?
下圖是batch_first時所對應的儲存順序

下圖時length_first時所對應的儲存順序

在其他時序模型中,由於需要按序輸入,因此直接拿到一個sequence沒啥用,不如直接得到一批batch中的所有sequence中的第一個語音序列或單詞,但是在transformer中應該不需要這樣吧?

另外一個小細節是進行mean pooling

stats = out.mean(dim=1)

這一步是不必可少的,不然沒法輸入pred_layer,這裡做mean的意思是把每個sequence的所有frame透過平均合併為一個frame,如下圖所示

維度由batch_size\(\times\)length\(\times\)d_model變成了batch_size\(\times\)d_model

Medium Baseline

對於medium baseline,只需要調節影片中提示的地方進行修改即可,我的得分如下:

相關引數如下
d_model=120
4個encoder_layer的nhead=4

Strong Baseline

對於strong baseline,需要引入conformer架構,我的得分如下:

而conformer的引入需要注意以下幾點:
引入(當然你也可以使用pip進行單獨安裝)

from torchaudio.models.conformer import Conformer

由於torchaudio中實現的conformer預設是batch_first,因此在程式碼中我們需要去掉下面兩行

out = out.permute(1, 0, 2)
out = out.transpose(0, 1)

Boss Baseline

引入self-attention pooling和additive margin softmax後,準確率下降了。

相關文章