質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

6894閲覧

python negative dimensions are not allowed エラーを解決できません

toommauts

総合スコア2

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/10/29 02:36

前提・実現したいこと

「pythonで学ぶ音声認識」という本を勉強していのですが、MFCC特徴量を計算するプログラムを実行すると

ValueError: negative dimensions are not allowed

というエラーが出てしまい、実行することができません。ネットで調べたところ「サイズの大きく、かつ、スパースなndarrayを操作すると発生する」ようで、その記事の方はnumpy.floatで表現できる最小値を代入して解決したようなのですが、今回扱っているのがInt型でうまく応用できていません。どうしたらいいでしょうか?

使用しているOSはMacOSで、anacondaで仮想環境を立ててjupyternotebookでソースコードを書いています。

発生している問題・エラーメッセージ


ValueError Traceback (most recent call last) <ipython-input-5-4bcd799c2d54> in <module> 337 338 # MFCCを計算する --> 339 mfcc = feat_extractor.ComputeMFCC(waveform) 340 341 # 特徴量のフレーム数と次元数を取得 <ipython-input-5-4bcd799c2d54> in ComputeMFCC(self, waveform) 237 ''' 238 # FBANKおよび対数パワーを計算する --> 239 fbank, log_power = self.ComputeFBANK(waveform) 240 241 # DCTの基底行列との内積により,DCTを実施する <ipython-input-5-4bcd799c2d54> in ComputeFBANK(self, waveform) 171 num_frames = (num_samples - self.frame_size) // self.frame_shift + 1 172 # メルフィルタバンク特徴 --> 173 fbank_features = np.zeros((num_frames, self.num_mel_bins)) 174 # 対数パワー(MFCC特徴を求める際に使用する) 175 log_power = np.zeros(num_frames) ValueError: negative dimensions are not allowed

該当のソースコード

python

