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

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

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

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Python 3.x

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

Q&A

0回答

398閲覧

y=x^2の学習が進まない

aky

総合スコア0

Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Python 3.x

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

0グッド

1クリップ

投稿2023/04/05 04:44

編集2023/04/07 01:32

実現したいこと

y=x^2の関数を区間[-1,1]で学習したいです

前提

Pythonで基本的なNumpyの使い方について勉強しています。試行錯誤しながらコードを書いているのですがいまいちうまくいきません。

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

学習結果をプロットしてみてみると、y=x^2のあたいとはかけ離れてしまっています。
イメージ説明

イメージ説明

該当のソースコード

python

1import numpy as np 2import matplotlib.pyplot as plt 3from sklearn.model_selection import train_test_split 4 5def sigmoid(x): 6 return 1 / (1 + np.exp(-x)) 7def sigmoid_grad(x): 8 return (1.0 - sigmoid(x)) * sigmoid(x) 9def mean_squared_error(y, t): 10 return 0.5 * np.sum((y - t)**2) 11 12class Adam: 13 def __init__(self, lr=0.01, beta1=0.9, beta2=0.999): 14 self.lr = lr 15 self.beta1 = beta1 16 self.beta2 = beta2 17 self.iter = 0 18 self.m = None 19 self.v = None 20 21 def update(self, params, grads): 22 if self.m is None: 23 self.m, self.v = {}, {} 24 for key, val in params.items(): 25 self.m[key] = np.zeros_like(val) 26 self.v[key] = np.zeros_like(val) 27 28 self.iter += 1 29 lr_t = self.lr * np.sqrt(1.0 - self.beta2**self.iter) / (1.0 - self.beta1**self.iter) 30 31 for key in params.keys(): 32 #self.m[key] = self.beta1*self.m[key] + (1-self.beta1)*grads[key] 33 #self.v[key] = self.beta2*self.v[key] + (1-self.beta2)*(grads[key]**2) 34 self.m[key] += (1 - self.beta1) * (grads[key] - self.m[key]) 35 self.v[key] += (1 - self.beta2) * (grads[key]**2 - self.v[key]) 36 37 params[key] -= lr_t * self.m[key] / (np.sqrt(self.v[key]) + 1e-7) 38 39class Affine: 40 def __init__(self, W, b): 41 self.W =W 42 self.b = b 43 44 self.x = None 45 self.original_x_shape = None 46 # 重み・バイアスパラメータの微分 47 self.dW = None 48 self.db = None 49 50 def forward(self, x): 51 # テンソル対応 52 self.original_x_shape = x.shape 53 x = x.reshape(x.shape[0], -1) 54 self.x = x 55 56 out = np.dot(self.x, self.W) + self.b 57 58 return out 59 60 def backward(self, dout): 61 dx = np.dot(dout, self.W.T) 62 self.dW = np.dot(self.x.T, dout) 63 self.db = np.sum(dout, axis=0) 64 65 dx = dx.reshape(*self.original_x_shape) # 入力データの形状に戻す(テンソル対応) 66 return dx 67 68# データセットの生成 69from sklearn.model_selection import train_test_split 70np.random.seed(42)#今回はシード42 71x = np.random.uniform(-1, 1, size=(100, 1)) 72t = x ** 2 73X = np.arange(-1, 1, 0.01) 74Y = X ** 2 75 76# データセットの分割 77x_train, x_val, x_test = np.split(x, [int(len(x)*0.5), int(len(x)*0.75)]) 78t_train, t_val, t_test = np.split(t, [int(len(y)*0.5), int(len(y)*0.75)]) 79# 結果の表示 80#print("x_train:", x_train.shape) 81#print("x_val:", x_val.shape) 82#print("x_test:", x_test.shape) 83 84import numpy as np 85class TwoLayerNet: 86 def sigmoid(x): 87 return 1 / (1 + np.exp(-x)) 88 def __init__(self, input_size, hidden_size1, hidden_size2, hidden_size3, output_size, weight_init_std=0.01): 89 # 重みの初期化 90 self.params = {} 91 self.params['W1'] = weight_init_std * np.random.randn(input_size, hidden_size1) 92 self.params['b1'] = np.zeros(hidden_size1) 93 self.params['W2'] = weight_init_std * np.random.randn(hidden_size1, hidden_size2) 94 self.params['b2'] = np.zeros(hidden_size2) 95 self.params['W3'] = weight_init_std * np.random.randn(hidden_size2, hidden_size3) 96 self.params['b3'] = np.zeros(hidden_size3) 97 self.params['W4'] = weight_init_std * np.random.randn(hidden_size3, output_size) 98 self.params['b4'] = np.zeros(output_size) 99 100 def predict(self, x): 101 W1, W2, W3, W4 = self.params['W1'], self.params['W2'], self.params['W3'], self.params['W4'] 102 b1, b2, b3, b4 = self.params['b1'], self.params['b2'], self.params['b3'], self.params['b4'] 103 104 a1 = np.dot(x, W1) + b1 105 z1 = sigmoid(a1) 106 a2 = np.dot(z1, W2) + b2 107 z2 = sigmoid(a2) 108 a3 = np.dot(z2, W3) + b3 109 z3 = sigmoid(a3) 110 a4 = np.dot(z3, W4) + b4 111 y = (a4) 112 113 return y 114 115# x:入力データ, t:教師データ 116 def loss(self, x, t): 117 y = self.predict(x) 118 return mean_squared_error(y, t) 119 120 def accuracy(self, x, t): 121 y = self.predict(x) 122 y = np.argmax(y, axis=1) 123 t = np.argmax(t, axis=1) 124 125 accuracy = np.sum(y == t) / float(x.shape[0]) 126 return accuracy 127 128 # x:入力データ, t:教師データ 129 def numerical_gradient(self, x, t): 130 loss_W = lambda W: self.loss(x, t) 131 grads = {} 132 grads['W1'] = numerical_gradient(loss_W, self.params['W1']) 133 grads['b1'] = numerical_gradient(loss_W, self.params['b1']) 134 grads['W2'] = numerical_gradient(loss_W, self.params['W2']) 135 grads['b2'] = numerical_gradient(loss_W, self.params['b2']) 136 grads['W3'] = numerical_gradient(loss_W, self.params['W3']) 137 grads['b3'] = numerical_gradient(loss_W, self.params['b3']) 138 grads['W4'] = numerical_gradient(loss_W, self.params['W4']) 139 grads['b4'] = numerical_gradient(loss_W, self.params['b4']) 140 141 return grads 142 143 def gradient(self, x, t): 144 W1, W2, W3, W4 = self.params['W1'], self.params['W2'], self.params['W3'], self.params['W4'] 145 b1, b2, b3, b4 = self.params['b1'], self.params['b2'], self.params['b3'], self.params['b4'] 146 grads = {} 147 148 batch_num = x.shape[0] 149 150 # forward 151 a1 = np.dot(x, W1) + b1 152 z1 = sigmoid(a1) 153 a2 = np.dot(z1, W2) + b2 154 z2 = sigmoid(a2) 155 a3 = np.dot(z2, W3) + b3 156 z3 = sigmoid(a3) 157 a4 = np.dot(z3, W4) + b4 158 y = sigmoid(a4) 159 160 # backward 161 dy = (y - t) / batch_num 162 grads['W4'] = np.dot(z3.T, dy * sigmoid_grad(a4)) 163 grads['b4'] = np.sum(dy * sigmoid_grad(a4), axis=0) 164 165 dz3 = np.dot(dy * sigmoid_grad(a4), W4.T) 166 da3 = dz3 * sigmoid_grad(a3) 167 grads['W3'] = np.dot(z2.T, da3 * sigmoid_grad(a3)) 168 grads['b3'] = np.sum(da3 * sigmoid_grad(a3), axis=0) 169 170 dz2 = np.dot(da3 * sigmoid_grad(a3), W3.T) 171 da2 = dz2 * sigmoid_grad(a2) 172 grads['W2'] = np.dot(z1.T, da2 * sigmoid_grad(a2)) 173 grads['b2'] = np.sum(da2 * sigmoid_grad(a2), axis=0) 174 175 dz1 = np.dot(da2 * sigmoid_grad(a2), W2.T) 176 da1 = dz1 * sigmoid_grad(a1) 177 grads['W1'] = np.dot(x.T, da1 * sigmoid_grad(a1)) 178 grads['b1'] = np.sum(da1 * sigmoid_grad(a1), axis=0) 179 180 return grads 181 182network = TwoLayerNet(input_size=1, hidden_size1=10, hidden_size2=10, hidden_size3=10, output_size=1) 183 184#学習 185def sigmoid(x): 186 return 1 / (1 + np.exp(-x)) 187def sigmoid_grad(x): 188 return (1.0 - sigmoid(x)) * sigmoid(x) 189def mean_squared_error(y, t): 190 return 0.5 * np.sum((y - t)**2) 191def softmax(x): 192 x = x - np.max(x, axis=-1, keepdims=True) # オーバーフロー対策 193 return np.exp(x) / np.sum(np.exp(x), axis=-1, keepdims=True) 194 195iters_num = 10000 # 繰り返しの回数を適宜設定する 196train_size = x_train.shape[0] 197batch_size = 10 198learning_rate = 0.1 199 200train_loss_list = [] 201train_acc_list = [] 202test_acc_list = [] 203 204iter_per_epoch = max(train_size / batch_size, 1) 205 206for i in range(iters_num): 207 batch_mask = np.random.choice(train_size, batch_size) 208 x_batch = x_train[batch_mask] 209 y_batch = t_train[batch_mask] 210 211 # 勾配の計算 212 #grad = network.numerical_gradient(x_batch, y_batch) 213 grad = network.gradient(x_batch, y_batch) 214 215 # パラメータの更新 216 for key in ('W1', 'b1', 'W2', 'b2', 'W3', 'b3', 'W4', 'b4'): 217 network.params[key] -= learning_rate * grad[key] 218 219 loss = network.loss(x_batch, y_batch) 220 train_loss_list.append(loss) 221 222 optimizer = Adam 223y_pred = network.predict(x_test) 224 225import matplotlib.pyplot as plt 226plt.plot(x_test,y_pred,marker='.',ls='',label='y_pred') 227plt.grid() 228plt.xlabel('x_test',fontsize='16') 229plt.ylabel('y_pred',fontsize='16') 230plt.show() 231plt.close() 232 233plt.plot(train_loss_list) 234plt.xlabel('epoc') 235plt.ylabel('loss') 236plt.show()

