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

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

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

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

9480閲覧

Python3 numpyの2次元配列同士の計算エラー

Hiroaki_N

総合スコア7

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2017/05/14 16:28

###前提・実現したいこと
Python3.5.2でニューラルネットワークを作っています。
勾配を数値微分を求める機能を実装中に以下のエラーメッセージが発生しました。

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

unsupported operand type(s) for -: 'list' and 'list'

###該当のソースコード

python3

1def numerical_gradient(f, w): 2 h = 1e-4 # 0.0001 3 grad = np.zeros_like(w) 4 5 for idx in range(w.size): 6 tmp_val = w[idx] 7 w[idx] = tmp_val + h 8 fwh1 = f(w) # f(w+h) 9 w[idx] = tmp_val - h 10 fwh2 = f(w) # f(w-h) 11 grad[idx] = (fwh1- fwh2) / (2*h) # ここでエラーが発生しています 12 w[idx] = tmp_val # 値を元に戻す 13 14 return grad 15 16class TwoLayerNet: 17 18 def __init__(self, input_size, hidden_size, output_size, weight_init_std=0.01): 19 # 重みの初期化 20 self.params = {} 21 self.params['w1'] = weight_init_std * np.random.randn(input_size, hidden_size) 22 self.params['w2'] = weight_init_std * np.random.randn(input_size, hidden_size) 23 self.params['w3'] = weight_init_std * np.random.randn(input_size, hidden_size) 24 self.params['w4'] = weight_init_std * np.random.randn(input_size, hidden_size) 25 self.params['w5'] = weight_init_std * np.random.randn(hidden_size, output_size) 26 self.params['w6'] = weight_init_std * np.random.randn(hidden_size, output_size) 27 self.params['w7'] = weight_init_std * np.random.randn(hidden_size, output_size) 28 self.params['w8'] = weight_init_std * np.random.randn(hidden_size, output_size) 29 self.params['b1'] = np.zeros(hidden_size) 30 31 def predict(self, x): 32 w1, w2, w3, w4, w5, w6, w7, w8 = self.params['w1'], self.params['w2'], self.params['w3'], self.params['w4'], self.params['w5'], self.params['w6'], self.params['w7'], self.params['w8'] 33 b1 = self.params['b1'] 34 z = [] 35 y = [] 36 37 a1 = np.dot(w1, x[0][0]) + np.dot(w2, x[0][1]) + np.dot(w3, x[0][2]) + np.dot(w4, x[0][3]) + b1 38 z.append(np.dot(w5, a1)) 39 z.append(np.dot(w6, a1)) 40 z.append(np.dot(w7, a1)) 41 z.append(np.dot(w8, a1)) 42 y.append(softmax(z[0])) 43 y.append(softmax(z[1])) 44 y.append(softmax(z[2])) 45 y.append(softmax(z[3])) 46 return y 47 # x:入力データ, t:教師データ 48 def loss(self, x, t): 49 y = self.predict(x) 50 return y 51 52 # x:入力データ, t:教師データ 53 def numerical_gradient(self, x, t): 54 #損失関数定義 55 loss_W = lambda w: self.loss(x, t) 56 #def loss_W(w): 57 # return self.loss(x, t) 58 59 #勾配導出 60 grads = {} 61 grads['w1'] = numerical_gradient(loss_W, self.params['w1']) 62 grads['w2'] = numerical_gradient(loss_W, self.params['w2']) 63 grads['w3'] = numerical_gradient(loss_W, self.params['w3']) 64 grads['w4'] = numerical_gradient(loss_W, self.params['w4']) 65 grads['w5'] = numerical_gradient(loss_W, self.params['w5']) 66 grads['w6'] = numerical_gradient(loss_W, self.params['w6']) 67 grads['w7'] = numerical_gradient(loss_W, self.params['w7']) 68 grads['w8'] = numerical_gradient(loss_W, self.params['w8']) 69 grads['b1'] = numerical_gradient(loss_W, self.params['b1']) 70 return grads 71 72csv_obj = csv.reader(open("aaa.csv", "r")) 73data = [ v for v in csv_obj] 74x = [[0 for i in range(4)] for j in range(len(data))]#入力 75t = [[0 for i in range(4)] for j in range(len(data)-1)]#教師データ 76for i in range(len(data)): 77 sss = str(data[i][1]) 78 x[i][0] = int(sss[0:1]) 79 x[i][1] = int(sss[1:2]) 80 x[i][2] = int(sss[2:3]) 81 x[i][3] = int(sss[3:4]) 82 83 if i >= 1: 84 t[i-1][0] = int(sss[0:1]) 85 t[i-1][1] = int(sss[1:2]) 86 t[i-1][2] = int(sss[2:3]) 87 t[i-1][3] = int(sss[3:4]) 88 89#ハイパーパラメータ定義 90iters_num = 10000 91#train_size = x_train.shape[0] 92#batch_size = 100 93learning_rate = 0.1 94#TwoLayerNetインスタンス生成 95network = TwoLayerNet(input_size=4, hidden_size=1, output_size=4) 96 97#勾配の計算 98for i in range(iters_num): 99 grad = network.numerical_gradient(x, t) #数値微分 100 101以下エラー表示の内容です 102C:\deep-learning\ch04>python two_layer_net_Numbers4.py 103Traceback (most recent call last): 104 File "two_layer_net_Numbers4.py", line 128, in <module> 105 grad = network.numerical_gradient(x, t) #数値微分 106 File "two_layer_net_Numbers4.py", line 64, in numerical_gradient 107 grads['w1'] = numerical_gradient(loss_W, self.params['w1']) 108 File "..\common\gradient.py", line 73, in numerical_gradient 109 grad[idx] = (fwh1- fwh2) / (2*h) 110TypeError: unsupported operand type(s) for -: 'list' and 'list' 111