1-*- coding: utf-8 -*- 2 3 4 MFCC特徴の計算を行います. 5 6 7 wavデータを読み込むためのモジュール(wave)をインポート 8import wave 9 10 数値演算用モジュール(numpy)をインポート 11import numpy as np 12 13 os, sysモジュールをインポート 14import os 15import sys 16 17class FeatureExtractor(): 18 ''' 特徴量(FBANK, MFCC)を抽出するクラス 19 sample_frequency: 入力波形のサンプリング周波数 [Hz] 20 frame_length: フレームサイズ [ミリ秒] 21 frame_shift: 分析間隔(フレームシフト) [ミリ秒] 22 num_mel_bins: メルフィルタバンクの数(=FBANK特徴の次元数) 23 num_ceps: MFCC特徴の次元数(0次元目を含む) 24 lifter_coef: リフタリング処理のパラメータ 25 low_frequency: 低周波数帯域除去のカットオフ周波数 [Hz] 26 high_frequency: 高周波数帯域除去のカットオフ周波数 [Hz] 27 dither: ディザリング処理のパラメータ(雑音の強さ) 28 ''' 29 クラスを呼び出した時点で最初に1回実行される関数 30 def __init__(self, 31 sample_frequency=16000, 32 frame_length=25, 33 frame_shift=10, 34 num_mel_bins=23, 35 num_ceps=13, 36 lifter_coef=22, 37 low_frequency=20, 38 high_frequency=8000, 39 dither=1.0): 40 サンプリング周波数[Hz] 41 self.sample_freq = sample_frequency 42 窓幅をミリ秒からサンプル数へ変換 43 self.frame_size = int(sample_frequency * frame_length * 0.001) 44 フレームシフトをミリ秒からサンプル数へ変換 45 self.frame_shift = int(sample_frequency * frame_shift * 0.001) 46 メルフィルタバンクの数 47 self.num_mel_bins = num_mel_bins 48 MFCCの次元数(0次含む) 49 self.num_ceps = num_ceps 50 リフタリングのパラメータ 51 self.lifter_coef = lifter_coef 52 低周波数帯域除去のカットオフ周波数[Hz] 53 self.low_frequency = low_frequency 54 高周波数帯域除去のカットオフ周波数[Hz] 55 self.high_frequency = high_frequency 56 ディザリング係数 57 self.dither_coef = dither 58 59 FFTのポイント数 = 窓幅以上の2のべき乗 60 self.fft_size = 1 61 while self.fft_size < self.frame_size: 62 self.fft_size *= 2 63 64 メルフィルタバンクを作成する 65 self.mel_filter_bank = self.MakeMelFilterBank() 66 67 離散コサイン変換(DCT)の基底行列を作成する 68 self.dct_matrix = self.MakeDCTMatrix() 69 70 リフタ(lifter)を作成する 71 self.lifter = self.MakeLifter() 72 73 74 75 76 def ComputeFBANK(self, waveform): 77 '''メルフィルタバンク特徴(FBANK)を計算する 78 出力1: fbank_features: メルフィルタバンク特徴 79 出力2: log_power: 対数パワー値(MFCC抽出時に使用) 80 ''' 81 波形データの総サンプル数 82 num_samples = np.size(waveform) 83 特徴量の総フレーム数を計算する 84 num_frames = (num_samples - self.frame_size) // self.frame_shift + 1 85 メルフィルタバンク特徴 86 fbank_features = np.zeros((num_frames, self.num_mel_bins)) 87 対数パワー(MFCC特徴を求める際に使用する) 88 log_power = np.zeros(num_frames) 89 90 1フレームずつ特徴量を計算する 91 for frame in range(num_frames): 92 分析の開始位置は,フレーム番号(0始まり)*フレームシフト 93 start_index = frame * self.frame_shift 94 1フレーム分の波形を抽出し,前処理を実施する. 95 また対数パワーの値も得る 96 window, log_pow = self.ExtractWindow(waveform, start_index, num_samples) 97 98 高速フーリエ変換(FFT)を実行 99 spectrum = np.fft.fft(window, n=self.fft_size) 100 FFT結果の右半分(負の周波数成分)を取り除く 101 ※Kaldiの実装ではナイキスト周波数成分(最後の+1)は捨てているが, 102 本実装では捨てずに用いている 103 spectrum = spectrum[:int(self.fft_size/2) + 1] 104 105 パワースペクトルを計算する 106 spectrum = np.abs(spectrum) ** 2 107 108 メルフィルタバンクを畳み込む 109 fbank = np.dot(spectrum, self.mel_filter_bank.T) 110 111 対数計算時に-infが出力されないよう,フロアリング処理を行う 112 fbank[fbank<0.1] = 0.1 113 114 対数をとってfbank_featuresに加える 115 fbank_features[frame] = np.log(fbank) 116 117 対数パワーの値をlog_powerに加える 118 log_power[frame] = log_pow 119 120 return fbank_features, log_power 121 122 123 124 125 def ComputeMFCC(self, waveform): 126 ''' MFCCを計算する 127 ''' 128 FBANKおよび対数パワーを計算する 129 fbank, log_power = self.ComputeFBANK(waveform) 130 131 DCTの基底行列との内積により,DCTを実施する 132 mfcc = np.dot(fbank, self.dct_matrix.T) 133 134 リフタリングを行う 135 mfcc *= self.lifter 136 137 MFCCの0次元目を,前処理をする前の波形の対数パワーに置き換える 138 mfcc[:,0] = log_power 139 140 return mfcc 141 142 143 メイン関数 144 145if __name__ == "__main__": 146 147 148 設定ここから 149 150 151 各wavファイルのリストと特徴量の出力先 152 wav_dir = './wav' 153 out_dir = './mfcc' 154 155 repeat500内で使用するセット数 156 num_set = 5 157 158 repeat500内で使用する1セットあたりの発話数 159 num_utt_per_set = 10 160 161 サンプリング周波数 [Hz] 162 sample_frequency = 16000 163 フレーム長 [ミリ秒] 164 frame_length = 25 165 フレームシフト [ミリ秒] 166 frame_shift = 10 167 低周波数帯域除去のカットオフ周波数 [Hz] 168 low_frequency = 20 169 高周波数帯域除去のカットオフ周波数 [Hz] 170 high_frequency = sample_frequency / 2 171 メルフィルタバンクの数 172 num_mel_bins = 23 173 MFCCの次元数 174 num_ceps = 13 175 ディザリングの係数 176 dither=1.0 177 178 乱数シードの設定(ディザリング処理結果の再現性を担保) 179 np.random.seed(seed=0) 180 181 特徴量抽出クラスを呼び出す 182 feat_extractor = FeatureExtractor( 183 sample_frequency=sample_frequency, 184 frame_length=frame_length, 185 frame_shift=frame_shift, 186 num_mel_bins=num_mel_bins, 187 num_ceps=num_ceps, 188 low_frequency=low_frequency, 189 high_frequency=high_frequency, 190 dither=dither) 191 192 193 出力ディレクトリが存在しない場合は作成する 194 os.makedirs(out_dir, exist_ok=True) 195 196 セット x 発話数分だけ処理を実行 197 for set_id in range(num_set): 198 for utt_id in range(num_utt_per_set): 199 # wavファイル名 200 filename = 'REPEAT500_set%d_%03d' % (set_id+1, utt_id+1) 201 wav_path = os.path.join(wav_dir, filename+'.wav') 202 print(wav_path) 203 204 wavファイルを読み込み,特徴量を計算する 205 with wave.open(wav_path) as wav: 206 サンプリング周波数のチェック 207 if wav.getframerate() != sample_frequency: 208 sys.stderr.write('The expected \ 209 sampling rate is 16000.\n') 210 exit(1) 211 wavファイルが1チャネル(モノラル) 212 データであることをチェック 213 if wav.getnchannels() != 1: 214 sys.stderr.write('This program \ 215 supports monaural wav file only.\n') 216 exit(1) 217 218 wavデータのサンプル数 219 num_samples = wav.getnframes() 220 221 wavデータを読み込む 222 waveform = wav.readframes(num_samples) 223 224 読み込んだデータはバイナリ値 225 (16bit integer)なので,数値(整数)に変換する 226 waveform = np.frombuffer(waveform, dtype=np.int16) 227 228 MFCCを計算する 229 mfcc = feat_extractor.ComputeMFCC(waveform) 230 231 特徴量のフレーム数と次元数を取得 232 (num_frames, num_dims) = np.shape(mfcc) 233 234 特徴量ファイルの名前(splitextで拡張子を取り除いている) 235 out_file = os.path.splitext(os.path.basename(wav_path))[0] 236 out_file = os.path.join(os.path.abspath(out_dir), 237 out_file + '.bin') 238 239 データをfloat32形式に変換 240 mfcc = mfcc.astype(np.float32) 241 242 データをファイルに出力 243 mfcc.tofile(out_file) 244

