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

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

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

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

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

機械学習

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

Q&A

解決済

1回答

495閲覧

tensorflowにおけるmnist分類でbut the requested shape requires a multiple of 6272というエラーが出る

vaitarika

総合スコア29

Python 3.x

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

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

機械学習

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

0グッド

0クリップ

投稿2019/02/12 09:17

編集2019/02/12 10:49

実現したいこと

tensorflowを使って自分で組んだCNNでMNISTデータセットの分類を行いたい

発生している問題

python

1from tensorflow.examples.tutorials.mnist import input_data 2mnist = input_data.read_data_sets("MNIST_data", one_hot=True)

上記のコードでmnistデータセットを読み込んだ後に畳み込み層、プーリング層、全結合層を作って実行すると次のエラーが起きてしまいます。

InvalidArgumentError (see above for traceback): Input to reshape is a tensor with 2097152 values, but the requested shape requires a multiple of 6272

このエラーが出たときは畳み込み層を3層作った後に全結合層を2層作るとこのエラーが起きました。しかし、畳み込み層を2層に減らしたところこのエラーは消え、分類を行うことができました。
下記がエラーが出たときに加えていた三層目です。

python

1 #畳み込み3 2 with tf.name_scope('conv3') as scope: 3 W_conv3 = weight_variable([5, 5, 64, 128]) 4 b_conv3 = bias_variable([128]) 5 h_conv3 = tf.nn.relu(conv2d(h_pool2, W_conv3) + b_conv3) 6 #プーリング3 7 with tf.name_scope('pool3') as scope: 8 h_pool3 = max_pool_2x2(h_conv3)

このように畳み込み層の3層目を書いていたところエラーが出てしまったのですが、何かおかしいところはありますか。
また、下記がエラーが出ていた時の全結合層の一層目です。

python

1 # 全結合層1 2 with tf.name_scope('fc1') as scope: 3 W_fc1 = weight_variable([7*7*128, 1024]) 4 b_fc1 = bias_variable([1024]) 5 h_pool3_flat = tf.reshape(h_pool3, [-1, 7*7*128]) 6 h_fc1 = tf.nn.relu(tf.matmul(h_pool3_flat, W_fc1) + b_fc1)

下記が全体のコードです

python