###試したこと
http://stackoverflow.com/questions/26685679/typeerror-unsupported-operand-types-for-list-and-list
によく似た問題が記載してありましたので、このサイト言うとおり
grad[idx] = (np.array(fwh1)- np.array(fwh2)) / (2*h)
と問題のコードを変更して実行してみた所
could not broadcast input array from shape(4,1,1) into shape(1)
というエラーが表示されてしまい、どうするべきかわからりませんでした。

おそらくデータ型があっていないのだと思いますが、どのようにすると計算ができるようになるのかを教えていただけたら嬉しいです。

###補足情報(言語/FW/ツール等のバージョンなど)
Python3.5.2やnumpyはAnaconda4.2.0をダウンロードして使っています。
使用端末はwindows10のPCです

よろしくお願い致します

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

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

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

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

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

guest

回答2

0

修行中の身にて大外れでも低評価にしないでね。

最初のエラーメッセージはlistには引算(-)はないよといってますね。
fwh1とfwh2はpredictが配列を返しているためにリストになっていますね。
質問者の方がnumpy配列にしてみたところ今度は grad[idx] はshape(1)なので代入できないと言っていますね。

さてpredictが配列を返しているためにこのような事態になっていますが
意図としては外側のnumerical_gradient関数で4要素を同時に計算したいということしょうか?
いずれにせよpredictメソッドとnumerical_gradient関数のミスマッチが原因と思われます。

投稿2017/05/15 05:45

yasushi_sapporo

総合スコア61

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

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

Hiroaki_N

2017/05/15 10:30

z = [] y = []となっていたのを z = np.array([0,0,0,0]) y = np.array([0,0,0,0]) というようにnumpy配列にしてみました! あと、配列の形状が異なっているというエラーが出ましたが、 network = TwoLayerNet(input_size=1, hidden_size=1, output_size=1) として、wやbの配列を1*1行列にした所、エラーは解消されました! ありがとうございます。 はい、4要素を同時に計算したいと考えています。 それについてはこれから考えようと思っています。 また何かありましたらよろしくお願い致します!
guest

0

ベストアンサー

エラーメッセージが

TypeError: unsupported operand type(s) for -: 'list' and 'list'

となっておりますので、fwh1 および fwh2 が PythonのList型であることがエラーの原因なのではないでしょうか。(実現したい内容から推測すると、fwh1fwh2は本来 numpy配列 であるべきなのかと思います。)

ソースコードを見る限り、このfwh1(fwh2)は TwoLayerNet.predict() の戻り値から得られていますので、とりあえずこの関数の戻り値をnumpy配列になるように修正してみてはいかがでしょうか。

あくまでも今回のエラーを解決する手段であり、他のエラーが起こらないか・コード全体が問題なく動作するかに関しては確認しておりませんので言及できません。スミマセン

投稿2017/05/15 02:31

magichan

総合スコア15898

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

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

Hiroaki_N

2017/05/15 10:28

z = [] y = []となっていたのを z = np.array([0,0,0,0]) y = np.array([0,0,0,0]) というようにnumpy配列にしてみました! あと、配列の形状が異なっているというエラーが出ましたが、 network = TwoLayerNet(input_size=1, hidden_size=1, output_size=1) として、wやbの配列を1*1行列にした所、エラーは解消されました! ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問