試したこと

np.zerosをnp.onesに変えて全部1を代入するようにしましたが同じようなエラーが出てしまいました。

補足情報(FW/ツールのバージョンなど)

python 3.8.8

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jbpb0

2021/10/29 03:04

エラーが出てる行のすぐ上に下記を追加して実行したら、何て表示されますでしょうか? print(num_frames) print(self.num_mel_bins)
toommauts

2021/10/29 04:16

-2 23 と表示されました。
jbpb0

2021/10/29 04:45 編集

「-2」はダメですよね その数字のサイズの配列を作るのだから num_frames = (num_samples - self.frame_size) // self.frame_shift + 1 の計算に使ってる各変数の値をprint()で表示させて、それぞれがどのような数値ではないといけないのかを別途考えて、どれが間違ってるのかを特定します そして、間違ってる変数を計算してるところで同様にして、間違ってる原因を遡って特定します
toommauts

2021/10/29 05:09

アドバイスしていただきありがとうございます。 num_samplesがどうやらおかしいので、それを手がかりに調べてみます。
jbpb0

2021/10/29 05:15

num_frames =... がマイナスだから、おそらく num_samples - self.frame_size がマイナスなので、「num_samples」と「self.frame_size」の数値の大小を比較します 「num_samples」は、すぐ上の num_samples = np.size(waveform) でいくつになってるか? それが、解析してるデータのサイズと合ってるか? 「self.frame_size」は、 self.frame_size = int(sample_frequency * frame_length * 0.001) で、いくつになってるか? それを計算してる「sample_frequency」や「frame_length」は正しい数値か? コードの「設定ここから」の下で設定してる数値が、正しくそこに代入されてるか? コードの「設定ここから」の下で設定してる数値は、解析条件に合致した適切な数値か? みたいなことを考えながら確認していき、エラーの原因を探します
guest

回答1

0

ベストアンサー

negative dimensions are not allowed

エラーが出てる行のすぐ上に、下記を追加して実行してみてください
その結果表示される数字のサイズの配列を作るのだから、1以上の整数じゃないとダメですが、マイナスになってるはずなので、その原因を突き止めて直す必要があります

python

1print(num_frames) 2print(self.num_mel_bins)

投稿2021/10/29 11:17

jbpb0

総合スコア7651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問