1import sys 2import os 3import numpy as np 4import tensorflow as tf 5import tensorflow.python.platform 6 7from tensorflow.examples.tutorials.mnist import input_data 8mnist = input_data.read_data_sets("MNIST_data", one_hot=True) 9 10NUM_CLASSES = 10 11IMAGE_SIZE = 28 12IMAGE_PIXELS = IMAGE_SIZE*IMAGE_SIZE 13 14flags = tf.app.flags 15FLAGS = flags.FLAGS 16flags.DEFINE_integer('max_steps', 20, 'Number of steps to run trainer.') 17flags.DEFINE_integer('batch_size', 1024, 'Batch size' 18 'Must divide evenly into the dataset sizes.') 19flags.DEFINE_float('learning_rate', 1e-4, 'Initial learning rate.') 20 21def inference(images_placeholder, keep_prob): 22 23 def weight_variable(shape): 24 initial = tf.truncated_normal(shape, stddev=0.1) 25 return tf.Variable(initial) 26 27 def bias_variable(shape): 28 initial = tf.constant(0.1, shape=shape) 29 return tf.Variable(initial) 30 31 def conv2d(x, W): 32 return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME') 33 34 def max_pool_2x2(x): 35 return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], 36 strides=[1, 2, 2, 1], padding='SAME') 37 38 x_image = tf.reshape(images_placeholder, [-1, IMAGE_SIZE, IMAGE_SIZE, 1]) 39 print(x_image.shape) 40 41 42 # 畳み込み層1の作成 43 with tf.name_scope('conv1') as scope: 44 W_conv1 = weight_variable([5, 5, 1, 32]) 45 b_conv1 = bias_variable([32]) 46 h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1) 47 48 # プーリング層1の作成 49 with tf.name_scope('pool1') as scope: 50 h_pool1 = max_pool_2x2(h_conv1) 51 52 # 畳み込み層2の作成 53 with tf.name_scope('conv2') as scope: 54 W_conv2 = weight_variable([5, 5, 32, 64]) 55 b_conv2 = bias_variable([64]) 56 h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) 57 58 # プーリング層2の作成 59 with tf.name_scope('pool2') as scope: 60 h_pool2 = max_pool_2x2(h_conv2) 61 62 # 畳み込み層3の作成 63 with tf.name_scope('conv3') as scope: 64 W_conv3 = weight_variable([5, 5, 64, 128]) 65 b_conv3 = bias_variable([128]) 66 h_conv3 = tf.nn.relu(conv2d(h_pool2, W_conv3) + b_conv3) 67 68 # プーリング層3の作成 69 with tf.name_scope('pool3') as scope: 70 h_pool3 = max_pool_2x2(h_conv3) 71 72 # 全結合層1の作成 73 with tf.name_scope('fc1') as scope: 74 W_fc1 = weight_variable([7*7*128, 1024]) 75 b_fc1 = bias_variable([1024]) 76 h_pool3_flat = tf.reshape(h_pool3, [-1, 7*7*128]) 77 h_fc1 = tf.nn.relu(tf.matmul(h_pool3_flat, W_fc1) + b_fc1) 78 h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) 79 80 # 全結合層2の作成 81 with tf.name_scope('fc2') as scope: 82 W_fc2 = weight_variable([1024, NUM_CLASSES]) 83 b_fc2 = bias_variable([NUM_CLASSES]) 84 85 with tf.name_scope('softmax') as scope: 86 y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2) 87 88 return y_conv 89 90def loss(logits, labels): 91 92 cross_entropy = -tf.reduce_sum(labels*tf.log(logits)) 93 tf.summary.scalar("cross_entropy", cross_entropy) 94 return cross_entropy 95 96def training(loss, learning_rate): 97 98 train_step = tf.train.AdamOptimizer(learning_rate).minimize(loss) 99 return train_step 100 101def accuracy(logits, labels): 102 103 correct_prediction = tf.equal(tf.argmax(logits, 1), tf.argmax(labels, 1)) 104 accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) 105 tf.summary.scalar("accuracy", accuracy) 106 return accuracy 107 108if __name__ == '__main__': 109 110 with tf.Graph().as_default(): 111 images_placeholder = tf.placeholder("float", shape=(None, IMAGE_PIXELS)) 112 113 labels_placeholder = tf.placeholder("float", shape=(None, NUM_CLASSES)) 114 115 keep_prob = tf.placeholder("float") 116 117 118 logits = inference(images_placeholder, keep_prob) 119 120 loss_value = loss(logits, labels_placeholder) 121 122 train_op = training(loss_value, FLAGS.learning_rate) 123 124 acc = accuracy(logits, labels_placeholder) 125 126 saver = tf.train.Saver() 127 128 sess = tf.Session() 129 130 sess.run(tf.global_variables_initializer()) 131 132 summary_op = tf.summary.merge_all() 133 summary_writer = tf.summary.FileWriter('./logs', sess.graph) 134 135 for step in range(FLAGS.max_steps): 136 for i in range(int(len(mnist.train.images)/FLAGS.batch_size)): 137 138 batch = FLAGS.batch_size * i 139 140 sess.run(train_op, feed_dict={ 141 images_placeholder: mnist.train.images[batch:batch+FLAGS.batch_size], 142 labels_placeholder: mnist.train.labels[batch:batch+FLAGS.batch_size], 143 keep_prob: 0.5}) 144 145 train_accuracy = sess.run(acc, feed_dict={ 146 images_placeholder: mnist.train.images, 147 labels_placeholder: mnist.train.labels, 148 keep_prob: 1.0}) 149 print ("step {}, training accuracy {}".format(step, train_accuracy)) 150 151 summary_str = sess.run(summary_op, feed_dict={ 152 images_placeholder: mnist.train.images, 153 labels_placeholder: mnist.train.labels, 154 keep_prob: 1.0}) 155 summary_writer.add_summary(summary_str, step) 156 157 print ("test accuracy {}".format(sess.run(acc, feed_dict={ 158 images_placeholder: mnist.test.images, 159 labels_placeholder: mnist.test.labels, 160 keep_prob: 1.0}))) 161 162 summary_str_1 = sess.run(summary_op, feed_dict={ 163 images_placeholder: mnist.test.images, 164 labels_placeholder: mnist.test.labels, 165 keep_prob: 1.0}) 166 summary_writer.add_summary(summary_str_1, step) 167 168 cwd = os.getcwd() 169 save_path = saver.save(sess, cwd + "//model.ckpt") 170 sess = tf.InteractiveSession() 171 saver.restore(sess, "model.ckpt") 172

補足情報

