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

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

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

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

Q&A

解決済

1回答

303閲覧

ニューラルネットワークに関する質問(TensorFlow)

yamato_user

総合スコア2321

Python

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

0グッド

1クリップ

投稿2018/02/03 17:54

ニューラルネットワークでわからないことをいくつか列挙します。
わかるものだけ回答していただければありがたいです。

1.活性化関数について
step/ReLu/sigmoid/tanh/softmax/elu/softsin/恒等関数 など様々な活性化関数がありますが、隠れ層・出力層での使い分けの基準ってどういう基準で使い分けているのですか?活性化関数によっては、出力値が0~1に収まるものと、そうでないものもありますが、これも関係しているのですか?また、予測問題と分類問題でも使い分けるのですか?

2.損失関数について
「1.活性化関数について」の質問と重なる部分もあると思いますが、書籍などを見ると、分類問題は交差エントロピー誤差関数(多クラス用)を用いて、損失関数を定義していましたが、数値の予測問題を実施したいときの損失関数は何を用いれば良いですか?最小2乗誤差?

3.重み更新方法
確率的勾配降下法/Adam/Adagrad/Adadelta/Momentum/RMSprop など様々ありますが、優劣ってあるのですか?また、使い分けの基準はなんですか?

4.mnistのクラス分類(CNNでなく、通常のNN)
書籍を見ながら、作成したしたmnistのクラス分類のコードです。畳み込みニューラルネットワークは使用せず、通常のニューラルネットワークを使用しました。
ここでの質問は、
「クラス分類のやり方としてなにか根本的な間違いはないか?一般的なやり方と違うか?」
「精度を高めるための改善点は何か?ハイパーパラメータの設定?重み・バイアス項の初期値?」
の2つです。

python

1import numpy as np 2import tensorflow as tf 3from sklearn import datasets 4from sklearn.model_selection import train_test_split 5from sklearn.utils import shuffle 6 7np.random.seed(0) 8tf.set_random_seed(1234) 9 10class DNN(object): 11 def __init__(self, n_in, n_hiddens, n_out,how_to_loss,how_to_optimize): 12 self.n_in = n_in 13 self.n_hiddens = n_hiddens 14 self.n_out = n_out 15 self.how_to_loss=how_to_loss 16 self.how_to_optimize=how_to_optimize 17 self.weights = [] 18 self.biases = [] 19 self._x = None 20 self._t = None, 21 self._keep_prob = None 22 self._sess = None 23 self._history = {'accuracy': [],'loss': []} 24 def weight_variable(self, shape): 25 initial = tf.truncated_normal(shape, stddev=0.01) 26 return tf.Variable(initial) 27 def bias_variable(self, shape): 28 initial = tf.zeros(shape) 29 return tf.Variable(initial) 30 def inference(self, x, keep_prob): 31 for i, n_hidden in enumerate(self.n_hiddens): 32 if i == 0: 33 input = x 34 input_dim = self.n_in 35 else: 36 input = output 37 input_dim = self.n_hiddens[i-1] 38 self.weights.append(self.weight_variable([input_dim, n_hidden])) 39 self.biases.append(self.bias_variable([n_hidden])) 40 h = tf.nn.relu(tf.matmul(input, self.weights[-1]) + self.biases[-1]) 41 output = tf.nn.dropout(h, keep_prob) 42 self.weights.append(self.weight_variable([self.n_hiddens[-1], self.n_out])) 43 self.biases.append(self.bias_variable([self.n_out])) 44 y = tf.nn.softmax(tf.matmul(output, self.weights[-1]) + self.biases[-1]) 45 return y 46 def loss(self, y, t): 47 if self.how_to_loss=="cross_entropy": 48 loss = tf.reduce_mean(-tf.reduce_sum(t * tf.log(y), axis=1)) 49 return loss 50 def training(self, loss): 51 if self.how_to_optimize=="GradientDescent": 52 optimizer = tf.train.GradientDescentOptimizer(0.01) 53 if self.how_to_optimize=="Adadelta": 54 optimizer = tf.train.AdadeltaOptimizer(0.01) 55 if self.how_to_optimize=="Adagrad": 56 optimizer = tf.train.AdagradOptimizer(0.01) 57 if self.how_to_optimize=="Momentum": 58 optimizer = tf.train.MomentumOptimizer(0.01,0.01) 59 if self.how_to_optimize=="Adam": 60 optimizer = tf.train.AdamOptimizer() 61 train_step = optimizer.minimize(loss) 62 return train_step 63 def accuracy(self, y, t): 64 correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(t, 1)) 65 accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) 66 return accuracy 67 def fit(self, X_train, Y_train, 68 nb_epoch=10, batch_size=100, p_keep=0.5, 69 verbose=1): 70 x = tf.placeholder(tf.float32, shape=[None, self.n_in]) 71 t = tf.placeholder(tf.float32, shape=[None, self.n_out]) 72 keep_prob = tf.placeholder(tf.float32) 73 self._x = x 74 self._t = t 75 self._keep_prob = keep_prob 76 y = self.inference(x, keep_prob) 77 loss = self.loss(y, t) 78 train_step = self.training(loss) 79 accuracy = self.accuracy(y, t) 80 with tf.Session() as sess: 81 sess.run(tf.global_variables_initializer()) 82 self._sess = sess 83 N_train = len(X_train) 84 n_batches = N_train // batch_size 85 for epoch in range(nb_epoch): 86 X_, Y_ = shuffle(X_train, Y_train) 87 for i in range(n_batches): 88 start = i * batch_size 89 end = start + batch_size 90 sess.run(train_step, feed_dict={ 91 x: X_[start:end], 92 t: Y_[start:end], 93 keep_prob: p_keep 94 }) 95 loss_ = loss.eval(session=sess, feed_dict={ 96 x: X_train, 97 t: Y_train, 98 keep_prob: 1.0 99 }) 100 accuracy_ = accuracy.eval(session=sess, feed_dict={ 101 x: X_train, 102 t: Y_train, 103 keep_prob: 1.0 104 }) 105 self._history['loss'].append(loss_) 106 self._history['accuracy'].append(accuracy_) 107 108 if verbose: 109 print('epoch:', epoch, 110 ' loss:', loss_, 111 ' accuracy:', accuracy_) 112 113 accuracy=accuracy.eval(session=self._sess, feed_dict={self._x: X_test,self._t: Y_test,self._keep_prob: 1.0}) 114 return accuracy 115 116if __name__ == '__main__': 117 with open('./mnist.pkl', 'rb') as f: 118 dataset = pickle.load(f) 119 mnist_data=dataset['train_img'] 120 mnist_target=dataset['train_label'] 121 n = len(mnist_data) 122 N = 10000 123 indices = np.random.permutation(range(n))[:N] 124 X = mnist_data[indices] 125 y = mnist_target[indices] 126 Y = np.eye(10)[y.astype(int)] 127 X_train, X_test, Y_train, Y_test = train_test_split(X, Y, train_size=0.8) 128 model = DNN(n_in=len(X[0]),n_hiddens=[200, 200, 200],n_out=len(Y[0]),how_to_loss="cross_entropy",how_to_optimize="GradientDescent") 129 accuracy = model.fit(X_train, Y_train,nb_epoch=10,batch_size=200,p_keep=0.5) 130print('accuracy: ', accuracy)

