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

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

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

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

Q&A

解決済

1回答

1102閲覧

MNISTの0〰9数字を分類するコードで学習が進みません。

kobahot

総合スコア10

Python 3.x

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

0グッド

0クリップ

投稿2022/09/17 08:58

前提

初心者です。
MNISTの0〰9数字を分類するコードをスクラッチで書いています。

実現したいこと

softmax関数の計算がおかしいようで学習が進ません。
class SoftmaxCrossEntropyLoss()の中で使っています。
softmaxの書き方が悪いのか、層の計算が間違っているのかも分かりません。
何んとなく怪しい箇所は、#怪しい と記載しました。

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

RuntimeWarning: invalid value encountered in subtract x = x-np.max(x,axis=0)

該当のソースコード

Python3.9

1import csv 2import os 3import pickle 4import numpy as np 5import matplotlib.pyplot as plt 6from mpl_toolkits.mplot3d import Axes3D 7import cv2 8from sklearn import datasets 9from sklearn.model_selection import train_test_split 10%matplotlib inline 11np.random.seed(seed=0) 12 13 14#怪しい 15def softmax(x): 16 x = x.T 17 x = x-np.max(x,axis=0) 18 x = np.exp(x)/np.sum(np.exp(x)) 19 return x.T 20 21# mnistデータセット 22mnist = datasets.fetch_openml('mnist_784', as_frame=False) 23# 画像とラベルを取得 24X, T = mnist.data, mnist.target 25# 訓練データとテストデータに分割 26X_train, X_test, T_train, T_test = train_test_split(X, T, test_size=0.2) 27 28T_train = np.eye(10)[T_train.astype("int")] 29T_test = np.eye(10)[T_test.astype("int")] 30 31def cross_entropy_error(t, y): 32 delta = 1e-8 33 error = -np.mean(t * np.log(y + delta)) 34 return error 35 36class SoftmaxCrossEntropyLoss(): 37 def __init__(self): 38 self.y = None 39 self.t = None 40 self.loss = None 41 42 def __call__(self, t, y): 43 self.y = softmax(y) 44 self.t = t.copy() 45 self.loss = cross_entropy_error(self.t, self.y) 46 return self.loss 47 48 def backward(self): 49 batch_size = self.t.shape[0] 50 dy = self.y - self.t 51 dy /= batch_size 52 return dy 53 54class FullyConnectedLayer(): 55 def __init__(self, input_shape, output_shape): 56 self.w = np.random.randn(input_shape, output_shape) * 0.01 57 self.b = np.zeros(output_shape, dtype=np.float) 58 self.x = None 59 self.dw = None 60 self.db = None 61 62#怪しい 63 def __call__(self, x): 64 self.x = x 65 out = np.dot(x,self.w)+self.b 66 return out 67#怪しい 68 def backward(self, dout): 69 dx = np.dot(dout,np.transpose(self.w)) 70 batch_size = dx.shape[0] 71 self.dw = np.dot(np.transpose(self.x),dout) 72 self.db = np.sum(dout,axis=0) 73 return dx 74 75class ReLU(): 76 def __init__(self): 77 self.mask = None 78#怪しい 79 def __call__(self, x): 80 self.mask = (x <= 0) 81 out = x.copy() 82 out[self.mask]=0 83 return out 84#怪しい 85 def backward(self, dout): 86 dout[self.mask]=0 87 dx = dout 88 89 return dx 90 91class MLP_classifier(): 92 93 def __init__(self): 94 ''' 95 96 x -> fc(784, 256) -> relu -> fc(256, 256) -> relu -> fc(256, 10) -> out 97 ''' 98 99 # 層 100 self.fc1 = FullyConnectedLayer(784, 256) 101 self.relu1 = ReLU() 102 self.fc2 = FullyConnectedLayer(256, 256) 103 self.relu2 = ReLU() 104 self.fc3 = FullyConnectedLayer(256, 10) 105 self.out = None 106 107 # 損失関数の定義 108 self.criterion = SoftmaxCrossEntropyLoss() 109 110 def forward(self, x): 111 ''' 112 順伝播 113 ''' 114 115 x = self.relu1(self.fc1(x)) 116 x = self.relu2(self.fc2(x)) 117 self.out = self.fc3(x) 118 119 120 return self.out 121 122 def backward(self, t): 123 ''' 124 逆伝播 125 ''' 126 127 # 誤差を計算 128 loss = self.criterion(t, self.out) 129 # 勾配を逆伝播 130 d = self.criterion.backward() 131 d = self.fc3.backward(d) 132 d = self.relu2.backward(d) 133 d = self.fc2.backward(d) 134 d = self.relu1.backward(d) 135 d = self.fc1.backward(d) 136 137 return loss 138 139 def optimize_GradientDecent(self, lr): 140 ''' 141 勾配降下法による全層のパラメータの更新 142 ''' 143 for fc in [self.fc1, self.fc2, self.fc3]: 144 fc.w -= lr * fc.dw 145 fc.b -= lr * fc.db 146 147# モデルの宣言 148model = MLP_classifier() 149 150# 学習率 151lr = 0.005 152# 学習エポック数 153n_epoch = 20 154 155 156for n in range(n_epoch): 157 # 訓練 158 159 y = model.forward(X_train) 160 loss = model.backward(T_train) 161 model.optimize_GradientDecent(lr) 162 163 # テスト 164 y = model.forward(X_test) 165 test_loss = model.backward(T_test) 166 pred = softmax(y) 167 accuracy = np.mean(np.equal(np.argmax(y, axis=1), np.argmax(T_test, axis=1))) 168 print(f'EPOCH {n + 1} | TRAIN LOSS {loss:.5f} | TEST LOSS {test_loss:.5f} | ACCURACY {accuracy:.2%}') 169classification_accuracy = accuracy 170

試したこと

エラーがdef softmax()の中なので、その中はいくつか試しました。

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

初心者ですので、質問の仕方が不適切かと思いますが、
助けてください。

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

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

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

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

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

meg_

2022/09/17 09:38 編集

まずは順伝播の計算が合っていることを単純なデータで確認するのが先かと思います。あと、エラーではなくウォーニングかと思いますが。
kobahot

2022/09/22 14:32

ご指導ありがとうございます。ルールを把握しておらず申し訳ありません。 正直、解決したか自信ありませんが、学習は完了できたので、その内容を投稿しておきます。
guest

回答1

0

自己解決

https://qiita.com/segavvy/items/bdad9fcda2f0da918e7c
↑を参考に、keepdims=Trueを追加し、np.maxで次元が減らないように修正した所、学習が完了しました。

投稿2022/09/22 14:33

kobahot

総合スコア10

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問