開発環境
・python 3.6.6
・tensorflow 1.12.0

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

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

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

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

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

guest

回答1

0

ベストアンサー

畳み込み層の出力が (OUT_H, OUT_W, OUT_C) であるとした場合、それを flatten して (OUT_HOUT_WOUT_C,) の1次元テンソルになります。
これが全結合層の入力となるので、全結合層の出力数が N とした場合、この全結合層の重み W は (OUT_HOUT_WOUT_C, N) となります。

問題なのは OUT_HOUT_WOUT_C の部分ですが、これが 77128 となっているので、畳み込み層が出力する特徴マップの形状は (7, 7, 128) でなければなりませんが、1個畳み込み層を追加してしまったことにより、この値が異なってしまったのではないでしょうか。

conv2d に padding="SAME" 引数を指定すると、入出力で大きさが変わらなくなるので、これを追加した conv2d に指定すれば直ると思います。

投稿2019/02/12 09:34

tiitoi

総合スコア21956

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

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

vaitarika

2019/02/12 09:42

回答ありがとうございます。 conv2dの部分ですが、ここはもとからpadding="SAME"を指定してあります。 他にどのような修正方法があるでしょうか。
tiitoi

2019/02/12 09:46 編集

質問のコードにはないようですが、実際は指定しているということなのでしょうか? コードの断片だけだとわからないので、「コピペしたらそのまま動かせるコード全体」を質問欄を編集して貼っていただけますか
vaitarika

2019/02/12 10:50

了解致しました。 コード全体を添付しました。
tiitoi

2019/02/12 11:22 編集

質問では「畳み込み層を追加したら」と記載されてますが、プーリング層 pool3 も質問者さんが独自に追加されましたか? pool3 の出力を print(pool3.shape) とすると、(?, 4, 4, 128) となっており、7*7*128 の全結合層とこのままでは接続することはできないため、エラーになっています。
tiitoi

2019/02/12 11:21

とりあえず 7*7*128 を 4*4*128 に直せばエラーは解消するかと思います。 ``` W_fc1 = weight_variable([4*4*128, 1024]) b_fc1 = bias_variable([1024]) h_pool3_flat = tf.reshape(h_pool3, [-1, 4*4*128]) ```
vaitarika

2019/02/13 04:47

プーリング層も自分で追加しました。 ご指摘いただいた通り直したところ、エラーは解消されました。ありがとうございました。 しかし、直したプログラムで分類を行なってみたところ、かなり低いaccuracyになってしまい、なおかつtrainもtestもどちらもaccuracyが変わらない状態になってしまいました。 原因がわからないのですが、どのようにすれば改善されるでしょうか。
tiitoi

2019/02/13 05:00 編集

プログラムのバグとかではないと思います。 プーリングすると画像サイズは半分になります。(stride=2 でやった場合) 元は2回プーリングして (28, 28) -> (14, 14) -> (7, 7) となっていたものが、1回追加したことで (4, 4) とかなり小さくなってしまったので、そこまでプーリングする必要はなかったのではないでしょうか? MNIST は簡単な問題なので、ネットワークをそこまで深くする必要はないように思います。深くするほど精度が上がるかというと問題によります。
vaitarika

2019/02/13 05:07

わかりやすい説明ありがとうございます。 確かにそうですね。この場合は2層でやってみようと思います。 今、犬猫判別を行なっていて、そこでは画像サイズを(56,56)にしているのですがこの場合では畳み込み、プーリング層を2層ずつにするとaccuracyが0.5で変化しなくなってしまいました。 この場合は層の数が少ないということなのでしょうか。また、strideやパッチサイズについてどのくらいの値で行えば良いのかいまいち分かっていないのですが、手探りでやっていくしかないのでしょうか。
tiitoi

2019/02/13 05:13 編集

バッチサイズ: 大きいほうが計算時間は早くなるが、小さいほうが精度がよくなる場合が多い。ハイパーパラメータなので 64, 32, 16, 8 など試して一番精度がいいのを採用する > この場合は層の数が少ないということなのでしょうか。また、strideやパッチサイズについてどのくらいの値で行えば良いのかいまいち分かっていないのですが手探りでやっていくしかないのでしょうか。 既存の実績があるモデル構造をまず試されるとよいと思います。 AlexNet, VGG、GoogLeNet, ResNet VGG、GoogLeNet, ResNet は関数1つでモデルを作成できるものが TensorFlow で提供されていたと思います。
vaitarika