試したこと

Affinをうまく適用しようとしたのですが、いまいち使い方が分かっていません

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

Jupyter labを使用しています。Python3です

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

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

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

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

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

jbpb0

2023/04/05 23:33

pythonのコードの一番最初の行のすぐ上に ```python だけの行を追加してください また、pythonのコードの一番最後の行のすぐ下に ``` だけの行を追加してください または、 https://teratail.storage.googleapis.com/uploads/contributed_images/56957fe805d9d7befa7dba6a98676d2b.gif を見て、そのようにしてみてください 現状では、コードの途中だけが上記の状態になってて、先頭と最後の部分がなってないため、とても読み辛いです 質問にコードを載せる際に上記をやってくれたら、他人がコードを読みやすくなり、コードの実行による現象確認もやりやすくなるので、回答されやすくなります
jbpb0

2023/04/05 23:54

エラーが出た時に実行してたコードも、質問に追記してください (ここに書くのではなく、質問を編集して追記する) > y=x^2の関数を区間[-1,1]で学習したい とのことなので、上記式に基づくデータをコード中で生成してると思うので、そのあたりも含めて追記してください エラーが出る状況を他人が再現できるように質問を書く方が、回答が得られやすくなります
jbpb0

2023/04/06 04:06

エラーが発生してる > --> 163 grad = network.gradient(x_batch, t_batch) のすぐ上に print(x_batch.shape) を追加して実行したら、何て表示されますでしょうか?
aky

2023/04/06 06:23

返信ありがとうございます!実はその後かなりプログラムを書き換えていまして、また別の問題が発生しています。よければ考えていただけるととても助かります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問