CMU-Multimodal SDK Version 1.1 (mmsdk)使用總結

20191026日 星期六git

     

  • mmdatasdk: module for downloading and procesing multimodal datasets using computational sequences.
  • mmmodelsdk: tools to utilize complex neural models as well as layers for building new models. The fusion models in prior papers will be released here.

     

  1. mmdatasdk

將每一個數據集當作是可計算的序列,每一個序列包含一個模態的數據(以分層結構存儲) github

關於csd格式文件(csd = computational sequential data):

  • 兩個主要元素(key elements)
    • data:特徵,根據video id等進行分類
      • 每一個多模態數據源關聯兩個矩陣:特徵和時間(timestamp),特徵和時間矩陣都是numpy 2d array
    • metadata:完整性和版本信息
  • 存儲在hdf5對象中

本例中,csd文件中存儲了提取出來的特徵(用於能夠將提取出來的特徵進行分享)

     

  1. 步驟:

Step1 下載 網絡

Step2 對齊(下載的數據頻率可能不同) 數據結構

sometimes the data needs to be aligned ide

Code 1>>>獲取情感態度標籤(label) cmumosi_highlevel.add_computational_sequences(mmdatasdk.cmu_mosi.labels,'cmumosi/')函數

Code 2>>> 使everything對齊ui

cmumosi_highlevel.align('Opinion Segment Labels') spa

舉例: debug

對於視頻模態的數據v0,用v0[2]來表示視頻的第三段 3d

     

  1. 單詞級別的對齊:word level alignment

>>> from mmsdk import mmdatasdk
>>> cmumosi_highlevel=mmdatasdk.mmdataset(mmdatasdk.cmu_mosi.highlevel,'cmumosi/')
>>> cmumosi_highlevel.align('glove_vectors',collapse_functions=[myavg])
>>> cmumosi_highlevel.add_computational_sequences(mmdatasdk.cmu_mosi.labels,'cmumosi/')
>>> cmumosi_highlevel.align('Opinion Segment Labels')

     

From <https://github.com/A2Zadeh/CMU-MultimodalSDK>

Align function:對齊函數,接受兩個值:時間和特徵(也就是前邊的兩個矩陣)

cmumosi_highlevel.align('glove_vectors',collapse_functions=[myavg])能夠接受多個函數做爲參數,這時將各個函數分別執行並將結果拼接

     

  1. 特徵提取:

使用glove

     

  1. 數據集的數據結構分析

     

數據集結構(邏輯結構)

     

存儲結構:

     

  1. 查看數值的方法:

print(dataset[text_field]['5W7Z1C_fDaE[9]']['features'])

輸出

[[b'its']
[b'completely']
[b'different']
[b'from']
[b'anything']
[b'sp']
[b'weve']
[b'ever']
[b'seen']
[b'him']
[b'do']
[b'before']]

     

print(dataset[label_field]['5W7Z1C_fDaE[10]']['intervals'])

輸出

[[32.239227 34.50408 ]]

(時間戳的起止點)

     

  1. 如何用HDF5格式表達多模態數據?

Pivot modality:核心模態

不一樣模態數據的採樣頻率不同,須要對齊到pivot modality上,一般狀況下,對齊到words

對齊的辦法:使用collapse函數

將不一樣模態數據按主要模態的時間軸進行分組,而後collapse函數將其進行池化

     

ATTN:本SDK將collapse函數應用到全部模態,可是Word模態沒法求均值,所以須要一個try:except,捕獲文本求均值產生的異常

     

  1. 讀取數據樣式:

dataset=md.mmdataset(recipe)

dataset變量結構以下:

     

其中,'CMU_MOSI_ModifiedTimestampedWords' 模態的數據格式以下:

     

data裏邊存儲了文本數據及其時間戳:

     

第一個維度:

對於一個batch(也就是變量train、變量test)來講,5個維度的含義以下:

print(batch[0].shape)

#wordvectors,paddedtomaxlen

print(batch[1].shape)

#visualfeatures