2019/02/13 05:20

何度もありがとうございます。参考にさせていただきます。 このプログラムにおいて例えば畳み込み層1の W_conv1 = weight_variable([5, 5, 1, 32]) の4つ目の引数(32)、出力チャンネル数とはどのようにして決まっているのでしょうか。
tiitoi

2019/02/13 05:50

どのように決まっているというのは、どこで指定しているのかという質問でしょうか? 例えば、ResNet50 であれば、以下のようにしてモデルを作成でき、summary() でモデルの概要を出力できます。 import tensorflow as tf from tensorflow.keras.applications.resnet50 import ResNet50 model = ResNet50(weights='imagenet') model.summary()
vaitarika

2019/02/13 05:59

以前に「ゼロから作るDeep Learning」を読んだときに、CNNの畳み込み層の出力はパディングやストライドによって決まるということだったと記憶しているのですが、ここでもそのように出力の数を他のパラメータから計算して求める必要があるのでしょうか。それともこの場合は、出力を自分で設定するということなのでしょうか。
vaitarika

2019/02/13 06:02

Kerasでの犬猫判別参考にさせていただきました。とてもわかりやすく、ためになりました。 その中で、犬猫の画像データをテスト用と訓練用に分けるという部分があったのですが、ResNet-50を用いて行う分類では犬と猫にフォルダーを分けておけば特にラベル付けのようなことは行わなくてよいということでしょうか。
tiitoi

2019/02/13 06:29 編集

> 「ゼロから作るDeep Learning」を読んだときに、CNNの畳み込み層の出力はパディングやストライドによって決まる その認識はあっています。 モデルを作成する方法として TensorFlow ではいくつかの方法が提供されています。 (1) 質問ように各層を重みを格納するためのテンソルを作っていく方法 → 重みは前の層の入力と出力数などのパラメータから決まるので1つずつ出力がどうなるかを計算して、しっかり合うように形状を指定しなければならない。 例えるなら、パズルのようなものだと思ってください。パズルのピースが合わない場合、質問のようなエラーになります。(繋げられない) (2) Keras API を使う 畳込み層、全結合層といった各層がオブジェクト化されており、それを繋げてくだけでよい。 (1) の煩わしい部分を内部に隠蔽して使いやすくなっている。 TensorFlow にも統合されています。 https://www.tensorflow.org/guide/keras (3) 提供されている有名なモデルを使う。 VGG16、ResNet50 などの有名なモデルは関数1つで作成できるような API が Keras (Tensorflow) で提供されています。 先程貼った犬猫の回答のサンプルコードではこちらを使っています。 自分でモデルを作る場合も基本的には (2) がおすすめです。 Keras 単体でも tensorflow に統合されている tf.keras も API は同じなので、使うならどちらでもよいと思います。
vaitarika

2019/02/13 06:43

とてもわかりやすい説明ありがとうございます。 ということは今回自分が使っているのは(1)の場合ということでしょうか。だとすると、32,64,128などは他の値を変えたときに自分で変える必要があるということでしょうか。
tiitoi

2019/02/13 06:48 編集

(1) だと変える必要があります。変えないと前後の層との整合性が取れなくなって質問のようなエラーになります。 (2) だとそういうのは自動で計算されます。
vaitarika

2019/02/13 08:40

ありがとうございます。 Kerasでの犬猫判別においては、特にラベル付けなどを行わずにファイルごとにまとめることによって分類を行なっているという認識でよろしいでしょうか。
tiitoi

2019/02/13 08:57

> 特にラベル付けなどを行わずにファイルごとにまとめることによって分類を行なっているという認識でよろしいでしょうか。 Keras の ImageDataGenerator の機能を使ってます。 各クラスの画像を分けておいたフォルダのパスを指定すると学習に必要なデータ形式を返すジェネレーターを作成できる機能があります。(ラベル付けなどもフォルダ構成に基づき、自動でつけてくれる) クラス分類以外のタスクでは使えませんが、クラス分類の場合には便利です。 使い方などは以下を参照ください。 https://qiita.com/croquette0212/items/9bb41c698d65282e5bb2 https://keras.io/ja/preprocessing/image/
vaitarika

2019/02/13 09:05

画像の水増しだけでなく、ラベル付けなどまでしてくれるとても便利なものがあるのですね。感動しました。 Kerasは色々と触ったつもりでしたが、まだ知らないことだらけなのでKerasも触っていこうと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問