🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

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

Q&A

解決済

2回答

4698閲覧

MinstをRNN(LSTM)で学習する際のイメージがつかめない

ads3hcgff

総合スコア16

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

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

1グッド

2クリップ

投稿2019/10/27 14:03

編集2019/10/27 14:05

MinistをLSTMで学習させたいのですが
特徴量の入力について疑問があります。
28*28のサイズで28の一行目(模式図のt1)から二行目(t2)というデータを読み込ませたいのですが
ディープニュートラルネットワークの設計としては中間層h0がh1に入るという認識でいいでしょうか?
時系列データとして扱っているのでt1からt2に行くh27とh28が(t2からt3も)つながっていないという認識なのですが・・・
あってますでしょうか?
模式図↓

イメージ説明

具体的なコード

python

1from keras.utils import np_utils # keras.utilsからnp_utilsをインポート 2from keras.datasets import mnist # MNISTデータセットをインポート 3 4# MNISTデータセットの読み込み 5(x_trains, y_trains), (x_tests, y_tests) = mnist.load_data() 6 7# 訓練データ 8x_trains = x_trains.astype('float32') # float32型に変換 9x_trains /= 255 # 0から1.0の範囲に変換 10# 正解ラベルをワンホット表現に変換 11correct = 10 # 正解ラベルの数 12y_trains = np_utils.to_categorical(y_trains, correct) 13 14# テストデータ 15x_tests = x_tests.astype('float32') # float32型に変換 16x_tests /= 255 # 0から1.0の範囲に変換 17# 正解ラベルをワンホット表現に変換 18y_tests = np_utils.to_categorical(y_tests, correct) 19 20print(x_trains.shape) # 訓練データの形状を出力 21print(x_tests.shape) # テストデータの形状を出力 22 23# RNNの構築 24from keras.models import Sequential 25from keras.layers import InputLayer, Dense 26from keras.layers.recurrent import LSTM 27from keras import optimizers,regularizers 28 29# Sequentialオブジェクトを生成 30model = Sequential() 31 32## 入力層 33# 入力データの形状は(28, 28) 34model.add( 35 InputLayer(input_shape=(28,28)) 36 ) 37 38## 中間層 39# LSTMブロック(ユニット数=128) 40weight_decay = 1e-4 # ハイパーパラメーター 41model.add(LSTM(units=128, dropout=0.25, return_sequences=True)) 42model.add(LSTM(units=128, dropout=0.25, return_sequences=True)) 43model.add(LSTM(units=128, dropout=0.25, return_sequences=False, 44 kernel_regularizer=regularizers.l2(weight_decay)) # 正則化 45) 46 47## 出力層 48model.add( 49 Dense(units=10, # 出力層のニューロン数は10 50 activation='softmax') # 活性化はシグモイド関数 51 ) 52 53# Squentialオブジェクをコンパイル 54model.compile( 55 loss='categorical_crossentropy', # 誤差関数はクロスエントロピー 56 optimizer=optimizers.Adam(), # Adamオプティマイザー 57 metrics=['accuracy'] # 学習評価として正解率を指定 58 ) 59 60model.summary() # RNNのサマリ(概要)を出力 61 62# 学習を開始 63history = model.fit(x_trains, y_trains, # 訓練データ、正解ラベル 64 batch_size=100, # ミニバッチのサイズ 65 epochs=10, # 学習回数 66 verbose=1, # 学習の進捗状況を出力する 67 validation_data=( # テストデータの指定 68 x_tests, y_tests) 69 ) 70 71# 損失と正解率をグラフにする 72 73import matplotlib.pyplot as plt 74 75# プロット図のサイズを設定 76plt.figure(figsize=(15, 6)) 77# プロット図を縮小して図の間のスペースを空ける 78plt.subplots_adjust(wspace=0.2) 79 80# 1×2のグリッドの左(1,2,1)の領域にプロット 81plt.subplot(1, 2, 1) 82# 訓練データの損失(誤り率)をプロット 83plt.plot(history.history['loss'], 84 label='training', 85 color='black') 86# テストデータの損失(誤り率)をプロット 87plt.plot(history.history['val_loss'], 88 label='test', 89 color='red') 90plt.ylim(0, 1) # y軸の範囲 91plt.legend() # 凡例を表示 92plt.grid() # グリッド表示 93plt.xlabel('epoch') # x軸ラベル 94plt.ylabel('loss') # y軸ラベル 95 96# 1×2のグリッドの右(1,2,21)の領域にプロット 97plt.subplot(1, 2, 2) 98# 訓練データの正解率をプロット 99plt.plot(history.history['acc'], 100 label='training', 101 color='black') 102# テストデータの正解率をプロット 103plt.plot(history.history['val_acc'], 104 label='test', 105 color='red') 106plt.ylim(0.5, 1) # y軸の範囲 107plt.legend() # 凡例を表示 108plt.grid() # グリッド表示 109plt.xlabel('epoch') # x軸ラベル 110plt.ylabel('acc') # y軸ラベル 111plt.show()
yu__👍を押しています

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

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

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

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

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

