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

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

新規登録して質問してみよう
ただいま回答率
85.48%
深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

CNN (Convolutional Neural Network)

CNN (Convolutional Neural Network)は、全結合層のみではなく畳み込み層とプーリング層で構成されるニューラルネットワークです。画像認識において優れた性能を持ち、畳み込みニューラルネットワークとも呼ばれています。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

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

Q&A

0回答

2331閲覧

プーリング層でValueError: axes don't match arrayというエラーが出る。

tre_v

総合スコア0

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

CNN (Convolutional Neural Network)

CNN (Convolutional Neural Network)は、全結合層のみではなく畳み込み層とプーリング層で構成されるニューラルネットワークです。画像認識において優れた性能を持ち、畳み込みニューラルネットワークとも呼ばれています。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

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

0グッド

1クリップ

投稿2021/08/02 08:52

編集2021/08/02 16:06

CNNを使った画像識別を行おうとしていますが、プーリング層の部分でエラーが発生してしまいます。

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

ValueError Traceback (most recent call last) <ipython-input-5-081f89893a7a> in <module> 55 56 # 勾配の計算 (誤差逆伝播法を用いる) ---> 57 grads = snet.gradient(batches, t_train) 58 59 # 更新 ~/***/cnn.py in gradient(self, x, t) 122 layers.reverse() 123 for layer in layers: --> 124 dout = layer.backward(dout) 125 126 # 設定 ~/***/layers.py in backward(self, dout) 458 # doutのチャンネル数軸を4番目に移動させる 459 print(dout.shape) --> 460 dout = dout.transpose(0, 2, 3, 1) 461 462 # プーリング適応領域の要素数(プーリング適応領域の高さ × プーリング適応領域の幅) ValueError: axes don't match array

メインのソースコード

Python

1epochs = 10 2batch_size = 32 3lr = 0.01 4loop = 3 5 6optimizer = Adam() 7 8# CNNのオブジェクト生成 9snet = CNN(input_dim=(1, 28, 28), 10 conv_param={'filter_size':3, 'pad':1, 'stride':1}, 11 pool_param={'pool_size':2, 'pad':0, 'stride':2},filter_num_list=[32,64,64], 12 hidden_size=100, output_size=15, weight_init_std=0.01) 13 14train_loss = [] 15test_loss = [] 16train_accuracy = [] 17test_accuracy = [] 18 19#データ拡張に使う 20datagen = ImageDataGenerator(rotation_range = 20, height_shift_range = 0.1,width_shift_range = 0.1,zoom_range= 0.1) 21 22for i in range(loop): 23 train, test, train_labels, test_labels = train_test_split(train_data, train_label, test_size=0.3,shuffle=True) 24 train = train.reshape(-1, 1, 28, 28) 25 test = test.reshape(-1, 1, 28, 28) 26 x = train 27 t = train_labels 28 x = x.reshape(-1,1,28,28) # 配列形式の変形 29 30 # 繰り返し回数 31 xsize = x.shape[0] 32 iter_num = np.ceil(xsize / batch_size).astype(np.int) 33 34 x = x.reshape(-1,1,28,28) # 配列形式の変形 35 for epoch in range(epochs): 36 print("epoch=%s"%epoch) 37 38 # シャッフル 39 idx = np.arange(xsize) 40 np.random.shuffle(idx) 41 42 for it in range(iter_num): 43 """ 44 ランダムなミニバッチを順番に取り出す 45 """ 46 print("it=", it) 47 mask = idx[batch_size*it : batch_size*(it+1)] 48 49 # ミニバッチの生成 50 x_train = x[mask] 51 t_train = t[mask] 52 53 g = datagen.flow(x_train, batch_size = batch_size,shuffle=False) 54 batches = g.next() 55 56 # 勾配の計算 (誤差逆伝播法を用いる) 57 grads = snet.gradient(batches, t_train) 58 59 # 更新 60 optimizer.update(snet.params, grads) 61 62 ## 学習経過の記録 63 64 # 訓練データにおけるloss 65 # print("calculating train_loss") 66 train_loss.append(snet.loss(x, t)) 67 68 # print("calculating test_loss") 69 # テストデータにおけるloss 70 test_loss.append(snet.loss(test, test_labels)) 71 72 # print("calculating train_accuracy") 73 # 訓練データにて精度を確認 74 train_accuracy.append(snet.accuracy(x, t)) 75 76 # print("calculating test_accuracy") 77 # テストデータにて精度を算出 78 test_accuracy.append(snet.accuracy(test, test_labels))

