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

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

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

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

Q&A

1回答

1226閲覧

画像認識NNを改良したい

退会済みユーザー

退会済みユーザー

総合スコア0

Python

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

0グッド

1クリップ

投稿2021/05/07 09:47

編集2021/05/08 01:54

自分でニューラルネットワークを作ろう
https://qiita.com/takahiro_itazuri/items/d2bea1c643d7cca11352#comment-a59cd26161ee56ea1220
を元に作ったコードなんですが・・・。

コードと出力結果はBA決定後、中略します。

python

1from google.colab import drive 2 3 4中略(以下に書いたコード参照) 5 6 scoreboard_array = np.asarray(scoreboard) 7 print('performance: ', scoreboard_array.sum() / scoreboard_array.size)

以下画像
0.png~9.png
イメージ説明
10.png~19.png
イメージ説明
20.png~29.png
イメージ説明
以下同様。
イメージ説明
イメージ説明
イメージ説明
イメージ説明
イメージ説明
イメージ説明
イメージ説明

出力結果
Mounted at /content/drive
test_data_list [[0
中略
/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:160: RuntimeWarning: invalid value encountered in double_scalars

plabelが判定結果の画像ファイル名前です、testファイルは50.pngそのものですので、5と出力させたいのですが、9になったり7になったりしてしまいます。

というか気づいたのですが、こちらのコード

python

1from google.colab import drive 2drive.mount('/content/drive') 3 4import sys 5import numpy as np 6 7sys.path.append('/content/drive/My Drive') 8 9import ActivationFunction as AF 10from PIL import Image 11 12# PILで開いたうえでデータをNumpy形式にする 13# (例えばJPEGは圧縮されていてNumpyな配列になっていないので、 14# そこからNumpyのデータ空間(?)に持ってくる必要がある) 15tefilename = "1.png" 16teimg = Image.open("drive/My Drive/mnist_dataset/" + tefilename) 17teimg = teimg.resize((10, 10)) 18teimg = np.asarray(teimg) 19 20def extract(x, y): 21 # カラー画像の時Gだけ抜き取りたい 22 if len(x.shape) == 3: 23 h, w, ch = x.shape 24 25 # RGBのGだけ抜き取りたい 26 return x[:,:,y] 27 28v_max, v_min = 300, 200 29 30def diff(x): 31 imgrows, lenrows, imgcolumns, lencolumns = [], [], [], [] 32 for (img, imgt) in zip(x, x.T): 33 rows = img[(v_min<img)&(v_max>img)] 34 columns = imgt[(v_min<imgt)&(v_max>imgt)] 35 imgrows.append(rows) 36 lenrows.append(len(rows)) 37 imgcolumns.append(columns) 38 lencolumns.append(len(columns)) 39 return lenrows + lencolumns 40 41test_data_list = [] 42 43test_data_list.append([0] + diff(extract(teimg, 1))) # 略 44 45print("test_data_list" ,test_data_list) 46 47# 見本データに対しても同様に 48# exについて同様に 49training_data_list = [] 50 51for i in range(10): 52 for e in range(1): 53 trad = Image.open("drive/My Drive/mnist_dataset/" + str(10*i+e) + ".png") 54 trad = trad.resize((10, 10)) 55 trad = np.asarray(trad) 56 #g #b #r 抽出後diffしてappend 57 training_data_list.append([i] + diff(extract(trad, 1))) # 略 58 59print("training_data_list" ,training_data_list) 60 61# 3層ニューラルネットワーク 62class ThreeLayerNetwork: 63 # コンストラクタ 64 def __init__(self, inodes, hnodes, onodes, lr): 65 # 各レイヤーのノード数 66 self.inodes = inodes 67 self.hnodes = hnodes 68 self.onodes = onodes 69 70 # 学習率 71 self.lr = lr 72 73 # 重みの初期化 74 self.w_ih = np.random.normal(0.0, 1.0, (self.hnodes, self.inodes)) 75 self.w_ho = np.random.normal(0.0, 1.0, (self.onodes, self.hnodes)) 76 77 # 活性化関数 78 self.af = AF.sigmoid 79 self.daf = AF.derivative_sigmoid 80 81 # 誤差逆伝搬 82 def backprop(self, idata, tdata): 83 84 # 縦ベクトルに変換 85 o_i = np.array(idata, ndmin=2).T 86 t = np.array(tdata, ndmin=2).T 87 88 # 隠れ層 89 x_h = np.dot(self.w_ih, o_i) 90 o_h = self.af(x_h) 91 92 # 出力層 93 x_o = np.dot(self.w_ho, o_h) 94 o_o = self.af(x_o) 95 96 # 誤差計算 97 e_o = (t - o_o) 98 e_h = np.dot(self.w_ho.T, e_o) 99 100 # 重みの更新 101 self.w_ho += self.lr * np.dot((e_o * self.daf(o_o)), o_h.T) 102 self.w_ih += self.lr * np.dot((e_h * self.daf(o_h)), o_i.T) 103 104 # 順伝搬 105 def feedforward(self, idata): 106 # 入力のリストを縦ベクトルに変換 107 o_i = np.array(idata, ndmin=2).T 108 109 # 隠れ層 110 x_h = np.dot(self.w_ih, o_i) 111 o_h = self.af(x_h) 112 print("o_h" ,o_h) 113 114 # 出力層 115 x_o = np.dot(self.w_ho, o_h) 116 print("x_o" ,x_o) 117 o_o = self.af(x_o) 118 119 return o_o 120 121if __name__=='__main__': 122 # パラメータ 123 #inodes=784から59+1に変更 124 inodes = 20 125 hnodes = 100 126 onodes = 10 127 lr = 0.3 128 129 # ニューラルネットワークの初期化 130 nn = ThreeLayerNetwork(inodes, hnodes, onodes, lr) 131 132 # 学習 133 epoch = 1 134 for e in range(epoch): 135 print('#epoch ', e) 136 data_size = len(training_data_list) 137 for i in range(data_size): 138 if i % 1000 == 0: 139 print(' train: {0:>5d} / {1:>5d}'.format(i, data_size)) 140 idata = (np.array(training_data_list[i][1:]) / 255.0 * 0.99) + 0.01 141 # 変更の余地あり 142 tdata = np.zeros(onodes) + 0.01 143 tdata[training_data_list[i][0]] = 0.99 144 print("idata" ,idata) 145 print("tdata" ,tdata) 146 nn.backprop(idata, tdata) 147 pass 148 pass 149 150 # テスト 151 scoreboard = [] 152 for record in test_data_list: 153 idata = (np.array(record[1:]) / 255.0 * 0.99) + 0.01 154 predict = nn.feedforward(idata) 155 plabel = np.argmax(predict) 156 np.set_printoptions(threshold=10000) 157 print("predict=o_o" ,predict) 158 print("plabel" ,plabel) 159 pass 160 161 scoreboard_array = np.asarray(scoreboard) 162 print('performance: ', scoreboard_array.sum() / scoreboard_array.size)

の出力結果が以下のようになるわけですが、

Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount("/content/drive", force_remount=True).
test_data_list [[0, 10, 4, 2, 4, 4, 4, 4, 4, 4, 8, 10, 4, 2, 2, 6, 6, 2, 2, 4, 10]]
training_data_list [[0, 10, 4, 2, 4, 4, 4, 4, 4, 4, 8, 10, 4, 2, 2, 6, 6, 2, 2, 4, 10], [1, 10, 8, 5, 5, 7, 7, 8, 7, 3, 4, 10, 10, 6, 6, 1, 1, 3, 8, 9, 10], [2, 10, 4, 3, 8, 7, 6, 6, 7, 2, 2, 10, 6, 5, 4, 3, 3, 2, 4, 8, 10], [3, 10, 4, 2, 7, 6, 5, 7, 5, 3, 5, 10, 7, 5, 6, 4, 4, 1, 2, 5, 10], [4, 10, 7, 6, 5, 5, 5, 2, 2, 7, 8, 10, 7, 6, 6, 6, 2, 1, 1, 8, 10], [5, 10, 3, 8, 7, 3, 5, 7, 4, 3, 9, 10, 7, 3, 5, 5, 5, 4, 4, 6, 10], [6, 10, 5, 5, 7, 3, 3, 5, 4, 4, 8, 10, 5, 3, 3, 5, 4, 4, 3, 7, 10], [7, 10, 2, 4, 7, 7, 7, 7, 7, 7, 10, 10, 9, 7, 5, 4, 4, 5, 6, 8, 10], [8, 8, 4, 4, 4, 4, 2, 5, 4, 4, 8, 10, 5, 2, 3, 4, 4, 2, 2, 5, 10], [9, 10, 4, 2, 5, 5, 3, 4, 6, 4, 7, 10, 7, 3, 2, 4, 4, 4, 2, 4, 10]]
#epoch 0
train: 0 / 10
idata [0.04882353 0.02552941 0.01776471 0.02552941 0.02552941 0.02552941
0.02552941 0.02552941 0.02552941 0.04105882 0.04882353 0.02552941
0.01776471 0.01776471 0.03329412 0.03329412 0.01776471 0.01776471
0.02552941 0.04882353]
tdata [0.99 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01]
中略
tdata [0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.99]
o_h [[0.44149295]
[0.47443682]
中略
[0.5014706 ]]
x_o [[ -2.09106513]
中略
[ -2.25102428]]
predict=o_o [[1.09968282e-01]
中略
[9.52611495e-02]]
plabel 6
performance: nan
/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:162: RuntimeWarning: invalid value encountered in double_scalars

まあつまり、trainingは、画像番号0しか入力していないのに、画像番号は存在しない3になっており、これは毎度引っかかっているlist in list構造問題であり、

python

1 predict = nn.feedforward(idata)

ここでfeedforwardしたidataが、idataつまりtarining_dataの1番目のlist(呼び方が分からない)のn番目(呼び方が分からない)を画像番号nに該当するとして計算しており、

training_data_list [[0, 10, 4, 2, 4, 4, 4, 4, 4, 4, 8, 10, 4, 2, 2, 6, 6, 2, 2, 4, 10]]

この10が画像番号0,4が画像番号1,2が画像番号2・・・となっているのですが、実際は、(最初のコードに書いたように)

training_data_list [[0, 10, 4, 2, 4, 4, 4, 4, 4, 4, 8, 10, 4, 2, 2, 6, 6, 2, 2, 4, 10]
これを画像番号1のデータ
[1, 10, 8, 5, 5, 7, 7, 8, 7, 3, 4, 10, 10, 6, 6, 1, 1, 3, 8, 9, 10]
これを画像番号2のデータ・・・
として処理したいのですが、どうすればいいんでしょうか。]

・・・というかこれもう、元のプログラムに即して、画像からテキストファイルを作成し、そのテキストファイルを読み込む、みたいにした方がいいんでしょうか・・・?

ちょっとミスを見つけたんですが、テストの所一部record使わないとrecord使ってる意味がないですね、

まあ。。元はcsv読み込んでいるのだから、コードでcsv作成して読み込んだ方が良いですかね、色々ややこしいし。

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

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

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

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

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

guest

回答1

0

つっこみどころ満載ですね。

train: 0 / 10

10個のデータを1回だけ通して学習させたNNで判定できるとは思いません。

training_data_list [[0, 10, 4, 2, 4, 4, 4, 4, 4, 4, 8, 10, 4, 2, 2, 6, 6, 2, 2, 4, 10],
inodes = 20

これ、もしかして画像データですか? inodesも20になっているのでそうだし、元のソースからすると、生データの筈ですが、20個はいくらなんでも少なすぎて、特徴が抽出できないのではないかと思います。

255.0 * 0.99) + 0.01

この計算で元データを256階調の白黒画像だとして処理してますが、元データの方は大きくても10程度です。 そうてい通りですか?

として処理したいのですが、どうすればいいんでしょうか。

単に1増やしたいだけなら、[i]のところで、[i+1]とでもすればいいのではないかと思うし、そもそも連番入れているのには違和感がありますね。
何れにしても、下記の通り、事前にCSVを用意するのが適当ではないかな。

元はcsv読み込んでいるのだから、コードでcsv作成して読み込んだ方が良いですかね

そうしない理由がわかりません。

投稿2021/05/08 11:27

TakaiY

総合スコア13790

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

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

退会済みユーザー

退会済みユーザー

2021/05/09 10:59 編集

training_data_list [[0, 10, 4, 2, 4, 4, 4, 4, 4, 4, 8, 10, 4, 2, 2, 6, 6, 2, 2, 4, 10] は、1つの画像のデータですね。 これは1つの画像のデータであるため、inodesは10でも問題なく動いていると思っているのですが・・・。 いずれにせよ、画像の種類数は少ない事は間違いないですね。 255.0 * 0.99) + 0.01 この式ですが、全体を1/10したりしたのですが、あまり変化がなく・・・ 256で割ると小さくなりすぎますかね。 csv作成バージョンと非作成バージョンを作ったのですが、 どっちも同程度の精度なので、後者を改造しています。 データ数は少ないですが「完全に一致しているデータ」があるのだから、 それを正答に出すようにしたいのですが、そう上手くはいかないんですかね? 完全に一致するデータは最有力候補にあげるような仕組みにしたいのですが・・・。 たぶん「誤差」が小さいほど、その(誤差の小さい)番号の値が大きくなるような計算が、 何等かの計算式によるなされていると思うのですが、その「誤差が小さい程番号の値が大きくなる」という部分を上手く改良すれば良いと思うのですが・・・ やはり、backとforwrardの関数をいじるしかないですよね、 乱数の正規分布行列を掛け合わせる事で誤差が大きくなってるんですよねたぶん。 お、ところが言われた通り、epochを1000にすると5しか出なくなったっぽいです・・・ でもなんで10とかだとだめなんでしょう・・・、「完全一致」って極めて特異的だと思うのですが・・・。
TakaiY

2021/05/09 13:38

データ数は少ないですが「完全に一致しているデータ」があるのだから、 それを正答に出すようにしたい NNは画像と画像の距離を測るようなものではありません。なのでそうはなりません。 NNについて誤解していると思うので、そっちの方向に行っても正解には辿りつけないでしょう。
退会済みユーザー

退会済みユーザー

2021/05/11 09:30

一応簡単な認識プログラム作ったんですが、みたいですか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

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

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

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問