teefpc

2019/10/27 14:13 編集

参考までにお聞きしたいのですが、このモデルは画像認識ですか?それとも時系列の学習でしょうか。 もし、画像認識の場合、なぜLSTMを使っているのか興味があります。
ads3hcgff

2019/10/27 14:13

画像認識です。 ディープラーニングの理論と実装という本を参考にLSTMを理解しようとしたのですが コードを追ってたところ肝心の入力周りのところがkerasの内部処理になっておりイメージがつかめなかったため質問させていただきました。
teefpc

2019/10/27 14:17

畳み込みニューラルネットワークを使わずに、敢えて再帰型ニューラルネットワークで学習に挑戦しているということは、論文などを発表されるためでしょうか。
ads3hcgff

2019/10/27 14:23

そういうわけではないですね
teefpc

2019/10/27 14:49

再帰型ニューラルネットワークは、入力(時刻 t) に対して、出力(時刻 t+1) を予測するというものなのですが、このプログラムは、入力に画像データ、教師データにそのラベルを設定してfit させようとしています。(CNNを理解された上でLSTMモデルを独自に研究されているのであれば、申し訳ありませんが私の理解を超えています)
ads3hcgff

2019/10/27 15:30

今回の目的としては厳密なモデル選択をしているのではなくMnistでとりあえずLSTMを適用しようという方針です。その際にピクセル単位で相互に関連性を持ったと仮定しており、その前提のモデルがあっているかどうかということを質問しているという流れです。厳密性にこだわっていないので有識者の人から見ると怒られるかもしれませんがそれはそれこれはこれでお願いします。
guest

回答2

0

ベストアンサー

lstmにおける1ノードは1ピクセルではなく、複数ピクセルを含みます。
イメージ説明

すなわち、画像認識においては、1行28ピクセルを1ステップとして、28ステップの学習をします。
これは、数字描画するときは、黒画素と黒画素とが連結しているのが自然で、縦方向を時間軸とみなせば、
時間軸上になんらかの関連性があるという考えに基づくもので、画像にlstmを使用するのは不自然ではありません。
ただし、cnnよりも精度が出るとはかぎりません。

投稿2019/10/28 02:41

qax

総合スコア622

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

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

ads3hcgff

2019/10/28 07:28 編集

回答ありがとうございます。 図のx0(t0)の中に28個のデータ(一行28ピクセル)があるとと思うのですがこちらは 一行目だと ピクセルをp 重みをwとしてh0 = sigmoid([p0,p1....p27] *[[w0,w1...w27](転置)])を h1に再入力しているという認識でいいでしょうか どうもx0の中のピクセル28個分をどうするかというイメージとその正解ラベルy0のイメージがつきません。 正解ラベルについては一枚の画像で28個正解ラベルがいるという認識であってますでしょうか。
qax

2019/10/28 11:18

その部分については、LSTMなのか、RNNなのか、GRUなのかで異なってきます。 しかし、基本的にはその認識でまちがいありません。
qax

2019/10/28 12:06