5.勾配降下法・確率的勾配降下法・ミニバッチ学習[1]
まず、以下のような認識で合ってますか?

名称方法デメリット・メリット
勾配降下法全データで損失関数を計算し更新メモリ不足に陥る
確率的勾配降下法1つのデータで損失関数を計算し更新勾配降下法に比べ局所最適解に陥らない
ミニバッチ学習法n個のデータで損失関数を計算し更新確率的勾配降下法よりも計算時間が短い

次に、確率的勾配降下法とミニバッチ学習を比べたときメリットは計算時間の違いだけですか?
また、精度の点で優劣はありますか?

6.勾配降下法・確率的勾配降下法・ミニバッチ学習[2]
次に、上記のコードでは、ミニバッチ学習をさせていますが、
勾配降下法に変更しようとすると、

python

1with tf.Session() as sess: 2 sess.run(tf.global_variables_initializer()) 3 self._sess = sess 4 N_train = len(X_train) 5 for epoch in range(nb_epoch): 6 X_, Y_ = shuffle(X_train, Y_train) 7 sess.run(train_step, feed_dict={ 8 x: X_[0:N_train], 9 t: Y_[0:N_train], 10 keep_prob: p_keep 11 })

確率的勾配降下法にしようとすると、

python

1with tf.Session() as sess: 2 sess.run(tf.global_variables_initializer()) 3 self._sess = sess 4 N_train = len(X_train) 5 for epoch in range(nb_epoch): 6 X_, Y_ = shuffle(X_train, Y_train) 7 for i in range(N_train): 8 sess.run(train_step, feed_dict={ 9 x: np.reshape(X_[i],(1,784)), 10 t: np.reshape(Y_[i],(1,10)), 11 keep_prob: p_keep 12 })

に変更するだけでいいと思ったのですが、確率的勾配降下法の方だけ、損失関数の計算がうまくいかないので、重みも更新されません。どこを変更すれば良いですか?勾配降下法のほうはあっていますか?

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

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

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

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

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

guest

回答1

0

ベストアンサー

1
ゼロイチの間なら確率として解釈できます。
そうでなくても、シフトすればゼロイチの間に収めることができます。
表現力が異なるので、問題によって得意不得意があります。
層の数、ノードの数、過学習するかどうかなど総合的に判断する必要があります。
ハイパーパラメータの類なので、いろいろと試して決めるべきです。

2
二乗誤差、絶対誤差、対数誤差などいろいろあります。
https://en.m.wikipedia.org/wiki/Hinge_loss
のようなものも。

3
だいたいの優劣はあります。
新しいものほど性能が良いです。
新しいものほどmnistを学習する際の性能が良いです。
安定性と収束するまでの反復回数が異なります。

4
スキップ

5
偏りの強い分類の際にミニバッチの方が性能が出る感覚があります。

6
全体で学習してうまく行くのなら、一つずつやって同じ学習率だと変な極値にはまります。

投稿2018/02/04 06:46

mkgrei

総合スコア8560

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問