print(batch[2].shape)

#acousticfeatures

print(batch[3])

#labels

print(batch[4])

#lengths

     

rain_loader = DataLoader(train, shuffle=False, batch_size=batch_sz, collate_fn=multi_collate)

上述四個變量,在訓練中經過train_loader賦值給train_iter,再劃分紅每輪次循環中的batch

     

在文件train.py中:

    for batch in train_iter:

        model.zero_grad()

        t, v, a, y, l = batch

        batch_size = t.size(0)

t,v,a,y,l=batch

# t,v,a,y,l中存儲了一個batchsize中的全部數據

     

使用MOSI數據集,第一個batchsize以後,tval的維度以下:

t: [33, 56]

v: [33, 56, 47]

a: [33, 56, 74]

l: [56]

     

第二個batchsize以後,tval的維度以下:

t: [42, 56]

v: [42, 56, 47]

a: [42, 56, 74]

l: [56]

     

最後一個batchsize以後,上述變量的維度以下:

t: [59, 49]

v: [59, 49, 47]

a: [59, 49, 74]

l: [49]

     

debug模式下對上述y變量進行inspect,獲得結果以下:

     

且有len(y) == 168

     

  1. 對上述數據的分析:

    因爲batchsize = 56

    Dataloader的batchsize = batchsize * 3,所以len(y) == 168

     

劃分batch以後,train_loader內保存了dataset的一部分,也按照上邊的順序保存

例如:

train_loader.dataset[0]的返回結果表示一整條多模態數據

     

     

     

  1. 數據的物理含義:

train_loader.dataset[0]以及train_loader.dataset[1]等:

  • train_loader.dataset的第一個維度表示數據條數,對應一段視頻中的文本聲音圖像及其label

train_loader.dataset[0][0]中存儲了三種模態的數據(文本聲音圖像)

train_loader.dataset[0][1]中存儲了label(情感標籤)

train_loader.dataset[0][2]中存儲了視頻對應的字符串(視頻文件名)

     

ATTN

train_loader.dataset[0][0]是一個list,list中有三個元素,是三個array,表示三種模態的數據

例如train_loader.dataset[67][2]返回:

Out[12]: u'Oz06ZWiO20M[22]'

     

  1. 多模態數據的獲取方式:

train_loader.dataset[0][0][0]是wordvector(是一個array)

train_loader.dataset[0][0][1]是visual feature(是一個array)

train_loader.dataset[0][0][2]是acoustic feature(是一個array)

上述三個array構成了一個list

     

  1. 總結:

  • train_loader.dataset是一個list
  • train_loader.dataset[0]或train_loader.dataset[99]等,是tuple(三元組),三元組由兩個array和一個字符串構成
    • train_loader.dataset[0][0]中存儲了三種模態的數據(文本聲音圖像),是一個tuple
      • train_loader.dataset[0][0][0]是一個ndarray,表示word vector,一個值對應說話人說的一個單詞
      • train_loader.dataset[0][0][1]表示視覺信號ndarray,其列數等於視覺信號提取出來的特徵維度(47),其行數等於說話人說的單詞數
      • train_loader.dataset[0][0][2]表示聽覺信號ndarray,其列數等於聽覺信號提取出來的特徵維度(74),其行數等於說話人說的單詞數
    • train_loader.dataset[0][1]中存儲了label(情感標籤),是ndarray
    • train_loader.dataset[0][2]中存儲了視頻對應的字符串(視頻文件名)

     

  1. 對各個維度的分析:

wordvector的維度比較低,一般少於10維

visual feature和acoustic feature在對齊以後含有多個array(本例中,每一個音視頻array有46維長度)

即:

train_loader.dataset[78][0][2]表示音頻模態數據,可是這個數據包括14個特徵向量(其餘樣本可能包含不一樣數值)

     

至關於如下14個tensor,每一個tensor有46維:

train_loader.dataset[78][0][2][0]

... ...

train_loader.dataset[78][0][2][13]

     

總結:

MOSI數據集是語素級的,以數據集中編號爲'8qrpnFRGt2A'的視頻的第15小段爲例,該段視頻中人物說了14個字(word),所以對應的另外兩種模態中,有14個array,驗證方法是:

     

如圖,train_loader.dataset[78][0][2].__len__()==14,所以說明語素級別上數據集是對齊的

在數據集中能夠查找到對應的這句話

[['it']

['fell']

['like']

['i']

['was']

['watching']

['one']

['of']

['those']

['army']

['of']

['one']

['commercials']

['sometimes']]

     

對應的情感標籤:

     

     

  1. 網絡的訓練流程:

在trainloader的基礎上,新建一個`train_iter` 變量以下

train_iter=tqdm_notebook(train_loader)

train_iter增長了sample的功能

事實上,train_iter就是train_loader的基礎上增長了進度條功能

sample的方法使用的是pyTorch中的dataloader

     

_________________________

  1. 補充1

collate函數是pytorch中用Dataloader來處理數據集的概念,而不是多模態處理中的概念

collate取"拼接"之意

defmulti_collate(batch):

     

這個函數對一個batch的數據進行拼接

把batch[1]取出來做爲label(就是y)

batch[0][0]取出來做爲文本模態(就是t

batch[0][1]以及batch[0][2]取出來做爲視覺和音頻模態(就是v和a,多維tensor)

返回值是:

returnsentences,visual,acoustic,labels,lengths

     

————————————————————

  1. 補充2

數據集中共有1281條數據,即:

X_train_l.__len__()==1281

問題:最後整理出來的每一個batch下的t,v,a,y,l進行拼接,獲得1281條y和1281條l,可是v,a,t卻只有1014條

debug模式下,發如今某一輪batch循環中,batchsize=56,有:

y.__len__() == l.__len__() == 56,

可是a,v,t的長度倒是32

     

進一步分析a,v,t的維度,有:

In[14]: a.shape

Out[14]: torch.Size([48, 56, 74])

In[15]: v.shape

Out[15]: torch.Size([48, 56, 47])

所以,上邊a,v,t的length和y,l的length不同,其緣由在於:代碼中拼接a,v,t時選錯了維度

解決方案:

須要將a,v,t的前兩個維度互換位置

t=list(np.array(t).transpose((1,0)))

第一步:torch.tensor轉換成ndarray

第二步:ndarray前兩維互換

第三步:轉換成list

ATTN:

若是使用list(array1)的形式,則只將最外層轉換成list,裏邊仍是array

若是使用array1.tolist()方法,則整個array的每一層都變成了list

     

  1. 補充3

在第一個batch中,將t,v,a,y,l轉換成ndarray以後的shape以下:

t的shape爲(40,56)

v的shape爲(40,56,47)

a的shape爲(40,56,74)

y的shape爲(56,1)

l的shape爲(56,)

     

此時的ndarray的各個軸進行過變換

第二維(56)表示batchsize

第一維表示語素的個數(單詞數)

第三維表示模態特徵(應做爲X_train的一行,進行拼接)

     

整理數據的代碼:

forbatchintrain_iter:

#batch=list(batch)

#X_train_tmp=X_train_tmp+batch

t,v,a,y,l=batch

     

t=list(np.array(t).transpose((1,0)))

v=list(np.array(v).transpose((1,0,2)))

a=list(np.array(a).transpose((1,0,2)))

y=list(np.array(y))

l=list(np.array(l).reshape((-1,1)))

ifcnt==0:

X_train_t=t

X_train_v=v

X_train_a=a

Y_train=y

X_train_l=l

cnt+=1

else:

X_train_t+=t

X_train_v+=v

X_train_a+=a

Y_train+=y

X_train_l+=l

cnt+=1

     

上述代碼以後:

X_train_a是一個list(len==1281),每一個元素是一個array,每一個array的shape是(40, 74)

X_train_a[0].shape

Out[3]: (40, 74)

其中,40是語素的個數,74是提取的特徵數

相關文章
相關標籤/搜索