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

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

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

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

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

Python

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

Q&A

解決済

1回答

2165閲覧

MNISTのニューラルネット(CNNではない)

yamato_user

総合スコア2321

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

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

Python

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

0グッド

1クリップ

投稿2019/04/20 17:42

MNISTをCNNではなく通常のニューラルネットで分類させようとしていますが、acc: 0.1044、つまり、正答率10%ほどで学習が進まないです。Kerasを用いています。試しにirisデータセットを用いたところ、90%ほどになったのですが、MNISTで学習が進まない原因はどこにあるでしょうか?「正答率が思ったほど高くならない」ならわかるのですが、10%はひどすぎて、プログラムのどこかに欠陥があるのではないかと思っていますが、、、、

Python

1import sys, os 2sys.path.append(os.pardir) 3from dataset.mnist import load_mnist 4from keras import utils as np_utils 5from keras.models import Sequential 6from keras.layers.core import Dense 7from keras.utils import to_categorical 8from keras.optimizers import Adam 9from keras.callbacks import CSVLogger 10 11(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=False) 12 13t_train_ = np_utils.to_categorical(t_train) 14t_test_ = np_utils.to_categorical(t_test) 15model = Sequential() 16model.add(Dense(input_dim=784, output_dim=600, bias=True, activation='relu')) 17model.add(Dense(input_dim=600, output_dim=500, bias=True, activation='relu')) 18model.add(Dense(input_dim=500, output_dim=10, bias=True, activation='softmax')) 19model.compile(loss='categorical_crossentropy', optimizer=Adam(), metrics=['accuracy']) 20csv_logger = CSVLogger('log.csv', separator=',', append=False) 21history = model.fit(x_train, t_train_, 22 batch_size=32, epochs=100, 23 validation_data=(x_test, t_test_), 24 callbacks=[csv_logger])

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

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

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

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

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

amanoese

2019/04/21 01:15

ネットワークが大きすぎる気がします。 600と500のところをすべて64に設定すると良いと考えられます。
amanoese

2019/04/21 01:32

あとデータの値を0から1の間に正則化しないと学習が収束しないと思われます
amanoese

2019/04/21 09:34

質問のタグに「TensorFlow」や「Keras」を追加するとより多くの回答が得られると思います。
guest

回答1

0

ベストアンサー

正解データは0~9の数字10個なのでランダムに選択すると、正解率は10%になります。
つまり全く学習していないモデルであると言えます。

実際こちらでモデルを作成しても正解率は10%程度でした。
これはデータが正規化されていないことによってネットワークが学習できないことが原因です。

mnistのデータにはグレースケールされた0255の範囲でデータ登録されています。
今回の場合、outputは10次元のone-hotベクトルで回答を得ようとしています。
この2つの値は0
1の値と0~255の値というように範囲が大きく異なます。

python

1from keras.datasets import mnist 2import numpy as np 3from keras.utils import to_categorical 4 5(x_train, t_train), (x_test, t_test) = mnist.load_data() 6 7t_train = to_categorical(t_train) 8 9print("min: %d , max: %d , mean %f ." % (np.min(x_train),np.max(x_train),np.mean(x_train))) 10print("min: %d , max: %d , mean %f ." % (np.min(t_train),np.max(t_train),np.mean(t_train))) 11 12// min: 0 , max: 255 , mean 33.318421 . 13// min: 0 , max: 1 , mean 0.100000 .

このような場合に学習が上手くいくことは少ないです。
そのためmnistのinputのデータを255で割り0~1の範囲に収まるように加工(正規化)してあげます。

python

1from keras.datasets import mnist 2import numpy as np 3from keras.utils import to_categorical 4 5(x_train, t_train), (x_test, t_test) = mnist.load_data() 6 7x_train = x_train.reshape((60000,784)) 8x_train = x_train.astype('float32') / 255 9 10t_train = to_categorical(t_train) 11 12print("min: %d , max: %d , mean %f ." % (np.min(x_train),np.max(x_train),np.mean(x_train))) 13print("min: %d , max: %d , mean %f ." % (np.min(t_train),np.max(t_train),np.mean(t_train))) 14 15// min: 0 , max: 1 , mean 0.130661 . 16// min: 0 , max: 1 , mean 0.100000 .

このような状態であれば質問のネットワークでも十分に学習されます。

python