上で参照しているコード

cnn.py

import

1from collections import OrderedDict 2from layers import Convolution, Pooling, ReLU, Affine, SoftmaxWithLoss,BatchNormalization 3 4class CNN: 5 def __init__(self, input_dim=(1, 28, 28), 6 conv_param={'filter_size':3, 'pad':1, 'stride':1}, 7 pool_param={'pool_size':2, 'pad':0, 'stride':2},filter_num_list=[32,64,64], 8 hidden_size=100, output_size=15, weight_init_std=0.01): 9 10 filter_size = conv_param['filter_size'] 11 filter_pad = conv_param['pad'] 12 filter_stride = conv_param['stride'] 13 14 pool_size = pool_param['pool_size'] 15 pool_pad = pool_param['pad'] 16 pool_stride = pool_param['stride'] 17 self.filter_num_list = filter_num_list 18 19 # 重みの初期化 20 self.params = {} 21 std = weight_init_std 22 cv_input_size = input_dim[1] 23 cv_list = filter_num_list 24 input_oku = input_dim[0] 25 for idx in range(1, len(cv_list)+1): 26 filter_num = cv_list[idx - 1] 27 conv_output_size = (cv_input_size + 2*filter_pad - filter_size) // filter_stride + 1 28 pool_output_size = (conv_output_size + 2*pool_pad - pool_size) // pool_stride + 1 29 30 self.params['W'+ str(idx)] = std * np.random.randn(filter_num,input_oku, filter_size, filter_size) 31 self.params['b'+ str(idx)] = np.zeros(filter_num) 32 self.params['gamma'+ str(idx)] = np.ones(filter_num) 33 self.params['beta'+ str(idx)] = np.zeros(filter_num) 34 35 cv_input_size = pool_output_size 36 input_oku = filter_num 37 38 pool_output_pixel = filter_num * pool_output_size * pool_output_size 39 self.params['W_hidden'] = std * np.random.randn(pool_output_pixel, hidden_size) 40 self.params['b_hidden'] = np.zeros(hidden_size) 41 self.params['W_last'] = std * np.random.randn(hidden_size, output_size) 42 self.params['b_last'] = np.zeros(output_size) 43 self.params['gamma_last'] = np.ones(hidden_size) 44 self.params['beta_last'] = np.zeros(hidden_size) 45 46 # レイヤの生成 47 self.layers = OrderedDict() 48 for idx in range(1, len(cv_list)+1): 49 self.layers['Conv'+ str(idx)] = Convolution(self.params['W'+ str(idx)], self.params['b'+ str(idx)],conv_param['stride'], conv_param['pad']) 50 self.layers['BatchNorm'+ str(idx)] = BatchNormalization(self.params['gamma'+ str(idx)], self.params['beta'+ str(idx)]) 51 self.layers['ReLU'+ str(idx)] = ReLU() 52 self.layers['Pool'+ str(idx)] = Pooling(pool_h=pool_size, pool_w=pool_size, stride=pool_stride, pad=pool_pad) 53 self.layers['Affine_hidden'] = Affine(self.params['W_hidden'], self.params['b_hidden']) 54 self.layers['BatchNorm_last'] = BatchNormalization(self.params['gamma_last'], self.params['beta_last']) 55 self.layers['ReLU_last'] = ReLU() 56 self.layers['Affine_last'] = Affine(self.params['W_last'], self.params['b_last']) 57 58 self.last_layer = SoftmaxWithLoss() 59 60 def predict(self, x,train_flg=False): 61 for key, layer in self.layers.items(): 62 if "BatchNorm" in key: 63 x = layer.forward(x, train_flg) 64 else: 65 x = layer.forward(x) 66 67 return x 68 69 def loss(self, x, t,train_flg=False): 70 y = self.predict(x,train_flg) 71 return self.last_layer.forward(y, t) 72 73 def accuracy(self, x, t, batch_size=100): 74 if t.ndim != 1 : t = np.argmax(t, axis=1) 75 76 acc = 0.0 77 78 for i in range(int(x.shape[0] / batch_size)): 79 tx = x[i*batch_size:(i+1)*batch_size] 80 tt = t[i*batch_size:(i+1)*batch_size] 81 y = self.predict(tx,train_flg=False) 82 y = np.argmax(y, axis=1) 83 acc += np.sum(y == tt) 84 85 return acc / x.shape[0] 86 87 def gradient(self, x, t): 88 # forward 89 self.loss(x, t,train_flg=True) 90 91 # backward 92 dout = 1 93 dout = self.last_layer.backward(dout) 94 95 layers = list(self.layers.values()) 96 layers.reverse() 97 for layer in layers: 98 dout = layer.backward(dout) 99 100 # 設定 101 grads = {} 102 for idx in range(1, len(self.filter_num_list)+1): 103 grads['W'+ str(idx)], grads['b'+ str(idx)] = self.layers['Conv'+ str(idx)].dW, self.layers['Conv'+ str(idx)].db 104 grads['gamma'+ str(idx)] = self.layers['BatchNorm'+ str(idx)].dgamma 105 grads['beta'+ str(idx)] = self.layers['BatchNorm'+ str(idx)].dbeta 106 107 grads['W_hidden'], grads['b_hidden'] = self.layers['Affine_hidden'].dW, self.layers['Affine_hidden'].db 108 grads['gamma_last'] = self.layers['BatchNorm_last'].dgamma 109 grads['beta_last'] = self.layers['BatchNorm_last'].dbeta 110 grads['W_last'], grads['b_last'] = self.layers['Affine_last'].dW, self.layers['Affine_last'].db 111 112 return grads