正確には、あるステップtのピクセルP(t)={p1,p2,p3,...,p27}とします。 隠れ層のユニット数を28次元とすれば、一つ前のステップの隠れ層H(t-1)={h1,h2,h3,...,h27}と表せます。 このとき、ステップtの隠れ層はP×Wih+H(t-1)×Whhと表せます。 ここで、WihはPの次元数28とHの次元数28の28x28次元の重み行列です。 WhhはHの次元数28と同じくHの次元数28の28x28の重み行列です。 では、例えば、28x28の画像から10クラスの分類をしたい場合、出力は10次元ですね。 このとき、Hの次元数を10次元としてみます。 そうすると、Pは28次元ベクトル、Hは10次元ベクトルです。 これを先程の説明に当てはめると、Wihは28x10の重み行列、Whhは10x10の重み行列となります。 あとは、一ステップずつ計算していくことで、入力の28x28画像を10次元にへんかんできますね。 ただし、これは先程ものべたように、LSTMの基となるRNNのさらに基本的な部分のみです。 LSTMではもう少し複雑なことをしていますが、基本的な考え方は同じです。
guest

0

「28次元のベクトル」が変化していく時系列データを「28ステップ分」記録したもの

だと思ってLSTMは処理しています。


(追記)

質問に貼ってあるソースの動きはこうです。

1層目のLSTMの時刻t0の入力x0は「画像の一番上の28ピクセル」に対応する「28個の数値」を、28次元のベクトルだと見たものです。
LSTMにx0を入れると内部状態(128次元ベクトル)を更新してh0になります。(と同時にこれが出力でもあります。後述)

1層目のLSTMの時刻t1の入力x1は「画像の上から2番目の28ピクセル」に対応する「28個の数値」を、28次元のベクトルだと見たものです。
LSTMは1つ前の内部状態h0と、x1から、内部状態を更新してh1になります。

(略)

1層目のLSTMの時刻t27の入力x27は「画像の一番下の28ピクセル」に対応する「28個の数値」を、28次元のベクトルだと見たものです。
LSTMは1つ前の内部状態h26と、x27から、内部状態を更新してh27になります。

return_sequences=Trueが指定してありますから、1層目のLSTMの出力は、h0からh27の128次元のベクトル28個をconcatenateしたものです。

したがって、2層目のLSTMの入力は128次元のベクトルの28ステップの時系列データとなります。


2層目のLSTMの時刻t0の入力x0は「1層目のLSTMの時刻0の内部状態ベクトル」です。
LSTMにx0を入れると内部状態を更新してh0になります。

2層目のLSTMの時刻t1の入力x1は「1層目のLSTMの時刻1の内部状態ベクトル」です。
LSTMは1つ前の内部状態h0と、x1から、内部状態を更新してh1になります。

(略)

2層目のLSTMの時刻t27の入力x27は「1層目のLSTMの時刻27の内部状態ベクトル」です。
LSTMは1つ前の内部状態h26と、x27から、内部状態を更新してh27になります。

return_sequences=Trueが指定してありますから、2層目のLSTMの出力は、h0からh27の128次元のベクトル28個をconcatenateしたものです。

したがって、3層目のLSTMの入力も2層目と同様、128次元のベクトルの28ステップの時系列データとなります。


3層目のLSTMの時刻t0の入力x0は「2層目のLSTMの時刻0の内部状態ベクトル」です。
LSTMにx0を入れると内部状態を更新してh0になります。
(略)
3層目のLSTMの時刻t27の入力x27は「2層目のLSTMの時刻27の内部状態ベクトル」です。
LSTMは1つ前の内部状態h26と、x27から、内部状態を更新してh27になります。

return_sequences=Falseが指定してありますから、3層目のLSTMの出力は、最後の内部状態ベクトルh27です。つまり128次元のベクトルを出力します。

したがって、最後の全結合層の入力は128次元のベクトルになります。


最後に、128次元の入力から全結合層につながって、10次元のベクトルをsoftmax関数を通して出力することでクラス分類の結果としています。

投稿2019/10/28 02:02

編集2019/10/29 23:14
quickquip

総合スコア11231

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問