1from keras.datasets import mnist 2 3from keras.models import Sequential 4from keras.layers.core import Dense 5from keras.utils import to_categorical 6from keras.optimizers import Adam 7import matplotlib.pyplot as plt 8 9(x_train, t_train), (x_test, t_test) = mnist.load_data() 10 11x_train = x_train.reshape((60000,784)) 12x_train = x_train.astype('float32') / 255 13 14x_test = x_test.reshape((10000,784)) 15x_test = x_test.astype('float32') / 255 16 17t_train_ = to_categorical(t_train) 18t_test_ = to_categorical(t_test) 19 20model = Sequential() 21model.add(Dense(input_dim=784, output_dim=600, bias=True, activation='relu')) 22model.add(Dense(input_dim=600, output_dim=500, bias=True, activation='relu')) 23model.add(Dense(input_dim=500, output_dim=10, bias=True, activation='softmax')) 24model.summary() 25model.compile(loss='categorical_crossentropy', optimizer=Adam(), metrics=['accuracy']) 26 27epoch_num = 10 28history = model.fit(x_train, t_train_, 29 batch_size=1000, epochs=epoch_num, 30 validation_data=(x_test, t_test_))

学習結果1

正答率は98%くらいですね。
しかし過学習が発生しているのが少し気になります。
実際にはネットワークが小さく学習も早く終わる下記のネットワークにするほうが良いかもしれません。

python

1model.add(Dense(input_dim=784, output_dim=64, bias=True, activation='relu')) 2model.add(Dense(input_dim=64, output_dim=64, bias=True, activation='relu')) 3model.add(Dense(input_dim=64, output_dim=10, bias=True, activation='softmax')) 4model.compile(loss='categorical_crossentropy', optimizer=Adam(), metrics=['accuracy'])

学習結果2

このネットワークでも正答率は97%くらいなのでこちらのほうが使い勝手が良いと思います。

また、なぜうまくいくのかさらに精度を上げるにはどうすればよいのかなど詳しく知りたい場合は、
書籍などで数学的な側面も合わせて体系的に学ぶことをオススメします。

PythonとKerasによるディープラーニング

ここまで説明して申し訳ないですが、質問のコードにあるload_mnistのnormalizeというオプションは画素値を0~1の間に正規化してくれるオプションと思われるので、そこをTrueにするだけで上手くいく可能性が高いです。

(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=True)

投稿2019/04/21 09:31

編集2019/04/21 09:54
amanoese

総合スコア132

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

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

yamato_user

2019/04/21 11:33

> この2つの値は0~1の値と0~255の値というように範囲が大きく異なます。 ここ重要ですね。 勉強になりました。ありがとうございます
yamato_user

2019/04/21 12:55

お伺いしたいのですが、なぜ中間層のノードの数は少ないほうがいいのですか?また、入出力の数に対する中間層のノードの個数の目安ってありますか?
amanoese

2019/04/21 13:41 編集

非常に回答が難しい質問ですね。 > なぜ中間層のノードの数は少ないほうがいいのですか? プログラム的には、問題が2つあると思います。 1. 過学習を起こしやすい  数学的な説明を省くと変数が多いと上手く特徴を捉えられなくなるのです。  「オッカムの剃刀」のように、結果を判断するための媒介変数は少ないほど、そのデータに対する特徴を上手く捉えてることになります。  重回帰分析を知っているならば、変数が多いことで過学習が起きやすいことは理解しやすいかもしれません。  https://ja.wikipedia.org/wiki/%E9%81%8E%E5%89%B0%E9%81%A9%E5%90%88 2. 計算量が増大する  より抽象的な特徴を捉えるためには隠れ層増やす必要がでてきます(自分が知っているモデルでは)。  大きい次元のモデルは、より深いモデルの学習を困難にします。 > また、入出力の数に対する中間層のノードの個数の目安ってありますか?  すみませんが、私も機械学習の初心者で経験が浅いためわからないです。  というより、ここの設計で大きく性能が変わるのでそれが分かれば多くの研究者や機械学習のエンジニアは苦労しない気がします。。。   一応参考になりそうなリンクです。  https://qiita.com/To_Murakami/items/e8b7bfe66750fb3f2050 私も機械学習初心者なので勘違いしている部分や間違っている部分が多くあるかもしれません。 また、正しいパラメータの設定やニューラルネットワーク全体でのモデルの設計をしたいのであれば数学的な理解が必要になると思われます。 そのため繰り返しになりますが、書籍などで数学的な側面も合わせて体系的に学ぶことをオススメします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問