layers.py(プーリング層の部分)

class Pooling: def __init__(self, pool_h, pool_w, stride=1, pad=0): self.pool_h = pool_h self.pool_w = pool_w self.stride = stride self.pad = pad self.x = None self.arg_max = None def forward(self, x): N, C, H, W = x.shape out_h = int(1 + (H - self.pool_h) / self.stride) out_w = int(1 + (W - self.pool_w) / self.stride) col = im2col(x, self.pool_h, self.pool_w, self.stride, self.pad) col = col.reshape(-1, self.pool_h*self.pool_w) arg_max = np.argmax(col, axis=1) out = np.max(col, axis=1) # 画像形式に戻して、チャンネルの軸を2番目に移動させる out = out.reshape(N, out_h, out_w, C).transpose(0, 3, 1, 2) self.x = x self.arg_max = arg_max return out def backward(self, dout): # doutのチャンネル数軸を4番目に移動させる dout = dout.transpose(0, 2, 3, 1) # プーリング適応領域の要素数(プーリング適応領域の高さ × プーリング適応領域の幅) pool_size = self.pool_h * self.pool_w dmax = np.zeros((dout.size, pool_size)) dmax[np.arange(self.arg_max.size), self.arg_max.flatten()] = dout.flatten() dmax = dmax.reshape(dout.shape + (pool_size,)) dcol = dmax.reshape(dmax.shape[0] * dmax.shape[1] * dmax.shape[2], -1) dx = col2im(dcol, self.x.shape, self.pool_h, self.pool_w, self.stride, self.pad) return dx

試したこと

プーリング層のbackwardのtransposeでエラーが出ているので、transposeしようとしているdoutを確認したら、print(dout.shape)の結果が(32, 576)と出力されました。ここが4次元じゃなくなっているのでエラーが出ているのだと思いますが、原因がわかりません。

どのようにすれば解決できるのでしょうか。画像認識について初心者なので、ご教示頂けますと幸いです。

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

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

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

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

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

odataiki

2021/08/02 15:02

開示頂いたコードの cnn.py の中にに未定義変数 cv_list があってこちらで再現が出来ません。 コードのコピペ時に漏れている部分ありませんか?
tre_v

2021/08/02 16:07

ご指摘ありがとうございます。cnn.pyの重みの初期化の部分のコードを省略してしまっていたので、追記しました。ご確認をお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問